Configuration
Configuration is a single typed Settings object (Pydantic v2 BaseSettings) loaded from the
environment in backend/app/core/config.py. Invalid or missing required values fail fast at
startup with a clear error — not at 2 a.m. on the first request that needs them.
Backend environment variables
Section titled “Backend environment variables”| Variable | Required | Default | What it does |
|---|---|---|---|
DATABASE_URL | yes | — | Async PostgreSQL connection string (postgresql+asyncpg://...). |
CLERK_SECRET_KEY | yes | — | Clerk server-side API key. |
CLERK_JWKS_URL | yes | — | Clerk JWKS endpoint; the public keys used to verify RS256 tokens. |
CLERK_ISSUER | yes | — | Expected iss claim; tokens from any other issuer are rejected. |
CLERK_AUTHORIZED_PARTIES | yes | — | Allowed azp values, so a token minted for another app cannot be replayed against yours. |
STRIPE_SECRET_KEY | for billing | "" | Stripe server key (test or live). |
STRIPE_WEBHOOK_SECRET | for billing | "" | Signing secret used to verify incoming webhook signatures. |
STRIPE_PRICE_ID | for billing | "" | The price the checkout session is created against. |
CORS_ORIGINS | no | ["http://localhost:3000"] | The explicit list of allowed browser origins you set — the default is your real origins, not a permissive *. |
ALLOWED_REDIRECT_HOSTS | no | ["localhost","127.0.0.1"] | Open-redirect guard for checkout success/cancel URLs. |
APP_ENV | no | development | development / production; gates production-only behavior. |
DEBUG | no | false | Verbose errors locally; keep false in production. |
Why typed settings matter
Section titled “Why typed settings matter”Three things you get for free by configuring this way:
- Fail-fast validation. A missing
DATABASE_URLor a malformedCORS_ORIGINSlist stops the app at boot with a precise message, instead of surfacing as a confusing 500 later. - One source of truth. Every module reads
settings.x; there are no scatteredos.getenvcalls to hunt down, and no undocumented variable that only one engineer knows about. - Security defaults that are safe, not convenient. CORS is an explicit allow-list, redirects
are host-checked, and Clerk’s
iss/azpclaims are validated — all driven from this one file.
The frontend reads the standard Clerk publishable key and the API base URL from its own
.env.local; the download ships a documented template for both. The full configuration reference,
including production hardening notes, ships as docs/CONFIGURATION.md.