Skip to content

Key management (KMS/HSM)

Kravn encrypts secrets at rest — plugin credentials, SSO and LLM configuration, upstream auth — with AES-256-GCM. By default the encryption key is derived from your signing secret (KRAVN_SECRET). For regulated deployments that must keep key custody in their own key manager, Kravn can instead use an external KMS/HSM: your master key never leaves the KMS, and your key manager logs every use.

Why it matters

A bank or regulated org typically can't accept a long-lived symmetric key sitting in an environment variable. With an external KMS you get custody (the key lives in your Vault/HSM, not in Kravn), auditability (the KMS logs every unwrap), and rotation and revocation on your terms.

Modes

Selected with KRAVN_KMS_PROVIDER:

ModeKey sourceWhen
none (default)Derived from KRAVN_SECRET / auto-generated secret.keyZero-config or where env-managed secrets are acceptable
vaultHashiCorp Vault (Transit engine) wraps the encryption keyVault-based orgs; HSM-backed with a Vault HSM seal
azureAzure Key Vault (wrapKey/unwrapKey)Azure/Entra orgs; HSM-backed with Managed HSM

How it works — envelope encryption

Kravn never holds your master key. In KMS mode:

  1. On first boot Kravn generates a random data key, asks the KMS to wrap (encrypt) it with your master key — which never leaves the KMS/HSM — and stores only the wrapped key.
  2. On every boot it unwraps the data key once (a single KMS call), keeps it in memory, and encrypts and decrypts secrets locally — so there's no KMS round-trip per secret.
  3. Your KMS records every unwrap, you hold the master key, and you rotate or revoke it there.

Set up HashiCorp Vault

Enable the Transit engine and create a key:

bash
vault secrets enable transit
vault write -f transit/keys/kravn

Give Kravn a token with encrypt/decrypt on that key, then configure:

bash
KRAVN_KMS_PROVIDER=vault
KRAVN_KMS_VAULT_ADDR=https://vault.internal:8200
KRAVN_KMS_VAULT_TOKEN=<token with transit encrypt/decrypt>
KRAVN_KMS_VAULT_KEY=kravn
KRAVN_KMS_VAULT_NAMESPACE=            # Vault Enterprise namespace (optional)

Set up Azure Key Vault

Create an RSA (or RSA-HSM) key in your vault, and an Entra app (client credentials) granted Wrap Key and Unwrap Key on it — for example the Key Vault Crypto User role. Then configure:

bash
KRAVN_KMS_PROVIDER=azure
KRAVN_KMS_AZURE_VAULT_URL=https://<vault>.vault.azure.net
KRAVN_KMS_AZURE_KEY=kravn-kek         # key name, or "name/version"
KRAVN_KMS_AZURE_TENANT_ID=<tenant id>
KRAVN_KMS_AZURE_CLIENT_ID=<app registration id>
KRAVN_KMS_AZURE_CLIENT_SECRET=<app secret>

Turn it on for an existing install

Adopting a KMS on a running install is safe and needs no downtime or bulk re-encryption:

  • Existing secrets keep decrypting — the bootstrap key is retained as a read-only fallback, so keep KRAVN_SECRET set after enabling a KMS.
  • New and edited secrets are written under the KMS key. Secrets you never touch stay on the old key and remain readable; re-saving one moves it to the KMS key.

Fail-closed

If a KMS is configured but unreachable or misconfigured, Kravn fails to start rather than falling back to a different key or running unprotected. Set it up, confirm it boots, then roll it out.

Don't remove or swap a KMS after adopting it

Once secrets are written under the KMS key, decryption needs it. Pointing KRAVN_KMS_PROVIDER back to none, or at a different KMS, is rejected/insufficient — switching key managers is a deliberate re-key migration, not a config swap.

Good to know

  • The KMS endpoint is operator infrastructure config (from the environment, like DATABASE_URL) — it's never user-supplied. Calls are bounded (no redirects, a timeout, a capped response).
  • Multi-replica: the first replica provisions the key; the others unwrap the same one, so all replicas agree.
  • On the roadmap: in-product key rotation and a bulk re-key command, moving token signing onto the KMS, and AWS KMS / GCP KMS providers (same interface).

For the full technical reference, see KEY_MANAGEMENT.md in the repository.


Related: Configuration · Security & compliance.

Source-available under the Business Source License 1.1 (converts to Apache 2.0). Built by AddLayer.