Bifrost

Environment variables

Every variable the gateway reads, with its default and what it controls.

The gateway validates its environment at startup and exits if a required variable is missing or malformed. Configure the five required values below, then review optional settings for your deployment. Gateway and dashboard processes read separate environment files.

Required

VariableFormatNotes
MASTER_KEYString, 32+ charsFull-access operator key. Generate with openssl rand -base64 48.
ENCRYPTION_KEYRINGJSON objectMaps key ids to 64-character hex AES keys. Keep old ids during rotation.
ACTIVE_ENCRYPTION_KEY_IDKey idMust exist in ENCRYPTION_KEYRING; encrypts every new envelope.
DATABASE_URLPostgres connection URL
REDIS_URLRedis connection URL

Server

VariableDefaultControls
PORT4000HTTP listen port.
TRUSTED_PROXY_HOPS0Number of rightmost, operator-controlled proxy hops trusted in X-Forwarded-For. 0 ignores the header.
PUBLIC_MODELS_RPM600Per-process anonymous /v1/models requests allowed each minute per resolved client IP. 0 disables the limit.
NODE_ENVdevelopmentdevelopment | test | production.
LOG_LEVELinfodebug | info | warn | error.
MIGRATE_ON_BOOTtrueApply pending migrations before the server listens. Every replica does it behind an advisory lock, so they serialise; a failure stops the process.
DRAIN_DELAY_MS15000 (0 outside production)How long /health/ready answers 503 while the process keeps serving, so the proxy can deregister it before the listener closes. See Rollouts.
SHUTDOWN_TIMEOUT_MS120000Grace for in-flight requests once the listener is closed. Must cover the longest streamed response.

Requests, logging, and limits

VariableDefaultControls
OBSERVABILITY_PAYLOAD_ACCESSopenWho may read a retained sample. open: a role with payloads:read, audited. sealed: nobody, through any credential — samples are still captured and encrypted, and the refused attempt is audited.
OBSERVABILITY_PAYLOAD_RETENTION_DAYS7Encrypted forensic payload retention.
OBSERVABILITY_METADATA_RETENTION_DAYS30Retention for completed operation and upstream-attempt metadata.
ADMIN_AUDIT_RETENTION_DAYS365Retention for the /admin audit trail. Outlives operation metadata: one row per configuration change, asked about months later.
OBSERVABILITY_PAYLOAD_MAX_BYTES32768Maximum size of each request, response, error, and attempt component in an encrypted sample after redaction.
IMAGES_MAX_MULTIPART_BYTES805000000 (~805 MB)Aggregate cap on an image multipart upload (images + mask + fields), streamed to temporary disk.
AUDIO_MAX_MULTIPART_BYTES30000000 (30 MB)Aggregate cap on an audio transcription multipart upload.
RESPONSES_STORE_DEFAULTtrueDefault for store when a /v1/responses request omits it. Set false for privacy-first deployments.
RESPONSES_STATE_RETENTION_DAYS14How long a stored Response (with store: true) stays retrievable via GET /v1/responses/:id.
RESPONSES_WEBSOCKET_MAX_CONNECTIONS1000Maximum live Responses WebSocket connections per gateway process.
RESPONSES_WEBSOCKET_MAX_CONNECTIONS_PER_KEY20Maximum live Responses WebSocket connections for one virtual key (the master key has its own scope).
RESPONSES_WEBSOCKET_MAX_QUEUED_TURNS64Maximum queued response.create turns per connection; one turn is processed at a time.
RESPONSE_STATE_GC_INTERVAL_MS3600000 (1h)How often the in-process job deletes expired response state.

Runtime extensions

VariableDefaultControls
EXTENSIONS_MAX_FAILURES3Consecutive hook failures before an extension instance is disabled for that process.
EXTENSIONS_RELOAD_INTERVAL_MS15000How often each replica polls for a changed extension registry to hot-reload.
EXTENSIONS_MAX_CODE_BYTES1000000 (1 MB)Maximum size of an uploaded extension module's source.
EXTENSIONS_HOOK_TIMEOUT_MS5000Per-hook wall-clock budget. 0 disables the timeout. An exceeded hook is aborted and counts as a failure.

Dashboard authentication

Optional, and off by default. When disabled the gateway never mounts /auth/* or /admin/users, and /admin accepts only the master key — exactly as before this surface existed. The tables are created either way and simply stay empty.

VariableDefaultControls
DASH_ENABLEDfalseMaster switch. Enabling it requires DASH_ROOT_USER; the process refuses to start otherwise.
DASH_ROOT_USER—Root operator's username. Read from the environment, never stored in the database, so it cannot be disabled, demoted, or deleted.
DASH_ROOT_PASSWORDfalls back to MASTER_KEYRoot operator's password.

Session lifetime, the idle window and the login lockout are not environment variables: they are policy an owner edits from Settings › Operator sessions, or through PUT /admin/dashboard-settings. Changing them takes effect within seconds, without a redeployment, and the change is audited like any other.

Set DASH_ROOT_PASSWORD in production rather than relying on the fallback: MASTER_KEY and the dashboard password have different rotation cycles, and sharing one value means rotating the API credential logs every operator out. See Security.

Dashboard process

Read by the dashboard container, not by the gateway. The full list is apps/dashboard/.env.example; the documentation site needs nothing at all. Nothing is baked into its image, so all of them take effect on restart and one image tag can be promoted between environments unchanged.

VariableDefaultControls
GATEWAY_URL—Where the gateway is. Required. Only this container needs to reach it — the browser never leaves the dashboard's own origin, so the gateway needs no public domain.
PORT3001Listen port (DASH_PORT in development).

The dashboard checks the address before it accepts its first request, so a missing one is a container that exits with the reason printed rather than one that starts and then fails every page.

DASH_ENABLED is read by the gateway — it gates /auth/* and /admin/users there. The Compose files in this repository reuse it as a single switch for the pair, so the dashboard container exits cleanly when it is false.

Observability (OpenTelemetry)

VariableDefaultControls
OTEL_ENABLEDfalseMaster switch. Metrics/traces are otherwise not exported at all.
OTEL_SERVICE_NAMEbifrostService name attached to exported telemetry.
OTEL_METRIC_EXPORT_INTERVAL_MS60000How often metrics are pushed to the collector.

These are read by the gateway's own schema. Once OTEL_ENABLED=true, the exporters (OTLPMetricExporter, OTLPTraceExporter) also read the standard OpenTelemetry SDK environment variables directly — notably OTEL_EXPORTER_OTLP_ENDPOINT and OTEL_EXPORTER_OTLP_HEADERS — which are not gateway-specific and so aren't validated by the schema above. See Observability for a working example.

Boolean variables (RESPONSES_STORE_DEFAULT, OTEL_ENABLED, DASH_ENABLED) accept 1/true/yes/on or 0/false/no/off, case-insensitively.

Next steps

On this page