configuration-reference
Configuration overview
VaultTerm is entirely environment-driven: one image runs in dev, staging, or on-prem, and only the .env changes. This page covers where config lives and the production boot guards.
Updated Jun 23, 2026
VaultTerm is configured almost entirely through environment variables. There is one image and one
codebase; the same build runs in local development, in staging, or on a customer’s own hardware. The
only thing that differs between those environments is the .env file. There are no per-environment
code branches and no hardcoded hosts, endpoints, or secrets baked into the build — everything that
points at infrastructure is a variable you set, which is what makes the platform cloud-portable and
safe to run air-gapped.
# A minimal self-hosted core
NODE_ENV=production
PORT=4000
APP_BASE_URL=https://vault.example.com
DATABASE_URL=postgres://vaultterm:[email protected]:5432/vaultterm
REDIS_URL=redis://cache.example.com:6379
JWT_SECRET=replace-with-a-long-random-secret-at-least-32-bytes
KEY_PROVIDER=local
DEV_MASTER_KEY=<64 hex chars>
Where configuration lives
For self-hosting, the canonical template is deploy/onprem/.env.example. Copy it to .env, fill in
the values for your environment, and pass it to the container (Docker Compose reads it automatically;
an air-gapped install mounts it). The template is the source of truth for every variable the platform
reads — the reference pages below describe the subset a customer running their own instance legitimately
sets, grouped by concern.
In development the server falls back to safe local defaults (a localhost API origin, a dev master key, a dev signing secret) so it boots with almost no configuration. Those defaults are explicitly not safe for production, which is what the boot guards below exist to enforce.
Production boot guards
When NODE_ENV=production, the server refuses to start in a knowingly-insecure state rather than
booting with a weak default. Two guards matter most:
- JWT secret guard. A weak, short, or dev-default
JWT_SECRETis fatal under production. The secret must be at least 32 bytes and must not be the built-in development value. This prevents an instance from signing session tokens with a guessable key. See Authentication & sessions. - Private-network egress guard. Server-side outbound fetches to private, loopback, and
cloud-metadata targets (RFC1918 ranges,
127.0.0.0/8, link-local metadata addresses) are blocked under production unless you explicitly setEGRESS_ALLOW_PRIVATE=1. This is an anti-SSRF control: a webhook URL, SSO endpoint, or AI provider that resolves to an internal address will be refused unless you have opted in because you genuinely run those services on a private network. See Core & database configuration.
Other production behaviors follow the same fail-closed principle — for example the Prometheus
/metrics endpoint requires a token under production rather than serving openly. These are documented
alongside the variables that control them on the reference pages.
Reference pages
The full variable reference is split by concern:
- Core & database configuration — server, networking, PostgreSQL, Redis, observability, and egress.
- Authentication & sessions — tokens, WebAuthn, SSO, and social login.
- Keys & licensing — the key provider, master-key binding, hardware root, and on-prem licensing.
- AI & egress integrations — the AI provider and transactional mail.
For the bigger picture, see Self-hosting overview and Architecture overview.