The proxy-router is configured through .env (or container env vars). This page documents every variable. The canonical .env.example lives in the repo at proxy-router/.env.example and the full annotated dump at docs/proxy-router.all.env.
Defaults below are from the source of truth (proxy-router/internal/config/config.go). When in doubt, the source wins.

Conflicting / overlapping variables — read this first

Several pairs of variables look like they do “the same thing.” They don’t. The proxy-router resolves each pair with a specific precedence rule, and getting it wrong is a common cause of “I changed the env but nothing happened.”
For every *_CONTENT*_PATH pair below, the *_CONTENT variable is a one-shot file seeder, not a runtime override. It only takes effect when the corresponding file does not exist. After the first successful start the file exists, and changing the *_CONTENT env on subsequent runs has no effect until you delete the file at *_PATH.
SituationWhat the proxy-router does
File at COOKIE_FILE_PATH already existsReads the file. COOKIE_CONTENT is silently ignored.
File does not exist + COOKIE_CONTENT is setWrites COOKIE_CONTENT to the file (username:password\n), then reads it.
File does not exist + COOKIE_CONTENT is unsetGenerates a random 32-char password for admin, writes it to the file.
Source: proxy-router/internal/system/auth.go (EnsureConfigFilesExist). Practical implications
  • For TEE / Akash / ephemeral container deployments, set COOKIE_CONTENT once on first start; the file gets seeded inside the volume and persists.
  • To rotate credentials on a self-hosted node, use the POST /auth/users endpoint (or edit the cookie file in place) — changing COOKIE_CONTENT after first start does nothing.

MODELS_CONFIG_PATHMODELS_CONFIG_CONTENT

SituationWhat the proxy-router does
File at MODELS_CONFIG_PATH already existsReads the file. MODELS_CONFIG_CONTENT is silently ignored.
File does not exist + MODELS_CONFIG_CONTENT is setWrites MODELS_CONFIG_CONTENT to the file, then reads it.
File does not exist + MODELS_CONFIG_CONTENT is unsetLogs a warning and runs with an empty model registry.
Source: proxy-router/internal/config/models_config.go (ModelConfigLoader.Init). Practical implications
  • Use MODELS_CONFIG_CONTENT (single-line JSON) in TEE/Akash deployments where you can’t mount a volume.
  • To update models on a self-hosted node, edit the JSON file directly and restart — don’t bump MODELS_CONFIG_CONTENT. See models-config.json.

AGENT_CONFIG_PATHAGENT_CONFIG_CONTENT

Same *_CONTENT-only-seeds-the-file rule as the two above. Source: proxy-router/internal/config/agents_config.go.

AUTH_CONFIG_FILE_PATH (no inline twin)

Path to proxy.conf, which holds rpcauth= and rpcwhitelist= lines. There is no AUTH_CONFIG_CONTENT env — the file is built at runtime by the proxy-router itself when you add users via POST /auth/users. For TEE / ephemeral deployments, proxy.conf is created on first start (with the admin entry derived from the cookie file) and managed via the API afterwards.

WALLET_PRIVATE_KEY ↔ system keychain

SituationWhat the proxy-router does
WALLET_PRIVATE_KEY is setUses it. The keychain is not read.
WALLET_PRIVATE_KEY is unset and the OS supports a keychain (macOS)Reads / writes the key from the system keychain.
NeitherRefuses to start signing transactions; read-only operations still work.
APP_RESET_KEYCHAIN=true wipes the macOS keychain entry on start (use with care).

WEB_PUBLIC_URL fallback

If WEB_PUBLIC_URL is unset, the proxy-router synthesizes http://localhost:<port-from-WEB_ADDRESS>. For provider deployments where consumers must reach you over the public internet, always set this explicitly to your public URL (e.g. https://provider.example.com). The TLS-pinning step in TEE attestation reads this URL.

ETH_NODE_USE_SUBSCRIPTIONSETH_NODE_POLLING_INTERVAL

Not a precedence pair, but easy to misconfigure:
  • ETH_NODE_USE_SUBSCRIPTIONS=true → expects a WSS ETH_NODE_ADDRESS (e.g. wss://...). Polling interval is irrelevant.
  • ETH_NODE_USE_SUBSCRIPTIONS=false (default) → expects an HTTPS ETH_NODE_ADDRESS and uses ETH_NODE_POLLING_INTERVAL (default 10 seconds).
Mismatch (e.g. subscriptions=true with HTTPS endpoint) makes the node fail to receive blockchain events even though startup may look healthy.

PROXY_STORE_CHAT_CONTEXT is TEE-frozen

In the -tee image this is hard-coded false at build time and cannot be overridden at runtime. Setting it in the env has no effect inside a TEE deployment. See TEE reference.

Application

VariableDefaultNotes
APP_RESET_KEYCHAINfalseSet true to reset the macOS keychain entry on start
AUTH_CONFIG_FILE_PATH./proxy.confPath to the auth config file (no inline twin)
COOKIE_FILE_PATH./.cookiePath to admin cookie file
COOKIE_CONTENT(unset)Seeds the cookie file on first start only. See precedence above.

Blockchain

VariableDefaultNotes
ETH_NODE_CHAIN_ID8453 (mainnet) / 84532 (testnet)BASE chain ID
ETH_NODE_ADDRESS(unset, falls back to built-in public RPC round-robin)RPC endpoint URL (HTTPS or WSS — must match ETH_NODE_USE_SUBSCRIPTIONS). Set explicitly for any real deployment — the public round-robin fallback is rate-limited and unreliable; missed events break the node silently.
ETH_NODE_LEGACY_TXfalseSet true to disable EIP-1559
BLOCKSCOUT_API_URLhttps://base.blockscout.com/api/v2Block explorer API
EXPLORER_RETRY_DELAY5Delay between explorer retries (seconds)
EXPLORER_MAX_RETRIES5Max explorer retries
ETH_NODE_USE_SUBSCRIPTIONSfalsetrue to use WSS subscriptions; false for HTTP polling
ETH_NODE_POLLING_INTERVAL10Polling interval (seconds, only when ETH_NODE_USE_SUBSCRIPTIONS=false)
ETH_NODE_MAX_RECONNECTS30Max reconnect attempts

Environment

VariableDefaultNotes
ENVIRONMENTdevelopmentUse production in deployments

Marketplace

VariableDefaultNotes
DIAMOND_CONTRACT_ADDRESSmainnet 0x6aBE1d282f72B474E54527D93b979A4f64d3030a; testnet 0x6e4d0B775E3C3b02683A6F277Ac80240C4aFF930Diamond marketplace contract
MOR_TOKEN_ADDRESSmainnet 0x7431aDa8a591C955a994a21710752EF9b882b8e3; testnet 0x5C80Ddd187054E1E4aBBfFCD750498e81d34FfA3MOR ERC-20 token
WALLET_PRIVATE_KEY(unset)Wallet private key. Falls back to system keychain when unset. See precedence above.

Logging

VariableDefaultNotes
LOG_COLORfalseColored console output
LOG_FOLDER_PATH(unset)If set, also write logs to files in this directory
LOG_IS_PRODfalseProduction log format
LOG_JSONfalseJSON-formatted log lines
LOG_LEVEL_APPwarnApp-level log level: debug info warn error dpanic panic fatal
LOG_LEVEL_TCPwarnTCP layer log level
LOG_LEVEL_ETH_RPCwarnEthereum RPC log level
LOG_LEVEL_STORAGEwarnBadger storage log level
For TEE images logging is frozen to production / JSON / minimal at build time — these vars have no effect inside a -tee image.

Network ports & URLs

VariableDefaultNotes
WEB_ADDRESS0.0.0.0:8082Bind for the HTTP/Swagger API
WEB_PUBLIC_URLhttp://localhost:<WEB_ADDRESS port>Public-facing URL of the API. Set explicitly for any provider that consumers must reach.
PROXY_ADDRESS0.0.0.0:3333Bind for the consumer-to-provider TCP proxy

Proxy state & configs

VariableDefaultNotes
MAX_CACHED_DESTS5Max cached provider destinations
PROXY_STORAGE_PATH./data/badger/Local Badger / runtime state
PROXY_STORE_CHAT_CONTEXTtruePersist chat context. Frozen false in -tee images.
PROXY_FORWARD_CHAT_CONTEXTtruePrepend stored history to prompts
MODELS_CONFIG_PATH./models-config.jsonSee models-config. See precedence above.
MODELS_CONFIG_CONTENT(unset)Seeds the models config file on first start only. See precedence above.
AGENT_CONFIG_PATH(built-in default)Local agent registry path
AGENT_CONFIG_CONTENT(unset)Seeds the agent config file on first start only. Same rules as the models pair.
RATING_CONFIG_PATH./rating-config.jsonSee rating-config

Timeouts & retries

VariableDefaultNotes
LLM_TIMEOUT(depends on release)P-Node → backend LLM timeout (streaming + non-streaming)
CNODE_PNODE_TIMEOUT(depends on release)Per-attempt timeout for C-Node waiting for P-Node first response
CNODE_PNODE_MAX_RETRIES(depends on release)Max retries for C-Node → P-Node read timeout (chat / embeddings)
CNODE_PNODE_AUDIO_MAX_RETRIES(depends on release)Max retries for audio transcription / speech routes
For exact defaults check the source of truth (config.go) — these can change between releases as we tune the network.

Model health self-checks (provider)

On provider nodes the proxy-router periodically probes every model from models-config.json that has an active bid from this provider: LLM models get a small dynamically generated arithmetic prompt (correctness is graded), embedding models get an embeddings request, and other model types are skipped. The report covers the whole ecosystem of bids and configured models — active bids whose model is missing from models-config.json are flagged as no_model_configured (capacity being sold with no backend to serve it). The cached per-model results (on-chain modelId and registered model name, bidId, status, errorKind plus upstream httpStatus on failure, lastHealthy epoch, latency, prompt correctness — never the private models-config.json modelName, apiUrl, or apiKey) are exposed in the models field of GET /healthcheck, in the network.ping (pong) response on the :3333 MOR RPC port, and in POST /proxy/provider/ping, so consumers can see a provider’s model health before opening a session. Full operational guide: Model health self-report.
VariableDefaultNotes
MODEL_HEALTH_CHECK_DISABLEDfalseSet true to disable the loop (the models field disappears from /healthcheck)
MODEL_HEALTH_CHECK_INTERVAL1hHow often models are probed; results are cached between runs
MODEL_HEALTH_CHECK_TIMEOUT60sPer-model probe timeout
MODEL_HEALTH_CHECK_PROBE_DELAY2sPause between per-model probes so many-model providers don’t burst their upstream into a rate limit

TEE (Phase 1 + Phase 2 attestation)

These are only consulted when at least one model in the marketplace is tee-tagged. Otherwise they are unused.
VariableDefaultNotes
TEE_PORTAL_URLhttps://secretai.scrtlabs.com/apiSecretAI Portal used to verify raw TDX CPU quotes
TEE_IMAGE_REPOghcr.io/morpheusais/morpheus-lumerin-node-teeGHCR repo where the consumer-side P-Node attestation fetches the signed golden manifest via cosign
ARTIFACT_REGISTRY_URLhttps://raw.githubusercontent.com/scrtlabs/secretvm-verify/main/artifacts_registry/tdx.csvSecretVM TDX artifact registry CSV (MRTD + RTMR0-2 lookup)
ARTIFACT_REGISTRY_REFRESH_INTERVAL1hHow often the proxy-router re-downloads the artifact registry
See TEE overview and TEE reference.

System tuning (optional sysctl tweaks)

These map to OS-level adjustments and only apply when SYS_ENABLE=true.
VariableDefaultNotes
SYS_ENABLEfalseSet true to apply the values below at startup
SYS_LOCAL_PORT_RANGE1024 65535
SYS_NET_DEV_MAX_BACKLOG100000
SYS_RLIMIT_HARD524288
SYS_RLIMIT_SOFT524288
SYS_SOMAXCONN100000 (Linux) / 2048 (Darwin/macOS)
SYS_TCP_MAX_SYN_BACKLOG100000

Mainnet vs testnet quick switch

Comment / uncomment the appropriate block in .env:

Full annotated dump

For the complete annotated reference (every variable, every example value), see docs/proxy-router.all.env in the repo.