KMS

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

It provides clean primitives and deployment patterns for:

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

Mode Use when Start here
Crypto-only App may decrypt at any time; no KMS storage needed. Crypto-only
Embedded KMS One Elixir/Phoenix app runs KMS in-process. Embedded KMS
Phoenix field encryption Encrypt Ecto fields with virtual plaintext fields. Quickstart
Remote KMS App servers call a dedicated KMS authority process. Remote KMS
Multi-user KMS KMS enforces per-principal permissions. Multi-user encryption
Factor-bound aliases Recipient 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:

See Root master keys.

Security posture

See Security.

Docs

Development validation

Useful commands:

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