Packages

Key management service with embedded OTP runtime, optional HTTP API, SQLite/PostgreSQL storage, and external RMK providers

Current section

Files

Jump to
kms README.md
Raw

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
```