Configuration Index
A single-page inventory of runtime configuration. The index is the fast lookup; canonical doctrine lives in the linked ADR or runbook for each row.
Each table has the same shape:
- Env var — the variable name as it appears in code or the deploy workflow
- Source — where the value is set: the GitHub Environment, a per-deploy container var, image-baked at build, build-time bundled (frontends), or computed at runtime
- Rotation — when the value changes, and the trigger
- Owning — the canonical ADR or runbook for the value
Runtime config is resolved by tools/provision/provision.sh from infra/environments.toml + 1Password into the GitHub Environment (ADR-110); the deploy applies it to the container (secrets + non-secret --vars). The production Environment carries every “Environment” row below; a staging Environment lands when a Supabase stage project exists. For the placement principle (shared vs per-deploy) see CD pipeline overview. For the provisioning + rotation flow see Secrets management and ADR-037.
The app container — both entrypoints (api.runspectral.com)
Section titled “The app container — both entrypoints (api.runspectral.com)”One Cloudflare container runs the FastAPI API and the LangGraph workers runtime as sibling entrypoints (per Deployment topology). They share one config set.
Substrate (from the GitHub Environment)
Section titled “Substrate (from the GitHub Environment)”| Env var | Source | Rotation | Owning |
|---|---|---|---|
SUPABASE_URL | Environment | Per-environment; set at provisioning | ADR-039 |
SUPABASE_PUBLISHABLE_KEY | Environment | At Supabase key rotation | Auth runbook |
SUPABASE_SECRET_KEY | Environment (secret) | At Supabase key rotation | Auth runbook |
SUPABASE_DB_URL / DATABASE_URL | Environment (secret) | At DB credential rotation | Connection pooling |
OTEL_EXPORTER_OTLP_ENDPOINT | Environment | Provider migration only | ADR-036 |
SENTRY_DSN | Environment | Provider migration only | ADR-036 |
LOGFIRE_TOKEN | Environment | Provider migration only | ADR-036 |
The DB connections (runtime + the deploy’s migration step) go over the Supabase session pooler, which supports LISTEN/NOTIFY for the outbox consumer (ADR-109 D4).
Per-deploy container vars (atomic with the image)
Section titled “Per-deploy container vars (atomic with the image)”| Env var | Source | Rotation | Owning |
|---|---|---|---|
SPECTRAL_GENERATION | Container var (set at deploy) | Bumped per deploy | ADR-109 D5 |
SPECTRAL_ENVIRONMENT | Container var (required to boot) | Per environment (local / staging / production) | LLM platform |
SPECTRAL_ENABLE_OAUTH_LLM_CONFIG | Container var (optional; default off) | Feature toggle | LLM platform |
SPECTRAL_MODULE_STORE_ROOT | Container var | Substrate change | Decision execution |
SPECTRAL_WORKER_POLL_INTERVAL_S | Container var | Tuning only | Deployment topology |
SPECTRAL_CORS_ALLOWED_ORIGINS | Container var | Edge / hostname change | Security boundaries |
LLM provider credentials
Section titled “LLM provider credentials”LLM model + credential selection lives in the DB control plane, not a container-level provider key: the operator sets the active provider/model and its credential (Supabase Vault) through the operations cockpit, and the platform resolves it per request with precedence customer-domain > customer-org > global (the global and customer-org tiers are live; the per-domain scope is reserved). A customer org brings its own provider/model + credential (API key or a refreshable OAuth bundle) through the customer dashboard. /health reports the resolved LLM config as wired or degraded-until-configured. OAuth (subscription) credentials are governed by SPECTRAL_ENABLE_OAUTH_LLM_CONFIG: permitted in local dev unconditionally, and in other environments only when the flag is set — otherwise both config surfaces reject an OAuth credential and resolution refuses to build one, so the global and customer tiers stay API-key-only by default (the OAuth path is experimental and may be blocked at datacenter origins). Provider keys used by shared infrastructure (e.g. embeddings) and by local-development credential plumbing live in the GitHub Environment / local env. See LLM platform.
Frontends — Cloudflare Pages SPAs (app.runspectral.com, ops.runspectral.com)
Section titled “Frontends — Cloudflare Pages SPAs (app.runspectral.com, ops.runspectral.com)”The customer dashboard and the staff operations console are TanStack/Vite SPAs on Cloudflare Pages (ADR-050). Frontend env vars are build-time bundled (Vite reads VITE_* at build and embeds them into the client bundle); rotation requires a rebuild, not a config flip. Pages Function env vars are request-time bindings on the Pages deployment.
| Env var | Source | Rotation | Owning |
|---|---|---|---|
VITE_API_BASE_URL / VITE_API_URL | Build-time → bundle | Normally unset in production so calls stay same-origin through Pages Functions; topology change only | Frontend architecture |
VITE_SUPABASE_URL | Build-time → bundle | At Supabase key rotation | ADR-039 |
VITE_SUPABASE_PUBLISHABLE_KEY | Build-time → bundle | At Supabase key rotation | ADR-039 |
SUPABASE_URL (operations Function) | Pages env | At Supabase project change | Access control |
SUPABASE_AUD (operations Function) | Pages env | Auth audience change only | Access control |
API_ORIGIN (dashboard/operations Functions) | Pages env | API hostname change only | Frontend architecture |
Rule: anything sensitive lands behind the API and is reached through the API proxy. A frontend bundle holds only public-facing keys; the Supabase secret key is never shipped to a frontend.
docs-codex (Cloudflare Pages, codex.runspectral.com)
Section titled “docs-codex (Cloudflare Pages, codex.runspectral.com)”The Codex docs site is a static Astro build with a Pages Function for JWKS-local auth on operator-only routes (ADR-052).
| Env var | Source | Rotation | Owning |
|---|---|---|---|
OPERATIONS_SCOPES | Cloudflare Pages env (Function reads at request time) | Scope-taxonomy change only | Access control |
SUPABASE_URL | Cloudflare Pages env | At Supabase key rotation | ADR-039 |
docs-user (Cloudflare Pages, docs.runspectral.com)
Section titled “docs-user (Cloudflare Pages, docs.runspectral.com)”Public marketing/docs site. No runtime config; all content is statically rendered at build.
CI secrets (GitHub Actions, not runtime)
Section titled “CI secrets (GitHub Actions, not runtime)”GitHub Environments hold these. The production Environment is gated by its protection rule + the production-ff-only ruleset (ADR-110). See CI secrets handling runbook and ADR-062 for the rotation procedure.
| Env var | Environment | Used by | Rotation |
|---|---|---|---|
CLOUDFLARE_API_TOKEN | production | Deploy + edge-reconcile workflows | Quarterly |
DATABASE_URL / SUPABASE_DB_URL | production | Migrations + the container runtime secret hop | At DB credential rotation |
SUPABASE_SECRET_KEY | production | The container runtime secret hop | At Supabase key rotation |
Tunables that are code constants, not env vars
Section titled “Tunables that are code constants, not env vars”The following appear in design docs but are set in source code (not configurable per-deploy). Listed here so a reader who searches for them lands somewhere useful:
| Constant | Defined in | Notes |
|---|---|---|
min_size, max_size, max_idle, prepare_threshold, reconnect_timeout | psycopg_pool config in spectral_api.db and spectral_workers.db | See Connection pooling for the defaults |
Session-var names (app.org_id, app.domain_id, app.user_id) | spectral.core.db.session_vars | Pinned by RLS contract tests; renamed per ADR-086 D1 + D2 + D6 |
See also
Section titled “See also”- Hosting — the substrate each entrypoint reads
- Secrets management — provisioning + rotation flow
- CD pipeline overview — config placement principle
- ADR-110 — provisioning architecture
- ADR-037 — secret-value sourcing
- Secrets management runbook — the operational rotation procedure