KMS is a building block for application-managed encryption. Start with the overview or Phoenix field-level encryption quickstart, then choose a use-case pattern.
Patterns
| Use case | Use KMS feature | Good fit |
|---|---|---|
| Crypto-only library | KMS.Crypto, optional KMS.RMK.Local | Use secure primitives without KMS OTP storage or supervision. |
| Application-wide encryption | KMS.Crypto, optional KMS.RMK.Local | App can encrypt/decrypt at any time without KMS OTP storage. |
| Embedded KMS | KMS.Client.Local, SQLite, RMK | One Phoenix/Elixir app runs KMS in-process. |
| Field-level encryption | KEK aliases and AAD | Encrypt selected Ecto fields while app keeps normal schemas and queries. |
| Shared passphrase documents | RMK PDK helpers, AAD | A document is unlockable by anyone who knows a shared high-entropy secret. |
| Multi-user encryption | Principals, sessions, bindings | Multiple KMS principals can encrypt/decrypt through authorization and sessions. |
| Standalone KMS with SQLite | SQLite, local/external RMK, optional HTTP API | Dedicated KMS process without a KMS PostgreSQL service. |
| Remote KMS service | KMS.Client.Remote, HTTP API | App servers call a dedicated KMS authority process over private network/TLS. |
| Break-glass recovery | fallback public keys | Offline trusted operators can unwrap KEK/principal material during incident recovery. |
Crypto-only library
Use KMS modules directly when you want secure AES-GCM primitives and optional local RMK wrapping, but not KMS storage, migrations, sessions, bindings, or supervision.
Application-wide encryption
See Application-wide encryption without KMS storage.
Use KMS crypto primitives directly when the app only needs transparent symmetric encryption and does not need KMS principals, sessions, bindings, or storage.
Embedded KMS
See Embedded KMS in an application.
Use embedded mode when one Phoenix/Elixir app should start :kms, store KMS key tables locally, and call KMS through KMS.Client.Local.
Field-level encryption in Phoenix
See Quickstart. It includes a working Phoenix example under example/phoenix_example.
Core idea:
- store ciphertext in app table (
encrypted_body); - keep plaintext as a virtual schema field (
body); - keep alias and AAD policy next to the encrypted field;
- call
KMS.encrypt_alias/3from the changeset andKMS.decrypt_alias/3on read.
Standalone KMS with SQLite
See Standalone KMS with SQLite.
Use the default SQLite backend when you want a small KMS authority process with local file persistence, one writable data directory, and no KMS PostgreSQL service.
Shared passphrase documents
See Shared passphrase documents.
Use KMS.encrypt_rmk_pdk/3 and KMS.decrypt_rmk_pdk/3 when a caller supplies a high-entropy shared secret and KMS should still RMK-wrap the encrypted payload.
Multi-user encryption
Use KMS principals, sessions, and bindings when users or service identities should get scoped authorization to encrypt/decrypt specific KEK aliases.
Choosing a pattern
Use alias field encryption when the application owns authorization and KMS is the crypto/key boundary.
Use multi-user KMS principals when KMS should enforce per-principal authorization on decrypt/encrypt operations.
Use passphrase encryption when the application should not be able to decrypt without a caller-supplied shared secret.
Use embedded KMS when one app can own the KMS runtime and storage boundary.
Use remote KMS when app servers should not have local DB/RMK access to KMS tables and key material.
See Remote KMS service.