Self-hosting
Configuration reference
Every environment variable a self-hosted Brunel reads, grouped by purpose, with what is required and how to generate secrets.
Generate secrets with openssl rand -base64 32 unless stated otherwise. Never commit real values.
Storage
| Variable | Purpose |
|---|---|
DATABASE_URL | PostgreSQL connection string. Without it (and without Blob), the in-memory store is used and nothing persists |
BLOB_READ_WRITE_TOKEN | Vercel Blob store, as an alternative to PostgreSQL |
BRUNEL_DEMO_MODE | 1: in-memory store and demo banner |
Sign-in and secrets
| Variable | Purpose |
|---|---|
AUTH_URL | Public address, e.g. https://brunel.example.com |
AUTH_SECRET | Encrypts the session cookie |
AUTH_GITHUB_ID, AUTH_GITHUB_SECRET | GitHub OAuth app for sign-in |
AUTH_ENCRYPTION_KEY | 32 bytes, base64: seals GitHub tokens and other secrets (AES-256-GCM) |
AUTH_ENCRYPTION_KEY_PREVIOUS | The previous key during a rotation; stored secrets are re-sealed by the daily job |
BRUNEL_ALLOWED_LOGINS | Private mode: only these GitHub logins can use the instance (comma-separated) |
BRUNEL_OWNER_LOGINS | Operators with the unlimited owner plan (comma-separated) |
AI reasoning
All optional: without them the deterministic architect answers.
| Variable | Purpose |
|---|---|
REASONING_BASE_URL, REASONING_API_KEY, REASONING_MODEL | An OpenAI-compatible reasoning endpoint |
REASONING_MAX_TOKENS | Output token cap per call |
REASONING_MONTHLY_TOKEN_BUDGET | Monthly token cap for the whole instance; beyond it, the deterministic architect answers |
ANTHROPIC_API_KEY, ANTHROPIC_MODEL | Alternative provider configuration |
BRUNEL_LLM_OFF | 1: kill switch, never call an AI provider |
BRUNEL_LLM_MOCK | fixtures: replay recorded answers (tests, offline demos) |
GitHub
| Variable | Purpose |
|---|---|
GITHUB_TOKEN | Optional server token for a higher public GitHub API rate limit |
BRUNEL_GITHUB_APP_ID, BRUNEL_GITHUB_APP_SLUG, BRUNEL_GITHUB_APP_PRIVATE_KEY, BRUNEL_GITHUB_APP_WEBHOOK_SECRET | The optional GitHub App (all four together) |
Billing
| Variable | Purpose |
|---|---|
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET | Stripe checkout and webhooks |
STRIPE_PRICE_PRO, STRIPE_PRICE_BUSINESS | Stripe price ids of the paid plans |
Certificates
| Variable | Purpose |
|---|---|
BRUNEL_CERT_SIGNING_KEY | Ed25519 private key (PKCS#8 PEM or base64 DER): openssl genpkey -algorithm ed25519 |
BRUNEL_CERT_SIGNING_KEY_PREVIOUS | The previous key during a rotation, published for verification only |
Operations and security
| Variable | Purpose |
|---|---|
CRON_SECRET | Bearer secret of the daily and monthly jobs |
UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN | Shared rate limits across instances |
BRUNEL_GUEST_ANALYSES_PER_HOUR | Guest analyses per address per hour (default 5) |
BRUNEL_OUTBOUND_ALLOWLIST | Restrict user-configured destinations (webhooks, SSO issuer, own AI endpoint) to these hosts; .example.com covers subdomains |
BRUNEL_SECURITY_ALERT_WEBHOOK | Slack-compatible webhook for critical security events |
Hosts
| Variable | Purpose |
|---|---|
BRUNEL_SUBDOMAINS | 1: console on console., enterprise. and portal. |
BRUNEL_API_SUBDOMAIN | 1: REST API and MCP on api. |
BRUNEL_CDN | 1 at build time: static files from cdn. |
BRUNEL_DOCS_SUBDOMAIN | 1: this documentation on docs. |