Console settings, environment variables and the secret key
Which settings the admin console stores, how environment variables override them, how changes reach every service, and how stored secrets are protected.
Environment variables win
Each group of settings comes from its environment variables when they are set, and from the admin
console otherwise. A group never mixes the two: setting OIDC_ISSUER replaces the whole
OIDC setup stored in the console. The console shows such a group as Set by
environment, read-only; remove the variables to manage it in the console.
| Setting | Variables that override it |
|---|---|
| Company sign-in (OIDC) | OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_DISPLAY_NAME, OIDC_ICON |
| The GitHub App (tokens, statuses) | GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY, or OPEND_GITHUB_BROKER_URL (managed hosting) |
| GitHub sign-in | GITHUB_OAUTH_CLIENT_ID and GITHUB_OAUTH_CLIENT_SECRET |
| Webhook secret | GITHUB_WEBHOOK_SECRET |
| Editor address | EDITOR_PUBLIC_URL |
| View source on GitHub | OPEND_SOURCE_LINKS |
| Demo readers | Only ever on where OPEND_DEV_LOGIN allows them; the console can turn them off |
Site access, the docs repository, organizations and readers live in their own tables, as before, and the admin API changes the same records.
Changes apply without a restart
Every change sends a Postgres notification. The web service (every replica), the worker and the editor reload their settings when it arrives, and re-read them at least once a minute in case a notification is missed. Sign-in providers are rebuilt only when their own settings change.
The secret key
Client secrets, the GitHub App's private key and its webhook secret are sealed with AES-256-GCM before they reach the database, bound to their names so one cannot be swapped for another. No page, API route, log line or audit entry ever contains one; the console only says whether each is set.
The key comes from OPEND_SECRET_KEY when it is set. Otherwise it is derived from
SESSION_SECRET with HKDF under a label of its own, so it is never the session key
itself. Either way, every service that reads the settings needs the same value: give the worker and
the editor the web service's SESSION_SECRET (or OPEND_SECRET_KEY).