Environment reference
Every environment variable the gateway, vault, witness, dashboard, and MCP server read.
Gateway core
| Variable | Default | Meaning |
|---|---|---|
MANDARE_GATEWAY_HOST | 127.0.0.1 | Bind address. Non-loopback WITHOUT token/passport auth refuses to start. |
MANDARE_GATEWAY_PORT | 8484 | Port (0 = ephemeral). |
MANDARE_LEDGER_DB | ./mandare-ledger.db | The ledger. |
MANDARE_MANDATE_PATH | — | Mandate file (SD-JWT VC or legacy dev JSON). No mandate → spend path closed. |
MANDARE_DOOR_ID | gateway:local | Door identity in every entry. |
MANDARE_LEDGER_CURRENCY | EUR | One ledger currency. |
MANDARE_USD_PER_LEDGER_UNIT | — | Explicit USD rate; absent on a non-USD ledger ⇒ spend closed. |
MANDARE_GATEWAY_AUTH | auto | auto | token | passport | none — auto requires tokens iff a vault is wired. |
MANDARE_GATEWAY_ALLOWED_HOSTS | — | Extra Host-header values (DNS-rebinding guard). |
MANDARE_GATEWAY_PUBLIC_URL | — | Public base URL (approval buttons, webhook host auto-allow). |
MANDARE_MAX_CALLS_PER_MINUTE | 60 | Velocity floor. |
MANDARE_TRUST_AUTHORITY | — | Attestation-authority DID (passport mode). |
Providers
ANTHROPIC_API_KEY / ANTHROPIC_BASE_URL (no /v1) ·
OPENAI_API_KEY / OPENAI_BASE_URL (with /v1) ·
OPENROUTER_API_KEY / OPENROUTER_BASE_URL ·
MANDARE_CHAT_PROVIDER (openrouter|openai) ·
MANDARE_PRICING_PATH (operator pricing table: a JSON array of rows like
{"model": "gpt-4o", "aliases": ["gpt-4o-2024-08-06"], "inUsdPerM": 2.5, "outUsdPerM": 10, "cacheReadUsdPerM": 1.25, "maxOutputTokens": 16384} — ids
match exactly, so an unlisted variant is refused, never priced as a sibling;
every OpenRouter model a request names — fallbacks included — needs a row,
with maxInputTokens, and the door forwards the row's rates as
provider.max_price).
With MANDARE_VAULT=1 the vault is the source of truth and env keys are
ignored (the startup banner says so).
Vault
| Variable | Meaning |
|---|---|
MANDARE_VAULT=1 | Gateway sources door + provider keys from the vault. |
MANDARE_VAULT_BACKEND | keychain (default) or file (headless/CI). Keychain unavailable ⇒ fail closed, never plaintext. |
MANDARE_VAULT_DB / MANDARE_VAULT_KEY_FILE | Vault DB and (file backend) 0600 master key. |
Approvals
MANDARE_NOTIFIER (none|ntfy|file) · MANDARE_NTFY_URL /
MANDARE_NTFY_TOPIC · MANDARE_NOTIFY_FILE ·
MANDARE_APPROVAL_TIMEOUT_MS (default 120000; no decision ⇒ deny) ·
MANDARE_MAX_PENDING_APPROVALS (default 8, flood guard).
Witnessing
| Variable | Meaning |
|---|---|
MANDARE_WITNESS_URL | The witness. Setting ack mode without it refuses to start. |
MANDARE_WITNESS_PUBLIC_KEY | 64-hex Ed25519 key, out-of-band. Mandatory when the URL is set. |
MANDARE_WITNESS_ACK_MODE | threshold (default: the mandate's approval set waits for a verified ack) | all | off. |
MANDARE_WITNESS_ACK_TIMEOUT_MS | Default 1500; no verified ack ⇒ the action is refused. |
MANDARE_WITNESS_STREAM_INTERVAL_MS | Head-streaming cadence (default 1000). |
MANDARE_WITNESS_ANCHOR_TOKEN | Witness side: bearer token for remote POST /v1/anchor/run. Unset ⇒ on-demand runs are loopback-only with header x-mandare-anchor: run; always throttled to one per minute. |
Card rail (Stripe Issuing)
STRIPE_SECRET_KEY · STRIPE_WEBHOOK_SECRET (rail mounts IFF set) ·
STRIPE_CARDHOLDER_ID · STRIPE_API_BASE · STRIPE_API_VERSION ·
STRIPE_WEBHOOK_TOLERANCE_SECONDS · MANDARE_CARD_WAIVER_TTL_MS.
Dashboard & MCP server
Dashboard: MANDARE_LEDGER_DB, MANDARE_CLI (override CLI path),
MANDARE_WITNESS_URL + MANDARE_WITNESS_PUBLIC_KEY (or
MANDARE_WITNESS_PUBLIC_HEX file), MANDARE_GATEWAY_URL, and
MANDARE_DOOR_PUBLIC_KEY — the door's 64-hex public key obtained
out-of-band. Without it the verification badge is SELF-ANCHORED: the
witness check then compares the ledger against the source the file itself
names, which a file-level attacker controls.
MCP server: the same, plus MANDARE_MCP_HOME (artifact directory, default
~/.mandare/mcp) and
MANDARE_MCP_ALLOW_REINSTATE=1 (expose reinstate; off by default).