Migrations
Authara requires a PostgreSQL database schema.
Schema changes are managed through explicit migrations.
Authara does not automatically mutate the database schema at runtime.
Instead:
- migrations are applied explicitly
- Authara starts against the resulting schema
- Authara validates the schema version at startup
This behavior is intentional and keeps database changes predictable and operator-controlled.
Why migrations are separate
Database schema changes are part of the operational lifecycle of Authara.
They are not runtime behavior.
This means:
- schema changes are applied explicitly
- startup is deterministic
- upgrades are controlled
- runtime does not mutate shared state unexpectedly
Authara treats schema management as an operator responsibility.
Migration Image
Authara provides a dedicated migration image.
This image contains:
- the SQL migration files
- the migration runner
- the logic required to apply schema changes
It does not start the Authara server.
It runs migrations and exits.
Applying migrations
Migrations are typically applied using the migration image before starting Authara.
Example:
docker run --rm \
--env-file .env \
ghcr.io/authara-org/authara-migrations:${AUTHARA_MIGRATIONS_VERSION:-v0.1.20} \
up -env=default -config=/migrations/dbconfig.yaml
This applies all pending migrations and exits.
Use the migrations image listed in the Core release notes. The attached
authara-images.env contains the same version and immutable image reference for
deployment tooling.
Configuration
The migration image uses the same PostgreSQL connection variables as Authara Core.
Required variables include:
POSTGRESQL_HOST=postgres
POSTGRESQL_PORT=5432
POSTGRESQL_DATABASE=authara
POSTGRESQL_USERNAME=authara
POSTGRESQL_PASSWORD=authara
POSTGRESQL_SSL_MODE=disable
For TLS-enabled PostgreSQL, use the same values as Core:
POSTGRESQL_SSL_MODE=verify-full
POSTGRESQL_SSL_ROOT_CERT=/certs/postgresql-ca.pem
Mount a private CA file at that path in the migrations container. See the database connection documentation for all supported verification modes.
These variables may be provided through:
.env- container environment variables
- CI secrets
- orchestration platforms
Typical usage
Migrations should be applied:
- before the first startup
- before starting a newer Authara version with a changed schema
- in CI when testing schema compatibility
Typical operational flow:
- Start PostgreSQL
- Run migrations
- Start Authara Core
- Start the gateway and application
Development
Migrations are required in development as well.
Even in local development, Authara expects the database schema to already exist.
This keeps development behavior consistent with staging and production.
Example local flow:
- Start PostgreSQL
- Run migrations
- Start Authara
Schema compatibility check
Authara validates the schema version at startup.
If the database schema does not match the version required by the running Authara binary, startup fails.
This prevents:
- partially upgraded deployments
- accidental runtime mismatches
- undefined database behavior
In other words:
If Authara starts successfully, the schema version is compatible.
Rollbacks
Rollback behavior depends on the migrations that have been applied.
Schema rollbacks should be treated as an advanced operational task.
Before rolling back:
- understand the migration contents
- evaluate possible data loss
- test the rollback path in a safe environment
Authara does not assume that rollbacks are always safe.
Summary
Authara migrations are:
- explicit
- operator-controlled
- required in development and production
- validated through schema version checks at startup
This keeps schema evolution predictable and prevents hidden runtime database changes.
Runtime-settings upgrade
Schema version 24 adds runtime_settings_state,
runtime_setting_overrides, and the per-challenge
minimum_resend_interval_ns column. Apply migration 024 before deploying the
matching Core binary. With no override rows, effective behavior remains the
same as the existing environment configuration and built-in defaults. The new
column remains null on pre-v24 challenge rows so their resend delay continues
to follow the effective policy, as it did before the value was persisted.
Session-bound email-change upgrade
Schema version 25 binds pending email changes to the session that initiated them. Applying migration 025 cancels existing email-change challenges because they cannot be safely attributed to an initiating session.
Durable email-delivery upgrade
Schema version 26 adds delivery deadlines, terminal failure metadata, and an index for reclaiming expired email-processing leases. Existing challenge email jobs inherit their challenge expiry; other existing jobs receive a deadline 72 hours after their original creation time. Apply migration 026 before deploying the matching Core binary.
Singleton cleanup upgrade
Schema version 34 adds the shared cleanup lease. Schema version 35 adds the supporting partial indexes with concurrent PostgreSQL index builds so existing table writes remain available during the migration. Apply both migrations before deploying the matching Core binary. Because migration 035 is non-transactional, it drops its own known index names before rebuilding them; this makes an interrupted run safe to retry even if PostgreSQL left an invalid concurrent index behind.