KMS can run inside an application or as a remote authority service.
Choose based on trust boundary, operations, and availability needs.
Local / embedded
Embedded mode starts :kms in the same BEAM VM as the application and uses KMS.Client.Local.
Good when:
- one app owns encrypted data;
- app-level authorization is enough;
- simple deployment matters;
- SQLite local persistence is acceptable;
- application and KMS share one trust boundary.
Tradeoffs:
- app process can call KMS as trusted/admin unless you pass
session:; - app host has KMS DB/RMK access;
- every app instance needs careful DB writer design if using SQLite;
- easiest operational path for small deployments.
See Embedded KMS.
Remote service
Remote mode runs :kms with the optional KMS.API server enabled in a dedicated authority process. Apps use KMS.Client.Remote.
Good when:
- multiple apps need one KMS authority;
- app hosts should not hold KMS DB/RMK credentials;
- KMS needs separate deployment or access controls;
- remote API boundary is useful for operations.
Tradeoffs:
- adds network dependency to encrypt/decrypt;
- requires TLS/private network and API-token management;
- HTTP API is backend/admin surface;
- KMS authority must be monitored like critical infrastructure.
See Remote KMS.
Decision table
| Need | Prefer |
|---|---|
| Fastest Phoenix integration | Embedded |
| One app, one DB, one operator boundary | Embedded |
| App hosts must not read RMK key file | Remote |
| Multiple apps share KEKs/principals | Remote |
| Centralized audit/deploy controls | Remote |
| No network dependency during decrypt | Embedded |
| Dedicated KMS operations team | Remote |
Authorization boundary
Local calls without session: are trusted/admin. That can be correct when the application has already authorized the user.
Use sessions/bindings if KMS should enforce authorization:
KMS.decrypt_alias(ciphertext, alias_name, session: session.secret, aad: aad)Remote KMS has two layers:
- HTTP API token: app-to-KMS backend authentication.
- KMS session: optional principal authorization inside KMS.
Do not confuse them.
Storage boundary
Embedded:
- app host has app DB access;
- app host has KMS DB access;
- app host has local RMK key file or cloud RMK credentials.
Remote:
- app host has app DB access;
- KMS host has KMS DB/RMK access;
- app host has only remote API token.
External RMK providers can improve DB-backup separation in either mode.
Migration path
A common path:
- Start embedded for simple field encryption.
- Keep aliases/AAD stable.
- Move KMS tables/RMK material to a KMS service.
- Switch application config from
KMS.Client.LocaltoKMS.Client.Remote.
Plan and test key/data migration before production. Do not switch RMK providers or databases without restore validation.