Skip to content

Environment Variables

All secrets, connection strings, and runtime tuning go in environment variables. Nothing sensitive is committed to git. Each service has a .env.example in its repo root — copy to .env and fill in values.

Common / shared

VariableRequiredPurpose
GORDON_DATABASE_URLYesBootstrap / superuser DSN. Used by gordon-migrate and dev scripts.
GORDON_BUS_NATS_URLYesNATS JetStream endpoint. Example: nats://localhost:4222
RUST_LOGNoTracing filter. Example: info,gordon=debug
RUST_BACKTRACENoEnable Rust backtraces. Set 1 in dev.

gordon-data

Source file: gordon-data/.env.example

VariableRequiredPurpose
DATABASE_URLYesPostgres DSN for gordon_data_writer role
GORDON_DATA_BIND_ADDRNoHTTP bind address. Default: 0.0.0.0:8081
GORDON_DATA_LOG_LEVELNoLog filter. Default: info
GORDON_DATA_BINANCE_API_KEYNoRead-only Binance key (raises rate limits, enables signed endpoints). Must NOT have withdrawal permission — startup probe aborts if enable_withdrawals=true.
GORDON_DATA_BINANCE_API_SECRETNoPaired secret for the above
BINANCE_SPOT_REST_URLNoOverride Binance Spot REST URL. Default: https://api.binance.com
BINANCE_SPOT_WS_URLNoOverride Binance Spot WS URL. Default: wss://stream.binance.com:9443
BINANCE_FUTURES_REST_URLNoOverride Binance Futures REST URL. Default: https://fapi.binance.com
BINANCE_FUTURES_WS_URLNoOverride Binance Futures WS URL. Default: wss://fstream.binance.com
GORDON_DATA_FRED_API_KEYNoFRED API key. Optional at runtime; required for historical macro backfill CLI.
GORDON_DATA_BINANCE_SPOT_SYMBOLSNoComma-separated symbols for spot ingest. Example: BTCUSDT,ETHUSDT
GORDON_DATA_BINANCE_PERP_SYMBOLSNoComma-separated symbols for perp ingest.
GORDON_DATA_BINANCE_FUNDING_SYMBOLSNoComma-separated symbols for funding rate ingest.

Read-only Binance keys only

gordon-data is the ONLY service that may hold Binance keys. They must be read-only (no trading, no withdrawal). The startup probe checks /sapi/v1/account/apiRestrictions and aborts if enable_withdrawals=true.

gordon-risk

Source file: gordon-risk/.env.example

VariableRequiredPurpose
GORDON_RISK_DATABASE_URLYesPostgres DSN for gordon_risk role
GORDON_RISK_BIND_ADDRNoHTTP bind address. Default: 0.0.0.0:8082
GORDON_RISK_LOG_LEVELNoLog filter. Default: info
GORDON_RISK_OPERATOR_TOKENYesPre-shared token for protected endpoints (POST /emergency-flatten, POST /risk/resume, POST /bots/:id/pause). Fail-closed: returns 503 if unset.

gordon-risk does NOT hold exchange keys. Trading keys live solely in gordon-executor.

gordon-manager

Source file: gordon-manager/.env.example, .env.dev.example

VariableRequiredPurpose
GORDON_MANAGER__DATABASE_URLYesPostgres DSN for gordon_manager role
GORDON_MANAGER__BIND_ADDRNoHTTP bind address. Default: 0.0.0.0:8083
GORDON_MANAGER_LOG_LEVELNoLog filter. Default: info
GORDON_MANAGER_OPERATOR_TOKENYesPrimary operator token. Browser mutations use this via X-Operator-Token header. Fail-closed.
GORDON_MANAGER__RISK_SERVICE_URLNogordon-risk URL for BFF proxy. Example: http://gordon-risk:8082
GORDON_MANAGER__DATA_SERVICE_URLNogordon-data URL for BFF reads. Example: http://gordon-data:8081
GORDON_MANAGER__GORDON_RISK_OPERATOR_TOKENNoForward token manager uses when proxying operator commands to gordon-risk.
GORDON_MANAGER__GORDON_ALERTMANAGER_URLNoAlertManager URL for GET /bff/alerts/firing. Unset → handler returns 503.
GORDON_MANAGER__GORDON_PROMETHEUS_URLNoPrometheus URL for GET /bff/bots/{bot_id}/metrics-summary. Unset → handler returns 503.
GORDON_MANAGER_DOCKER_SOCKET_PATHNodocker-socket-proxy endpoint. Default: unix:///var/run/docker-socket-proxy/docker.sock

gordon-bot

Source file: gordon-bot/.env.example

VariableRequiredPurpose
GORDON_BOT_IDYesUUIDv7 bot identifier. One unique value per container.
GORDON_BOT_DATABASE_URLYesPostgres DSN for gordon_bot role
GORDON_DATA_BASE_URLYesgordon-data REST base URL for warmup fallback.
GORDON_BUS_NATS_URLYesNATS endpoint for live candle subscription.
GORDON_BOT_BIND_ADDRNoHTTP bind address. Default: 0.0.0.0:8084 (container-internal)
GORDON_BOT_LOG_LEVELNoLog filter. Default: info
GORDON_BOT_STRATEGYNoStrategy name from StrategyRegistry. Production: a named strategy. E2E: manual.
GORDON_BOT_CANDLE_SOURCENodata-ws (default) or scripted (e2e fixture replay).

Banned exchange credentials

gordon-bot startup refuses to start if any of the following env vars are set. Exchange keys belong exclusively to gordon-executor.

BINANCE_API_KEY
BINANCE_API_SECRET
BINANCE_SECRET_KEY
BINANCE_TRADING_API_KEY
BINANCE_TRADING_SECRET_KEY
BINANCE_TESTNET_API_KEY
BINANCE_TESTNET_API_SECRET
BINANCE_TESTNET_SECRET
BINANCE_TESTNET_SECRET_KEY

gordon-executor

Source file: gordon-executor/.env.example, .env.executor.example

VariableRequiredPurpose
GORDON_EXECUTOR_DATABASE_URLYesPostgres DSN for gordon_executor role
GORDON_EXECUTOR_BIND_ADDRNoHTTP bind address. Default: 0.0.0.0:8085
GORDON_EXECUTOR_LOG_LEVELNoLog filter. Default: info
GORDON_EXECUTOR_OPERATOR_TOKENYesOperator token for POST /clear-quarantine, POST /flatten. Fail-closed.
GORDON_EXECUTOR_BREAK_GLASS_TOKENNoBreak-glass emergency token. Loaded lazily.
BINANCE_TESTNET_API_KEYYes (testnet)Trading-capable testnet key. Kept in .env.executor, not the global env.
BINANCE_TESTNET_API_SECRETYes (testnet)Paired testnet secret.
BINANCE_API_KEYYes (prod)Trading-capable production key. Distinct principal from gordon-data.
BINANCE_API_SECRETYes (prod)Paired production secret.
BINANCE_TESTNET_REST_URLNoTestnet REST URL. Default: https://testnet.binancefuture.com
BINANCE_TESTNET_WS_URLNoTestnet WS URL. Default: wss://stream.binancefuture.com
GORDON_EXECUTOR_MAX_NOTIONAL_USD_TESTNETNoMax notional per order on testnet.
GORDON_EXECUTOR_MAX_NOTIONAL_USD_PRODNoMax notional per order on production.
GORDON_EXECUTOR_MAX_DAILY_NOTIONAL_USD_PER_BOTNoOptional per-bot daily cap. Unset = warn-only mode.
GORDON_EXECUTOR_MAX_DAILY_NOTIONAL_USD_GLOBALNoOptional global daily cap. Unset = warn-only mode.

Testnet keys must stay out of the global env

BINANCE_TESTNET_API_KEY and BINANCE_TESTNET_API_SECRET must be sourced only to the executor process. Putting them in the global env would trip gordon-bot's banned-credentials check at startup. Use .env.executor (separate file, loaded only by the executor process in Procfile.dev).

gordon-console

Source file: gordon-console/.env.example

VariableRequiredPurpose
AUTH_SECRETYesJWT cookie encryption key. Generate: openssl rand -base64 32
AUTH_URLYesPublic origin for Auth.js callback URL. Example: https://gordon.lab
AUTH_TRUST_HOSTYesTrust X-Forwarded-* from nginx. Set true in production.
AUTH_KANIDM_ISSUERYesKanidm OIDC issuer URL. Example: https://auth.lepaux.com/oauth2/openid/gordon-console
AUTH_KANIDM_CLIENT_IDYesKanidm OIDC client id.
AUTH_KANIDM_CLIENT_SECRETYesKanidm OIDC client secret. Never in source.
GORDON_MANAGER_OPERATOR_TOKENYesOperator token injected as X-Operator-Token on every BFF mutation forwarded to gordon-manager. Never prefix with NEXT_PUBLIC_.
NEXT_PUBLIC_GORDON_MANAGER_URLNoBrowser-side manager URL. Example: http://localhost:8083
NEXT_PUBLIC_GORDON_DATA_URLNoBrowser-side data URL.
NEXT_PUBLIC_GORDON_RISK_URLNoBrowser-side risk URL (read-only; writes go through manager BFF).
GORDON_MANAGER_WS_INTERNAL_URLNoInternal WS URL for manager. Example: ws://gordon-manager:8083/ws
LOKI_URLNoLoki URL for the log viewer panel. Blank disables the panel.
GORDON_CONSOLE_E2E_INJECT_HEADERSNoSet true in e2e stack only — registers the Credentials auth provider. Must be false on srv-apps.
GORDON_CONSOLE_E2E_AUTH_TOKENNoE2e auth secret. E2e only.

gordon-lab

Source file: gordon-lab/.env.example

VariableRequiredPurpose
GORDON_DATABASE_URLYesRead-only Postgres DSN using the gordon_lab_reader role. INSERTs are revoked at the DB layer — any write attempt fails with InsufficientPrivilege.
FRED_API_KEYNoFRED API key for macro research scripts.

Conventions

  • .env files are gitignored across all repos. Never commit a populated .env.
  • Each service's .env.example is the source of truth for that service's variables.
  • Production values are managed via Ansible vault (homelab/ repo). Vault key names follow the pattern vault_gordon_<service>_<var>.
  • Operator tokens must be 256-bit random hex secrets in production: openssl rand -hex 32.

Gordon — keep compounding without blowing up