Configuration
Services are configured through environment variables. Each app validates critical variables at boot — a missing required variable refuses to start (fail-fast) instead of surfacing an opaque error on the first request.
.env file resolution
Production operations maintain one root .env.production; Docker Compose injects only each service’s allow-listed variables. Development continues to use .env.development. resolveEnvFilePath walks up from each app directory and picks a file by NODE_ENV:
NODE_ENV | File loaded |
|---|---|
production | .env.production → falls back to .env |
development (default) | .env.development → falls back to .env |
All .env* files are gitignored — never commit secrets. Start from the
generated .env.example; the complete catalog is in
docs/generated/environment-variables.md.
The registry lives at packages/shared/src/env/environment.registry.json. Run pnpm env:check, pnpm env:check:prod, or pnpm env:docs to validate or regenerate documentation. These commands never print variable values.
platform-api
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL | ✅ | Postgres connection string (Prisma) |
CLERK_SECRET_KEY | ✅ | Clerk backend key (auth) |
ENCRYPTION_SECRET_KEY | ✅ | AES-256-GCM field-level key for resume content |
CLERK_PUBLISHABLE_KEY | – | Clerk publishable key (must match the secret — both test or both live) |
CLERK_WEBHOOK_SECRET | – | Verify Clerk webhook (svix) signatures |
REDIS_HOST · REDIS_PORT · REDIS_PASSWORD | – | Redis (rate limiting / cache); defaults if absent |
CORS_ORIGINS | – | Allowed CORS origins (comma-separated) |
RESEND_API_KEY | – | Notification email delivery (Resend) |
SVIX_SERVER_URL · SVIX_TOKEN | – | For self-hosted svix (webhooks) |
DATABASE_POOL_MAX · DATABASE_POOL_IDLE_TIMEOUT_MS · DATABASE_POOL_CONNECTION_TIMEOUT_MS | – | pg connection-pool tuning |
Required: DATABASE_URL, CLERK_SECRET_KEY, ENCRYPTION_SECRET_KEY. The
rest are optional and enable their feature only when present.
agent-service
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL | ✅ | Postgres connection string (writes the agent run trace) |
CLERK_SECRET_KEY | ✅ | Auth (agent-service now authenticates every request) |
LLM_INTERNAL_API_KEY | ✅ (production) | Internal Relay mr_rk_ key or trusted provider credential |
LLM_INTERNAL_BASE_URL | ✅ (production) | Internal LLM/Relay URL; Docker uses http://relay:3113/v1 |
RELAY_INTERNAL_TOKEN | ✅ (production) | Trusted internal user-context token |
LLM_ALLOW_PRIVATE_BASE_URLS | – | User BYOK private-network policy; keep false when hosted |
AGENT_SKILLS_DIR | – | Mount path for the skills directory |
REDIS_HOST · CORS_ORIGINS | – | Same as platform-api |
Local development may still use a local model. Hosted production must
configure the internal LLM URL, key, and Relay context token explicitly.
LLM_BASE_URL and OPENAI_API_KEY remain compatibility aliases for one
release.
gateway
| Variable | Required | Purpose |
|---|---|---|
GATEWAY_INTERNAL_TOKEN | ✅ (production) | Shared secret the edge injects so backends trust edge identity |
CLERK_SECRET_KEY · CLERK_AUTHORIZED_PARTIES | ✅ (production) | Edge Clerk verification |
REDIS_PASSWORD (· REDIS_HOST · REDIS_PORT) | ✅ (production) | Rate-limit store |
CORS_ORIGINS | ✅ (production) | Allowed origins |
PLATFORM_API_URL · AGENT_SERVICE_URL · RELAY_SERVICE_URL · KEEPER_SERVICE_URL | – | Upstream targets the gateway routes to |
RATE_LIMIT_POINTS · RATE_LIMIT_DURATION_SEC | – | Edge rate-limit budget |
EDGE_AUTH_ENFORCE | – | Toggle edge auth enforcement |
UPSTREAM_PROXY_TIMEOUT_MS · HEALTH_PROBE_INTERVAL_MS · GATEWAY_PORT | – | Proxy / health / port tuning (port defaults 3110) |
relay
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL | ✅ | Postgres (relay keys, wallets, usage ledger) |
REDIS_PASSWORD (· REDIS_HOST · REDIS_PORT) | ✅ (production) | Key cache, rate limit, credit reservations |
GATEWAY_INTERNAL_TOKEN | ✅ (production) | Trust the edge |
RELAY_INTERNAL_TOKEN | ✅ (production) | Trusted internal user-context token (agent-service → relay) |
RELAY_UPSTREAM_API_KEY | ✅ (production) | Credential for the CLIProxyAPI upstream |
CORS_ORIGINS | ✅ (production) | Allowed origins |
RELAY_UPSTREAM_BASE_URL | – | Upstream URL (Docker default http://cliproxy:8317/v1) |
RELAY_CREDITS_PER_USD · RELAY_PRICING · RELAY_MODELS | – | Billing / pricing / model config |
RELAY_CIRCUIT_BREAKER_V2 · RELAY_USER_ENTITLEMENT_ENFORCEMENT_PERCENT · RELAY_PORT | – | Circuit-breaker / rollout / port (port defaults 3113) |
keeper
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL | ✅ | Postgres (usage events, stats, pricing) |
REDIS_PASSWORD (· REDIS_HOST · REDIS_PORT) | ✅ (production) | Queue / cache |
CLIPROXY_MANAGEMENT_KEY | ✅ (production) | CLIProxyAPI management API key |
CLERK_SECRET_KEY · CLERK_AUTHORIZED_PARTIES | ✅ (production) | Admin API auth |
GATEWAY_INTERNAL_TOKEN | ✅ (production) | Trust the edge |
CORS_ORIGINS | ✅ (production) | Allowed origins |
CLIPROXY_MANAGEMENT_BASE_URL | – | Management API URL (Docker default http://cliproxy:8317) |
KEEPER_REDIS_QUEUE_ADDR · KEEPER_INGEST_ENABLED · KEEPER_INGEST_BATCH_SIZE · KEEPER_RELIABLE_INGEST_REQUIRED | – | Usage-ingest reliable-queue tuning |
KEEPER_USAGE_HOURLY_AGGREGATION_ENABLED · KEEPER_USAGE_HOURLY_BACKFILL_DAYS · KEEPER_USAGE_HOURLY_RECONCILE_HOURS · KEEPER_PORT | – | Aggregation / port tuning (port defaults 3114) |
Next: Local development to get it running.