Configuration & environment
The API server reads 99 environment variables. The Required column below marks vars validated by requiredEnv() — they fail startup in every environment. Only JWT_SECRET is marked this way, because it has no safe default (a hardcoded signing key would be a security hole). The rest of the required-config story:
- Database (required to start): supply either
DATABASE_URLor the fullDATABASE_HOST/DATABASE_PORT/DATABASE_NAME/DATABASE_USERNAME/DATABASE_PASSWORDset. The ECS deployment uses the 5-part form (each part is a separate secret). - Production boot check: when
NODE_ENV=production,loadConfig()runsassertProdConfig()and fails fast with a single aggregated error naming every missing must-have var (JWT_SECRETand/or the database) — before it fails late at first use. Development and test are unaffected, so local runs and CI work with prod secrets unset. REDIS_URL: optional — the sim queue falls back to an in-memory single-process mode. It is required only for the multi-tier deployment where the wind-worker consumes the shared queue, and is guarded per-tier at boot (worker-mainexits, the enqueue path throws).- Everything else has a default or degrades gracefully — an unset integration key (e.g. FIRMS, Resend, Twilio, OAuth) simply disables that feature, even in production.
Full per-variable notes (what consumes each, rotation, prod source) are in the hand-maintained CONFIGURATION-INVENTORY.md.
| Variable | Required | Default |
|---|---|---|
AGENCY_ACCOUNTS_ENABLED | no | false |
AGENCY_DELEGATION_ENABLED | no | false |
ANTHROPIC_API_KEY | no | null |
BROADCAST_CAP_KM2 | no | 2000 |
BROADCAST_CAP_RECIPIENTS | no | 500 |
BROADCAST_ENABLED | no | false |
CONTACT_EMAIL | no | (computed) |
CORS_ALLOWED_ORIGINS | no | "" |
DATABASE_HOST | no | raw process.env |
DATABASE_NAME | no | raw process.env |
DATABASE_PASSWORD | no | raw process.env |
DATABASE_PORT | no | raw process.env |
DATABASE_URL | no | raw process.env |
DATABASE_USERNAME | no | raw process.env |
DB_BOOTSTRAP_ON_BOOT | no | false |
DEA_HOTSPOTS_BASE_URL | no | (computed) |
DEA_INGEST_ENABLED | no | true |
DEA_INGEST_INTERVAL_MIN | no | 10 |
DELEGATED_AUTHORITY_ENABLED | no | false |
ENABLE_TEST_LOGINS | no | raw process.env |
EXCLUSION_ZONES_ENABLED | no | false |
FIRE_CLUSTERING_ACTIVE_HOURS | no | 24 |
FIRE_CLUSTERING_ADJ_DIST_M | no | 3000 |
FIRE_CLUSTERING_ENABLED | no | true |
FIRE_CLUSTERING_INACTIVITY_HOURS | no | 120 |
FIRE_CLUSTERING_LINK_DIST_M | no | 5000 |
FIRE_CLUSTERING_MIN_POINTS | no | 1 |
FIRE_CLUSTERING_PROJ_SRID | no | 3577 |
FIRE_INCIDENTS_ASSOCIATE_DIST_M | no | 20000 |
FIRE_INCIDENTS_ENABLED | no | false |
FIRE_INCIDENTS_INTERVAL_MIN | no | 15 |
FIRE_SUMMARIES_ENABLED | no | false |
FIRE_SUMMARIES_MODEL | no | claude-haiku-4-5-20251001 |
FIRMS_AU_BBOX | no | 112,-44,154,-10 |
FIRMS_BASE_URL | no | (computed) |
FIRMS_INGEST_ENABLED | no | (computed) |
FIRMS_INGEST_INTERVAL_MIN | no | 30 |
FIRMS_MIRROR_BASE_URL | no | (computed) |
FIRMS_SENSORS | no | (computed) |
GOOGLE_OAUTH_CLIENT_ID | no | null |
JWT_SECRET | yes | - |
JWT_TTL_DAYS | no | 30 |
LOG_FORMAT | no | (computed) |
LOG_LEVEL | no | (computed) |
MICROSOFT_OAUTH_CLIENT_ID | no | null |
MICROSOFT_OAUTH_TENANT_ID | no | common |
MIGRATIONS_DIR | no | raw process.env |
NASA_FIRMS_API_KEY | no | null |
NODE_ENV | no | development |
NOTIFICATION_TICK_MIN | no | raw process.env |
NOTIFICATIONS_ENABLED | no | raw process.env |
OPENMETEO_BASE_URL | no | https://api.open-meteo.com |
OPENMETEO_FORECAST_HOURS | no | 24 |
OPENMETEO_GRID_STEP_DEG | no | raw process.env |
OPENMETEO_INGEST_ENABLED | no | true |
OPENMETEO_INGEST_INTERVAL_MIN | no | 60 |
OVERPASS_URL | no | https://overpass-api.de/api/interpreter |
PLACES_AU_BBOX | no | 112,-44,154,-10 |
PLACES_INGEST_ENABLED | no | false |
PLACES_INGEST_INTERVAL_MIN | no | 1440 |
PORT | no | 3000 |
PREDICTION_ENGINE | no | advected |
PREDICTION_MAX_CLUSTERS_PER_CYCLE | no | 500 |
PREDICTION_PERSISTENCE_ENABLED | no | true |
PREDICTION_RAW_RETENTION_DAYS | no | 30 |
PREDICTION_VALIDATED | no | false |
PUBLIC_APP_URL | no | https://app.firepath.software |
REDIS_URL | no | raw process.env |
RESEND_API_KEY | no | null |
RESEND_FROM_EMAIL | no | noreply@firepath.software |
RESEND_FROM_NAME | no | Fire Path AI |
SEED_ADMIN_EMAIL | no | (computed) |
SEED_ADMIN_PASSWORD | no | raw process.env |
SPREAD_MODEL_VERSION | no | (computed) |
TERRAIN_REMOTE_WORKER | no | raw process.env |
THREAT_EMAIL_FALLBACK_ENABLED | no | false |
THREAT_FORECAST_UNAVAILABLE_ALERT_KM | no | (computed) |
THREAT_REGISTRY_CADENCE_MIN | no | 5 |
THREAT_REGISTRY_ETA_HORIZON_MIN | no | 360 |
THREAT_REGISTRY_HOTSPOT_AGE_HOURS | no | 24 |
THREAT_REGISTRY_RADIUS_M | no | 30000 |
THREAT_REGISTRY_RESOLVE_QUIET_CYCLES | no | 3 |
THREAT_SMS_FALLBACK_ENABLED | no | false |
THREAT_SMS_FROM | no | null |
TWILIO_ACCOUNT_SID | no | null |
TWILIO_AUTH_TOKEN | no | null |
TWILIO_VERIFY_SERVICE_SID | no | null |
VAPID_PRIVATE_KEY | no | raw process.env |
VAPID_PUBLIC_KEY | no | raw process.env |
VAPID_SUBJECT | no | raw process.env |
VITEST | no | raw process.env |
WIND_ENQUEUE_TIMEOUT_MS | no | raw process.env |
WIND_WORKER_CONCURRENCY | no | raw process.env |
WINDNINJA_DATA_DIR | no | null |
WINDNINJA_EXEC_MODE | no | raw process.env |
WINDNINJA_IMAGE | no | firepath/windninja:3.13 |
WINDNINJA_PLATFORM | no | linux/amd64 |
WINDNINJA_WORKER_ENABLED | no | raw process.env |
ZONE_ALERT_SUPPRESSION_ENABLED | no | false |