Complete reference for all Vaultaris environment variables.
Vaultaris is configured entirely through environment variables — no config files required. Values can be provided via a .env file (loaded with dotenvy) or injected by your container runtime / secret manager.
| Variable | Default | Description |
|---|
SERVER_HOST | 0.0.0.0 | IP address to bind |
SERVER_PORT | 8080 | TCP port to listen on |
EXTERNAL_URL | http://localhost:8080 | Public-facing base URL. Used in OAuth redirects, emails, and as the WebAuthn Relying Party origin. Changing it invalidates registered passkeys. |
| Variable | Default | Description |
|---|
DATABASE_URL | postgres://postgres:postgres@localhost:5432/vaultaris | PostgreSQL connection string |
DATABASE_MAX_CONNECTIONS | 10 | Maximum pool size per node |
DATABASE_MIN_CONNECTIONS | 1 | Minimum idle connections |
DATABASE_ACQUIRE_TIMEOUT_SECS | 30 | Seconds to wait for a pool connection |
Multi-node: Total DB connections = nodes × DATABASE_MAX_CONNECTIONS. Keep below PostgreSQL max_connections.
| Variable | Default | Description |
|---|
JWT_SECRET | change-me-in-production | HMAC-SHA256 signing key for short-lived internal tokens (MFA tokens, setup tokens). Change in production. |
JWT_ISSUER | $EXTERNAL_URL | iss claim in all issued tokens |
ENCRYPTION_KEY | change-me-in-production-32-chars | AES-256-GCM key for encrypting sensitive data at rest (TOTP secrets). Must be exactly 32 bytes. |
Access, refresh, and ID tokens use rotating ed25519 / ECDSA keys from the JWK set, not JWT_SECRET. Token lifetimes are configured per-tenant in the dashboard or via API.
| Variable | Default | Description |
|---|
EMAIL_ENABLED | false | When false, tokens are logged to stdout only. Set to true for production. |
EMAIL_PROVIDER | smtp | Active provider: smtp · sendgrid · mailgun · ses · brevo |
EMAIL_FROM_ADDRESS | noreply@vaultaris.local | Sender address |
EMAIL_FROM_NAME | Vaultaris | Sender display name |
| Variable | Default | Description |
|---|
SMTP_HOST | localhost | SMTP server hostname |
SMTP_PORT | 587 | 587 = STARTTLS · 465 = implicit TLS · 25 = plain |
SMTP_USERNAME | — | SMTP username |
SMTP_PASSWORD | — | SMTP password or API key |
SMTP_TLS | true | Enable STARTTLS |
| Variable | Default | Description |
|---|
SENDGRID_API_KEY | — | API key from the SendGrid dashboard |
| Variable | Default | Description |
|---|
BREVO_API_KEY | — | API key from the Brevo dashboard |
| Variable | Default | Description |
|---|
MAILGUN_API_KEY | — | API key |
MAILGUN_DOMAIN | — | Sending domain, e.g. mg.example.com |
MAILGUN_EU_REGION | false | Use EU endpoint (api.eu.mailgun.net) |
The IAM user needs ses:SendEmail permission. Uses SES v2 HTTP API with AWS Signature Version 4 — no SDK required.
| Variable | Default | Description |
|---|
SES_ACCESS_KEY_ID | — | AWS access key ID |
SES_SECRET_ACCESS_KEY | — | AWS secret access key |
SES_REGION | us-east-1 | AWS region |
| Variable | Default | Description |
|---|
REDIS_URL | unset | redis://localhost:6379. When unset, rate limiting is in-memory (single-node only). |
| Variable | Default | Description |
|---|
RATE_LIMIT_MAX_REQUESTS | 120 | Requests per IP per window |
RATE_LIMIT_WINDOW_SECS | 60 | Rolling window in seconds |
Uses Redis sliding-window algorithm (Lua script). Falls back to in-memory fixed-window when Redis is unavailable. Returns 429 with Retry-After header.
| Variable | Default | Description |
|---|
GEOIP_DATABASE_PATH | unset | Path to a MaxMind GeoLite2-Country .mmdb file. When unset, falls back to ip-api.com (45 req/min free tier). |
Download from MaxMind (registration required).
These variables connect a self-hosted Vaultaris instance to the cloud control plane for license management and telemetry. Omit entirely for air-gapped deployments.
| Variable | Default | Description |
|---|
CONTROL_PLANE_URL | unset | Base URL of the control plane API, e.g. https://cp.vaultaris.net |
HEARTBEAT_INTERVAL_SECS | 60 | How often the instance reports to the control plane |
TELEMETRY_INTERVAL_SECS | 900 | How often usage telemetry is sent (leader node only) |
GRACE_PERIOD_HOURS | 168 | Hours after a missed heartbeat before entering read-only mode (7 days) |
On each heartbeat, the control plane returns the current license limits and a status (ok or read_only). If the control plane is unreachable, the instance operates normally until the grace period expires, then switches to read-only mode (logins still work, all writes blocked).
License limits received from the control plane are applied immediately: a downgrade triggers LIFO freeze, an upgrade triggers FIFO unfreeze.
Used by the cloud control plane to manage billing shadow tenants on this instance. Only required on cloud-managed deployments.
| Variable | Default | Description |
|---|
BILLING_SHADOW_SERVICE_TOKEN | unset | Pre-shared token. Constant-time comparison protects against timing attacks. |
| Variable | Default | Description |
|---|
METRICS_ENABLED | true | Expose Prometheus-compatible metrics at /metrics |
# Development
RUST_LOG=info,vaultaris=debug,tower_http=debug
# Production (structured JSON via tracing-subscriber)
RUST_LOG=info
DATABASE_URL=postgres://vaultaris:strong-pass@db:5432/vaultaris
JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 16)
EXTERNAL_URL=https://auth.example.com
REDIS_URL=redis://redis:6379
RATE_LIMIT_MAX_REQUESTS=60
EMAIL_ENABLED=true
EMAIL_PROVIDER=sendgrid
SENDGRID_API_KEY=SG.xxxxx