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
docs/installation.md
# Installation
This guide covers adding KMS to an Elixir/Phoenix application or running KMS from this repository.
For a copy/paste Phoenix field-encryption flow, start with [Quickstart](quickstart.md).
## Dependency
Add the published package dependency:
```elixir
defp deps do
[
{:kms, "~> 0.1.0"}
]
end
```
When working from this repository, the example application instead uses `{:kms, path: "../.."}`.
Remote-only clients still use the KMS package so the `KMS` facade and `KMS.Client.Remote` are available.
## Choose a deployment mode
- [Crypto-only](use_cases/crypto_only.md): no OTP app, no KMS DB.
- [Embedded KMS](use_cases/embedded.md): start `:kms` inside your app.
- [Remote KMS](use_cases/remote.md): run `:kms` with the optional `KMS.API` server in a dedicated authority process.
## Embedded KMS application setup
Start KMS with your app:
```elixir
def application do
[
mod: {MyApp.Application, []},
extra_applications: [:logger, :runtime_tools, :kms]
]
end
```
Configure local client and KMS repo:
```elixir
config :my_app,
ecto_repos: [MyApp.Repo, KMS.Repo.SQLite]
config :kms, ecto_repos: [KMS.Repo.SQLite]
config :kms, KMS.Repo, repo: KMS.Repo.SQLite
config :kms, :client, KMS.Client.Local
config :kms, :rmk_provider, KMS.RMK.Local
```
Configure local RMK key path:
```elixir
config :kms, KMS.RMK.Local,
key_path: Path.expand("../priv/kms_rmk_#{config_env()}.key", __DIR__)
```
Run migrations:
```sh
mix ecto.migrate
```
## SQLite default
SQLite is default persistence.
Production env:
```sh
export KMS_DATABASE_BACKEND=sqlite # optional
export KMS_DATA_DIR=/var/lib/kms
export KMS_RMK_LOCAL_KEY_PATH=/var/lib/kms/rmk.key
export KMS_SESSION_HASH_KEY=<high-entropy-secret>
export ERL_CRASH_DUMP_BYTES=0
mix ecto.migrate
```
Database path defaults to:
```text
$KMS_DATA_DIR/kms.sqlite3
```
You can set an exact file path:
```sh
export KMS_DATABASE_PATH=/var/lib/kms/kms.sqlite3
```
See [Database configuration](database.md).
## PostgreSQL option
```sh
export KMS_DATABASE_BACKEND=postgres
export KMS_DATABASE_URL=ecto://postgres:postgres@localhost/kms_prod
mix ecto.create
mix ecto.migrate
```
Or use discrete variables:
```sh
export KMS_DATABASE_HOST=localhost
export KMS_DATABASE_NAME=kms_prod
export KMS_DATABASE_USER=postgres
export KMS_DATABASE_PASSWORD=postgres
```
## Remote KMS service setup
On the KMS authority service:
```elixir
config :kms, :api,
server: true,
port: 4004,
scheme: :http,
api_token: System.fetch_env!("KMS_API_TOKEN")
```
On client apps:
```elixir
config :kms, :client, KMS.Client.Remote
config :kms, KMS.Client.Remote,
base_url: "https://kms.internal.example.com",
api_token: System.fetch_env!("KMS_REMOTE_API_TOKEN")
```
See [Remote KMS service](use_cases/remote.md).
## Production checklist
- Set `KMS_SESSION_HASH_KEY` to a high-entropy secret.
- Set explicit RMK configuration.
- Disable crash dumps with `ERL_CRASH_DUMP_BYTES=0` or `ERL_CRASH_DUMP_SECONDS=0`.
- Protect SQLite DB/WAL/SHM files or PostgreSQL credentials.
- Protect RMK key files or cloud RMK credentials.
- Disable request-body logging for KMS routes.
- Use TLS or trusted private networking for remote KMS.
- Run `/health/ready` before serving traffic.
See [Security](security.md) and [Operations](operations.md).