KMS is an Elixir key-management toolkit packaged as one OTP application, :kms.

It provides clean primitives and deployment patterns for:

  • direct AES-GCM encryption with AAD;
  • Phoenix/Ecto field-level encryption;
  • embedded KMS storage with SQLite by default;
  • optional KMS.API HTTP server for remote clients;
  • principal/session/binding authorization when KMS should enforce decrypt rights;
  • local or external root master key (RMK) providers;
  • RMK-wrapped P-256 signing-key custody and caller-process digest signing.

Start with:

Quick example

{:ok, _kek} = KMS.create_alias("owner:alice")

{:ok, encrypted} =
  KMS.encrypt_alias("secret", "owner:alice", aad: "document:123/body")

{:ok, "secret"} =
  KMS.decrypt_alias(encrypted, "owner:alice", aad: "document:123/body")

AAD binds ciphertext to context. In this example, copying the ciphertext to a different document id or field makes decrypt fail.

Choose a mode

ModeUse whenStart here
Crypto-onlyApp may decrypt at any time; no KMS storage needed.Crypto-only
Embedded KMSOne Elixir/Phoenix app runs KMS in-process.Embedded KMS
Phoenix field encryptionEncrypt Ecto fields with virtual plaintext fields.Quickstart
Remote KMSApp servers call a dedicated KMS authority process.Remote KMS
Multi-user KMSKMS enforces per-principal permissions.Multi-user encryption
Factor-bound aliasesRecipient secrets must cryptographically protect alias keys; share and revoke access.Factor-bound aliases

Persistence

KMS defaults to SQLite:

export KMS_DATA_DIR=/var/lib/kms
mix ecto.migrate

PostgreSQL remains supported:

export KMS_DATABASE_BACKEND=postgres
export KMS_DATABASE_URL=ecto://postgres:postgres@localhost/kms_prod
mix ecto.migrate

See Database configuration.

HTTP API

The optional HTTP API lives under KMS.API and runs inside the :kms OTP application when enabled.

Non-health routes require a bearer token. See HTTP API and Security stance.

Root master keys

The RMK protects persisted KMS secret material.

Providers:

  • local file-backed RMK (KMS.RMK.Local, default);
  • StackIT KMS;
  • AWS KMS;
  • Google Cloud KMS.

See Root master keys.

Security posture

  • Treat local KMS calls without session: as trusted application/admin execution.
  • Treat the HTTP API as an admin backend API.
  • Use TLS or a trusted private network for remote KMS.
  • Disable request-body logging and production crash dumps.
  • Do not log plaintext, ciphertext payloads, bearer tokens, passwords, factor codes, RMK material, or private keys.
  • Embedded signing copies decoded private-key material from sensitive cache into active caller processes; disable production crash dumps.

See Security.

Docs

Development validation

Useful commands:

mix format --check-formatted
mix compile --warnings-as-errors
mix test.sqlite
mix test.postgresql