Appearance
Environment Variables
All variables are read from the hosting platform's environment (Render for the API, Cloudflare for the Workers, Pages build env for the frontend). This documentation lists names and purposes only — no values. Secrets are never committed, never logged, and never exposed to the browser.
API — production (legacy names; PRODUCTION_* overrides)
| Variable | Required | Purpose |
|---|---|---|
SUPABASE_URL | yes | Supabase project URL |
SUPABASE_KEY | yes | service_role key (server only) |
OAUTH_SESSION_SECRET | yes | Session cookie signing secret |
API_KEY | for bot features | BotGhost shared key (Authorization header) |
DISCORD_CLIENT_ID / DISCORD_CLIENT_SECRET / DISCORD_REDIRECT_URI | for login | Discord OAuth app |
DASHBOARD_ORIGIN | yes | Allowlisted CORS origin(s), comma-separated |
TRAINING_ORIGIN | no | Default https://training.eccdps.org |
SUPABASE_ANON_KEY | for Realtime | Public anon key (served to sessions) |
SUPABASE_JWT_SECRET | for Realtime | Signs browser Realtime JWTs (server only) |
DISCORD_OAUTH_PROXY_URL / DISCORD_OAUTH_PROXY_SECRET | no | OAuth Worker proxy |
ERLC_RELAY_URLS / ERLC_RELAY_TOKEN | yes | ER:LC residential relay (comma-separated URLs, primary first) |
ERLC_SERVER_KEY | dev only | Direct ER:LC server key fallback (local dev/tests) |
SESSION_COOKIE_SECURE | no | Default true |
SESSION_COOKIE_SAMESITE | no | Default Lax |
REALTIME_TOKEN_TTL_SECONDS | no | Default 600 |
PRODUCTION_API_HOSTS | no | Default api.eccdps.org |
PRODUCTION_SESSION_COOKIE_NAME | no | Default eccdps_production_session |
PRODUCTION_INGRESS_SECRET | no | HMAC ingress assertion (when enabled) |
ECCDPS_DEV_HOSTS | dev only | Local host → environment mapping |
API — demo (all DEMO_*, no legacy fallback)
| Variable | Purpose |
|---|---|
DEMO_SUPABASE_URL / DEMO_SUPABASE_SERVICE_KEY / DEMO_SUPABASE_ANON_KEY / DEMO_SUPABASE_JWT_SECRET | Demo Supabase project |
DEMO_OAUTH_SESSION_SECRET | Demo session secret |
DEMO_API_KEY | Demo bot key |
DEMO_DISCORD_CLIENT_ID / DEMO_DISCORD_CLIENT_SECRET / DEMO_DISCORD_REDIRECT_URI | Demo Discord app (https://demo-api.eccdps.org/auth/discord/callback) |
DEMO_DISCORD_OAUTH_PROXY_URL / DEMO_DISCORD_OAUTH_PROXY_SECRET | Demo OAuth proxy |
DEMO_DASHBOARD_ORIGINS | Default https://demo.eccdps.org |
DEMO_TRAINING_ORIGIN | Optional demo training host |
DEMO_API_HOSTS | Default demo-api.eccdps.org |
DEMO_SESSION_COOKIE_NAME | Default eccdps_demo_session |
DEMO_INGRESS_SECRET | Demo ingress assertion |
DEMO_ALLOWED_DISCORD_IDS | Real Discord IDs allowed into the demo (id or real_id:demo_agent_id) |
DEMO_AUTO_RESET_ENABLED | Enable the daily demo auto-reset daemon |
An incomplete demo configuration makes the demo environment unavailable; it never falls back to production credentials. The API fails fast at boot when the production environment is not configured.
Frontend (browser bundle — public only)
| Variable | Purpose |
|---|---|
VITE_DPS_API_BASE_URL | Public API base URL (production https://api.eccdps.org; demo https://demo-api.eccdps.org) |
VITE_APP_ENV | Optional explicit environment hint (demo) |
DPS_API_BASE_URL / DPS_API_KEY | Dev-server proxy only (never in the bundle; vite.config.ts) |
Workers
| Variable | Where | Purpose |
|---|---|---|
DISCORD_CLIENT_ID / DISCORD_CLIENT_SECRET | discord-oauth-proxy Worker secrets | OAuth token exchange |
WORKER_SECRET | discord-oauth-proxy Worker secret | Authenticates the API (X-Worker-Secret) |
PRODUCTION_INGRESS_SECRET / DEMO_INGRESS_SECRET | cloudflare/ingress_worker.js | HMAC assertion signing |
PRODUCTION_ORIGIN / DEMO_ORIGIN | ingress Worker | Render origins to forward to |
Security rules
- Server-only values (
SUPABASE_KEY,SUPABASE_JWT_SECRET,OAUTH_SESSION_SECRET,API_KEY, client secrets, ingress secrets, relay token) never enter the browser bundle or this documentation. db.urland.env*files are secret-bearing, git-ignored, and only used locally (apply_rpc_migrations.py, dev servers).- Rotate via the platform consoles; after rotating the session secret, existing sessions invalidate once (environment-bound sessions).