configuration-reference
Keys & licensing
The master-key provider, hardware root and master binding, and on-prem license verification — the variables that control how Kutrion seals secrets and proves its entitlement.
Updated 16 अग॰ 2026
These variables control the cryptographic root of the platform and, for self-hosted deployments, how a
signed license is verified. Kutrion uses envelope encryption: every secret is sealed with a per-record
data key, and those data keys are wrapped by a master key. The key provider decides where that
master key lives and how it is unwrapped at boot. On-prem deployments can additionally bind the master
to the license and host, so that a cloned or forged instance boots but cannot decrypt the vault; this
is opt-in through LICENSE_BIND_MASTER and off by default. For the underlying design, see
Cryptography.
# HashiCorp Vault Transit
KEY_PROVIDER=hcv-transit
KEY_HCV_ADDR=https://vault.example.com:8200
KEY_HCV_AUTH=approle
KEY_HCV_ROLE_ID=<role-id>
KEY_HCV_SECRET_ID=<secret-id>
# ...or AWS KMS instead
# KEY_PROVIDER=aws-kms
# KEY_AWS_REGION=<region>
# KEY_AWS_KMS_KEY_ID=<key id, alias or ARN>
MASTER_KEY_CIPHERTEXT=<base64 from npm run seal-master>
DEPLOYMENT_MODE=onprem
LICENSE_PATH=/etc/vaultterm/license.vtlic
LICENSE_STATE_PATH=/var/lib/vaultterm/license.state
Key provider & master key
| Variable | Type | Default | Description |
|---|---|---|---|
KEY_PROVIDER | enum | local | local (uses DEV_MASTER_KEY), hcv-transit (HashiCorp Vault Transit) or aws-kms (AWS KMS customer managed key). |
DEV_MASTER_KEY | hex (64) | (empty) | 32-byte master key as hex (local provider only; dev/test). |
MASTER_KEY_CIPHERTEXT | base64 | (empty) | Sealed master key, for hcv-transit (Vault Transit ciphertext) or aws-kms (KMS CiphertextBlob); produced by npm run seal-master, which seals under whichever provider KEY_PROVIDER names. |
KEY_HCV_ADDR | URL | (empty) | HashiCorp Vault address. |
KEY_HCV_NAMESPACE | string | (empty) | Vault namespace (enterprise). |
KEY_HCV_AUTH | enum | token | token or approle. |
KEY_HCV_TOKEN | string | (empty) | Vault token (token auth). |
KEY_HCV_ROLE_ID | string | (empty) | AppRole role_id. |
KEY_HCV_SECRET_ID | string | (empty) | AppRole secret_id. |
KEY_HCV_TRANSIT_MOUNT | string | transit | Transit engine mount path. |
KEY_HCV_TRANSIT_KEY | string | vaultterm-master | Transit key name. |
KEY_AWS_REGION | string | AWS_REGION | Region of the KMS key (aws-kms). Required. |
KEY_AWS_KMS_KEY_ID | string | (empty) | KMS key id, alias or ARN (aws-kms). Required. |
KEY_AWS_ACCESS_KEY_ID | string | AWS_ACCESS_KEY_ID | Access key id for the KMS call. |
KEY_AWS_SECRET_ACCESS_KEY | string | AWS_SECRET_ACCESS_KEY | Secret access key for the KMS call. |
KEY_AWS_SESSION_TOKEN | string | AWS_SESSION_TOKEN | Session token, if you use temporary credentials. |
KEY_AWS_KMS_ENDPOINT | URL | (empty) | Override the KMS endpoint. |
For production, use hcv-transit or aws-kms so the master key is unwrapped at boot and never
exists as a static secret in your environment. The local provider with DEV_MASTER_KEY is intended
for development and test only.
hcv-transit— the master is unwrapped by a Vault Transit engine, which can itself be HSM-backed. ChoosetokenorapproleforKEY_HCV_AUTHand supply the matching credentials.aws-kms— the master is unwrapped by an AWS KMS customer managed key, which fits a deployment already governed by KMS key policy and CloudTrail. Credentials must be given explicitly through the variables above; Kutrion does not fall back to an instance role or the metadata service. TheKEY_AWS_*names take precedence, and the conventionalAWS_*names are used when they are unset, so a container that already carries them needs no duplicate configuration.
Either way there is one master key per deployment, chosen by whoever operates that deployment. Self-hosted, that is you. This is not per-organization keying, and naming a provider here is not a claim of any FIPS level, HSM backing or compliance status.
Hardware root & master binding (on-prem)
| Variable | Type | Default | Description |
|---|---|---|---|
ROOT_PROVIDER | enum | software | software (host fingerprint), kms (HSM-backed), or tpm/vtpm/enclave (reserved). |
ROOT_SOFTWARE_SECRET | string | (empty) | Extra entropy for the software root; back it up if set. |
LICENSE_BIND_MASTER | boolean (0/1) | 0 | Bind the master key to the license + host (a cloned or forged instance cannot decrypt). |
BOUND_MASTER_CIPHERTEXT | base64 | (empty) | Host-bound master ciphertext from npm run bind-master. |
RECOVERY_MODE | enum | customer-only | customer-only (vendor holds nothing) or managed (vendor holds one 2-of-3 break-glass share). |
PAYLOAD_KID_TTL_SEC | number | 3600 | Response-encryption session key lifetime. |
When LICENSE_BIND_MASTER=1, run npm run bind-master to produce BOUND_MASTER_CIPHERTEXT, which ties
the master to this license and host. RECOVERY_MODE decides who can recover: customer-only means the
vendor holds no recovery material whatsoever; managed means the vendor holds a single 2-of-3
break-glass share for assisted recovery. If you set ROOT_SOFTWARE_SECRET, back it up — losing it can
make a host-bound master unrecoverable. See Backups & recovery.
Confirm the settings reached the process. These are read at boot, and a value that sits in a file the container never sees is indistinguishable from one you never set — the server starts either way and says nothing. After changing any of them, recreate the container and check:
docker compose exec app printenv ROOT_PROVIDER LICENSE_BIND_MASTER
With LICENSE_BIND_MASTER=1 the stronger check is to leave DEV_MASTER_KEY unset: in production an
instance that cannot re-derive the license-bound unlock refuses to start, so a server that comes up is
a server that really opened the vault through the binding.
Licensing (on-prem)
| Variable | Type | Default | Description |
|---|---|---|---|
DEPLOYMENT_MODE | enum | saas | saas (hosted entitlements) or onprem (signed .vtlic license). |
LICENSE_PATH | string | (empty) | Path to the .vtlic license file. |
LICENSE_PUBLIC_KEY | base64 | (baked vendor key) | Override Ed25519 verification key(s); comma-separated for rotation. |
LICENSE_MLDSA_PUBLIC_KEY | base64 | (baked vendor key) | ML-DSA-65 key for quantum-safe composite verification. |
LICENSE_STATE_PATH | string | (empty) | Durable file for the monotonic anti-rollback counter. |
LICENSE_INSTALL_STATE_PATH | string | (next to state) | Durable file for the stable per-install id. |
LICENSE_HEARTBEAT_URL | string | (empty) | Optional connected check-in URL; empty means air-gapped (no phone-home). |
LICENSE_HEARTBEAT_INTERVAL_MS | number | 21600000 | Heartbeat interval (6h); only used when the URL is set. |
Set DEPLOYMENT_MODE=onprem to verify a signed .vtlic license at LICENSE_PATH. The license is
verified with a composite signature (Ed25519 plus ML-DSA-65), so both LICENSE_PUBLIC_KEY and
LICENSE_MLDSA_PUBLIC_KEY exist for key rotation and quantum-safe verification; the baked-in vendor keys
are used unless you override them. Point LICENSE_STATE_PATH and LICENSE_INSTALL_STATE_PATH at durable
storage so the anti-rollback counter and install id survive restarts. Leave LICENSE_HEARTBEAT_URL empty
for a fully air-gapped install with no phone-home; set it only if you want connected check-ins. See
Licensing & activation.