This page states the release stance for OSS v0.1.0 and future upgrades.
OSS v0.1.0 stance
OSS v0.1.0 is treated as a new-install release.
Do not assume compatibility with private/internal/pre-release KMS database schemas unless a migration is explicitly documented for that source version.
Session-protected aliases
Migration 20260906000000_create_kek_wrappings adds keks.protection, makes keks.master_key nullable, and creates kek_wrappings on SQLite and PostgreSQL. Existing rows default to "rmk"; their key material and application ciphertext remain unchanged. New aliases created with a session store recipient envelopes and leave master_key empty.
SQLite cannot alter a column, so this migration rebuilds the keks table with foreign keys temporarily disabled, then verifies PRAGMA foreign_key_check. It runs outside a DDL transaction. Back up the database file and its -wal/-shm sidecars first, as with any SQLite schema change.
Behavior changes:
- Principal sessions creating new aliases now create cryptographically protected aliases and receive creator bindings. Implicit creation through
encrypt_alias/3also requireskek.create. - Passphrase sessions no longer provide unrestricted alias access. They need a matching envelope on a session-protected alias. Existing passphrase sessions can still be used for new envelopes created for their passphrase.
- Existing RMK-only aliases are not auto-converted.
create_alias/2with a session refuses to claim them; existing principal binding-based encrypt/decrypt access remains supported. create_principal/2now enforces a supplied session'sprincipal.createpermission against the new principal's reference/tags, locally and over HTTP. The no-options bootstrap call is unchanged.- Protected aliases cannot use the legacy
KMS.Keks.rotate_kek/2operation, which would discard their recipient protection.
Run the migration on the KMS authority before deploying clients using the new API. For a stronger boundary on existing data, migrate to a new protected alias explicitly and account for old RMK-only copies/backups. No private Formfix schema migration is implied.
Do not roll old code back over protected data. Migration downgrade refuses while session-protected aliases exist, because dropping their envelopes would destroy access. Use a tested matching backup/restore plan instead. See Factor-bound aliases.
Before upgrade
For any deployment:
- back up KMS database;
- back up RMK material separately;
- back up application ciphertext rows;
- test restore in an isolated environment;
- read release notes and migration notes;
- run migrations before serving traffic.
SQLite upgrades
SQLite deployments must preserve:
- main DB file;
- WAL/SHM sidecars when present;
- file permissions;
- RMK key file.
Recommended flow:
systemctl stop my-kms-service
cp /var/lib/kms/kms.sqlite3 /backup/kms.sqlite3
cp /var/lib/kms/kms.sqlite3-wal /backup/kms.sqlite3-wal 2>/dev/null || true
cp /var/lib/kms/kms.sqlite3-shm /backup/kms.sqlite3-shm 2>/dev/null || true
cp /var/lib/kms/rmk.key /backup/rmk.key
mix ecto.migrate
systemctl start my-kms-service
Use your normal snapshot tooling in production. The example shows required material, not a full backup design.
PostgreSQL upgrades
Use standard database backup and migration practice:
pg_dump ... > kms_backup.sql
mix ecto.migrate
Keep RMK material outside the database backup and restore plan it separately.
RMK provider changes
Do not switch RMK providers for existing data without a rewrap/migration plan.
External RMK ciphertext envelopes include provider/key references. Provider mismatch fails closed.
Safe provider migration needs:
- old provider still available;
- decrypt/unwrap old RMK-protected material;
- re-encrypt under new provider;
- verify representative decrypts;
- only then remove old provider access.
Alias/AAD compatibility
Aliases and AAD are part of your application data contract.
Changing alias naming or AAD construction can make old ciphertext undecryptable unless you keep compatibility code.
Recommended:
- version AAD prefixes for large app changes;
- keep old AAD constructors for old rows;
- migrate ciphertext deliberately if row identifiers or field names change.
Session compatibility
Sessions are short-lived bearer credentials. Prefer letting old sessions expire naturally during upgrades.
If session verifier format changes, KMS may support old verifiers temporarily so existing sessions can expire. Do not rely on sessions as long-term state.
Rollback
Rollback is safest before migrations.
After migrations:
- restore DB backup if schema downgrade is not supported;
- restore matching RMK material;
- invalidate sessions if session state may be inconsistent;
- run representative decrypt checks before serving traffic.
Release note expectations
Each release should state:
- database migrations included;
- RMK ciphertext format changes, if any;
- session/factor format changes, if any;
- deprecated config/env vars;
- required operator action;
- validation matrix.