Skip to content

Configuration

Environment variables, secrets, encryption, OAuth2, database, and production hygiene.

Intended audience: Stakeholders, Business analysts, Solution architects, Developers, Testers

Learning outcomes by role

Stakeholders

  • Recognize mandatory secrets and environment classes for production readiness.

Business analysts

  • Checklist configuration items for go-live sign-off.

Solution architects

  • Produce environment-specific matrices (dev, staging, prod) from this guide.

Developers

  • Set CADENCE_* variables and validate against AppSettings behavior.

Testers

  • Build config-focused smoke tests and misconfiguration detection.

Configure Cadence from environment variables prefixed CADENCE_ (secrets, Postgres URLs, Redis, RabbitMQ, CORS, OAuth, logging). The authoritative list is in the repository root .env.example. Immutable infrastructure settings load at process startup from those variables; operational defaults and feature flags that change at runtime live in the global_settings database table (not in env vars).

  • Secrets and complianceCADENCE_SECRET_KEY, CADENCE_ENCRYPTION_KEY, and database URLs are deployment commitments; weak defaults are rejected or warned in production validation.
  • Separation — Env vars bootstrap the process; product operators tune many limits via admin APIs and global_settings, not by redeploying for every change.
  • Go-live checklist — Map each CADENCE_ variable in .env.example to an owner and verification step (smoke test, secret rotation procedure).
  • Non-functional requirements — CORS, OAuth redirect URLs, and log format tie directly to customer-facing browser apps and SIEM ingestion.
Environment variables to AppSettings Process environment variables with prefix CADENCE are loaded into AppSettings once at startup. Environment CADENCE_* vars .env optional AppSettings cadence.core.config Immutable infra: DB, Redis, secrets, CORS… FastAPI main

Runtime feature flags and tier defaults live in global_settings (DB), not AppSettings — see module docstring in cadence/core/config.py.

  • Infrastructure reachable: PostgreSQL, Redis, and optionally RabbitMQ
  • Secrets generated for production (openssl rand -hex 32 for the encryption key)

| Variable | Default | Purpose | | ------------------------------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | CADENCE_SECRET_KEY | (placeholder) | JWT signing secret — must be changed in production | | CADENCE_ENCRYPTION_KEY | (zeros) | 64 hex chars (32 bytes AES-256) for encrypting API keys and LLM credentials — generate with openssl rand -hex 32must be changed in production | | CADENCE_JWT_ALGORITHM | HS256 | JWT signing algorithm | | CADENCE_THIRD_PARTY_JWT_SECRET_KEY | — | Optional public key for accepting third-party JWTs (e.g. an upstream IdP) | | CADENCE_THIRD_PARTY_JWT_ALGORITHM | RS256 | Algorithm for third-party JWT verification | | CADENCE_ACCESS_TOKEN_TTL_SECONDS | 10800 | Access token and Redis session lifetime (seconds) | | CADENCE_REFRESH_TOKEN_TTL_SECONDS | 604800 | Refresh token lifetime (seconds) |

| Variable | Default | Purpose | | --------------------------- | ------------------------ | ------------------------------------------------------------------------------- | | CADENCE_POSTGRES_URL | local default | Primary PostgreSQL connection URL (write path) | | CADENCE_POSTGRES_READ_URL | — | Optional read replica URL; omit to send all reads to primary | | CADENCE_PGBOUNCER_ENABLED | false | Use NullPool in SQLAlchemy when PgBouncer handles external connection pooling | | CADENCE_DB_POOL_SIZE | 20 | SQLAlchemy pool size | | CADENCE_DB_MAX_OVERFLOW | 10 | Extra connections allowed above pool size | | CADENCE_DB_POOL_RECYCLE | 3600 | Recycle connections after this many seconds | | CADENCE_DB_POOL_TIMEOUT | 30 | Seconds to wait for a connection from the pool | | CADENCE_DB_POOL_PRE_PING | true | Test connections before use | | CADENCE_REDIS_URL | redis://localhost:6379 | Session store, OAuth2 state, rate limits | | CADENCE_REDIS_DEFAULT_DB | 0 | Redis database index | | CADENCE_RABBITMQ_URL | local default | AMQP event bus for settings broadcast and pool lifecycle events |

| Variable | Default | Purpose | | ------------------------------ | ----------------- | ------------------------------------------------------------------------------ | | CADENCE_S3_ENABLED | True | Enable S3/MinIO as the plugin artifact store. If credentials are missing at startup, the lifespan warns and falls back to filesystem-only. | | CADENCE_S3_ENDPOINT_URL | None | S3-compatible endpoint URL; omit for AWS S3, set for MinIO | | CADENCE_S3_ACCESS_KEY_ID | "" | S3 access key ID | | CADENCE_S3_SECRET_ACCESS_KEY | "" | S3 secret access key | | CADENCE_S3_BUCKET_NAME | cadence-plugins | Bucket for plugin ZIP storage | | CADENCE_S3_REGION | us-east-1 | S3 region |

| Variable | Default | Purpose | | ----------------------------- | ---------------------------------- | ----------------------------------------------- | | CADENCE_SYSTEM_PLUGINS_DIR | /var/lib/cadence/plugins/system | Filesystem path for system-wide plugins | | CADENCE_TENANT_PLUGINS_ROOT | /var/lib/cadence/plugins/tenants | Root directory for tenant plugin subdirectories |

| Variable | Default | Purpose | | ---------------------- | --------------------------------------------- | --------------------------------------- | | CADENCE_CORS_ORIGINS | http://localhost:3000,http://localhost:8080 | Comma-separated allowed browser origins |

| Variable | Default | Purpose | | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------- | -------------------------------------------- | | CADENCE_OAUTH_REDIRECT_BASE_URL | http://localhost:3000 | Nuxt app base URL for OAuth callbacks | | CADENCE_CONSENT_UI_URL | — (defaults to {oauth_redirect_base_url}/oauth/consent) | Full URL to the consent UI page | | CADENCE_GOOGLE_CLIENT_ID / _SECRET | — | Google social OAuth credentials | | CADENCE_GITHUB_CLIENT_ID / _SECRET | — | GitHub social OAuth credentials | | CADENCE_OAUTH2_CLIENT_ID / _SECRET / _AUTHORIZATION_URL / _TOKEN_URL / _USERINFO_URL | — | Generic OAuth2 provider for social login | | CADENCE_OAUTH2_SCOPES | openid email profile | Scopes requested during generic OAuth2 flows |

| Variable | Default | Purpose | | --------------------- | ------------ | --------------------------------------------------------------- | | CADENCE_ENVIRONMENT | production | Deployment environment name — controls production safety checks | | CADENCE_DEBUG | false | Enable debug mode — must be false in production | | CADENCE_API_HOST | 0.0.0.0 | API server bind address | | CADENCE_API_PORT | 8888 | API server port |

Structured logging format is not selected via AppSettings; default process logging is configured in cadence.main. Use Observability for OpenTelemetry and log shipping patterns.

  1. Copy .env.example to .env.
  2. Bring up infrastructure (Docker Compose or your platform): PostgreSQL, Redis, RabbitMQ.
  3. Run migrations and bootstrap the admin user.
  4. Set CADENCE_CORS_ORIGINS to your UI origin.
  5. Start the API and UI; verify health endpoints (Monitoring).

| Symptom | Cause | Fix | | --------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------- | | 500 on startup | Database URL, credentials, or network | Check CADENCE_POSTGRES_URL and connectivity | | Sessions flaky or dropped | Redis unavailable | Check CADENCE_REDIS_URL and Redis health | | Plain text logs only | Default logging config in cadence.main | Add a log pipeline or OTel log export per Observability | | encryption_key validation error | Not exactly 64 hex characters | Regenerate with openssl rand -hex 32 |