Packages
Key management service with embedded OTP runtime, optional HTTP API, SQLite/PostgreSQL storage, and external RMK providers
Current section
Files
Jump to
Current section
Files
README.md
# KMS
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:
- [Overview](docs/overview.md)
- [Phoenix quickstart](docs/quickstart.md)
- [Use cases](docs/use_cases.md)
- [Security](docs/security.md)
## Quick example
```elixir
{: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](docs/use_cases/crypto_only.md) |
| Embedded KMS | One Elixir/Phoenix app runs KMS in-process. | [Embedded KMS](docs/use_cases/embedded.md) |
| Phoenix field encryption | Encrypt Ecto fields with virtual plaintext fields. | [Quickstart](docs/quickstart.md) |
| Remote KMS | App servers call a dedicated KMS authority process. | [Remote KMS](docs/use_cases/remote.md) |
| Multi-user KMS | KMS enforces per-principal permissions. | [Multi-user encryption](docs/use_cases/multi_user_encryption.md) |
| Factor-bound aliases | Recipient secrets must cryptographically protect alias keys; share and revoke access. | [Factor-bound aliases](docs/use_cases/factor_bound_aliases.md) |
## Persistence
KMS defaults to SQLite:
```sh
export KMS_DATA_DIR=/var/lib/kms
mix ecto.migrate
```
PostgreSQL remains supported:
```sh
export KMS_DATABASE_BACKEND=postgres
export KMS_DATABASE_URL=ecto://postgres:postgres@localhost/kms_prod
mix ecto.migrate
```
See [Database configuration](docs/database.md).
## 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](docs/http-api.md) and [Security stance](docs/security/stance.md).
## 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](docs/rmk.md).
## 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/security.md).
## Docs
- [Installation](docs/installation.md)
- [Configuration](docs/configuration.md)
- [Elixir API](docs/elixir-api.md)
- [HTTP API](docs/http-api.md)
- [Authorization and bindings](docs/authz-bindings.md)
- [Operations](docs/operations.md)
- [Observability](docs/observability.md)
- [Fallback recovery](docs/fallback-recovery.md)
- [Migrations and upgrades](docs/migrations-upgrades.md)
## Development validation
Useful commands:
```sh
mix format --check-formatted
mix compile --warnings-as-errors
mix test.sqlite
mix test.postgresql
```