Skip to main content
Almost nothing is configured through the environment. The rule is: if you need it to open the database, it is a variable. Everything else is a setting inside the app. That is deliberate. A Slack callback URL is per-domain and can never be ours, so it has to be editable by whoever runs the install, which means a screen. Two sources of truth for the same value is how a hosted build and a self-hosted build silently drift apart, so there is only one.

The bootstrap floor

The derived origins (PUBLIC_URL, APP_URL, BETTER_AUTH_URL, MCP_RESOURCE_URL) can each be set explicitly if the install is spread across more than one hostname. On a single domain, leave them alone.

Optional

Secrets you do not set

The session secret, the sealed-box keypair that connection credentials are encrypted under, and the bearer on the loopback call into the connection gateway are all generated on first boot and kept in the database.
They are in the database on purpose. On a platform with an ephemeral filesystem, a keypair in a file would be regenerated on every deploy, and a rotated sealing key makes every connection credential already stored permanently unopenable. Sessions dropping is the loud half of that. Unreadable connections is the silent, unrecoverable half.

Rotation

Changing a vendor credential in the environment after first boot does nothing. Environment seeded the credential table once, and nothing reads it again. Rotate in server settings.