Skip to content
Kutrion
Browse docs

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

VariableTypeDefaultDescription
KEY_PROVIDERenumlocallocal (uses DEV_MASTER_KEY), hcv-transit (HashiCorp Vault Transit) or aws-kms (AWS KMS customer managed key).
DEV_MASTER_KEYhex (64)(empty)32-byte master key as hex (local provider only; dev/test).
MASTER_KEY_CIPHERTEXTbase64(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_ADDRURL(empty)HashiCorp Vault address.
KEY_HCV_NAMESPACEstring(empty)Vault namespace (enterprise).
KEY_HCV_AUTHenumtokentoken or approle.
KEY_HCV_TOKENstring(empty)Vault token (token auth).
KEY_HCV_ROLE_IDstring(empty)AppRole role_id.
KEY_HCV_SECRET_IDstring(empty)AppRole secret_id.
KEY_HCV_TRANSIT_MOUNTstringtransitTransit engine mount path.
KEY_HCV_TRANSIT_KEYstringvaultterm-masterTransit key name.
KEY_AWS_REGIONstringAWS_REGIONRegion of the KMS key (aws-kms). Required.
KEY_AWS_KMS_KEY_IDstring(empty)KMS key id, alias or ARN (aws-kms). Required.
KEY_AWS_ACCESS_KEY_IDstringAWS_ACCESS_KEY_IDAccess key id for the KMS call.
KEY_AWS_SECRET_ACCESS_KEYstringAWS_SECRET_ACCESS_KEYSecret access key for the KMS call.
KEY_AWS_SESSION_TOKENstringAWS_SESSION_TOKENSession token, if you use temporary credentials.
KEY_AWS_KMS_ENDPOINTURL(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. Choose token or approle for KEY_HCV_AUTH and 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. The KEY_AWS_* names take precedence, and the conventional AWS_* 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)

VariableTypeDefaultDescription
ROOT_PROVIDERenumsoftwaresoftware (host fingerprint), kms (HSM-backed), or tpm/vtpm/enclave (reserved).
ROOT_SOFTWARE_SECRETstring(empty)Extra entropy for the software root; back it up if set.
LICENSE_BIND_MASTERboolean (0/1)0Bind the master key to the license + host (a cloned or forged instance cannot decrypt).
BOUND_MASTER_CIPHERTEXTbase64(empty)Host-bound master ciphertext from npm run bind-master.
RECOVERY_MODEenumcustomer-onlycustomer-only (vendor holds nothing) or managed (vendor holds one 2-of-3 break-glass share).
PAYLOAD_KID_TTL_SECnumber3600Response-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)

VariableTypeDefaultDescription
DEPLOYMENT_MODEenumsaassaas (hosted entitlements) or onprem (signed .vtlic license).
LICENSE_PATHstring(empty)Path to the .vtlic license file.
LICENSE_PUBLIC_KEYbase64(baked vendor key)Override Ed25519 verification key(s); comma-separated for rotation.
LICENSE_MLDSA_PUBLIC_KEYbase64(baked vendor key)ML-DSA-65 key for quantum-safe composite verification.
LICENSE_STATE_PATHstring(empty)Durable file for the monotonic anti-rollback counter.
LICENSE_INSTALL_STATE_PATHstring(next to state)Durable file for the stable per-install id.
LICENSE_HEARTBEAT_URLstring(empty)Optional connected check-in URL; empty means air-gapped (no phone-home).
LICENSE_HEARTBEAT_INTERVAL_MSnumber21600000Heartbeat 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.