Skip to content

Operate a self-hosted Chorus

This guide covers operating a self-hosted Chorus after it is deployed: getting the first person signed in, configuring authentication, upgrading safely, and the cookie and reverse-proxy settings that matter behind HTTPS. For how to stand a deployment up, see Deploy in production or Deploy with Docker.

A fresh deployment has no accounts yet. Set DEFAULT_USER and DEFAULT_PASSWORD to enable a built-in email/password login that bypasses single sign-on:

Terminal window
DEFAULT_USER='admin@example.com' \
DEFAULT_PASSWORD='choose-a-strong-password'

When both variables are set, the sign-in page shows an email/password form. On the first successful sign-in, Chorus automatically creates the user and their workspace from the email, so no manual setup is needed to get in.

The built-in login is a bootstrap mechanism, not a permanent account system. Once real accounts exist — or once single sign-on is configured — turn it off by unsetting both DEFAULT_USER and DEFAULT_PASSWORD and restarting Chorus. With the pair removed, the built-in email/password form no longer appears and access goes through your configured identity provider instead.

Two kinds of authentication are configured at the deployment level.

The /admin Super Admin panel is bootstrapped from environment variables, not from a database account:

VariableDescription
SUPER_ADMIN_EMAILEmail for the Super Admin account that can reach the /admin panel.
SUPER_ADMIN_PASSWORD_HASHBcrypt hash of the Super Admin password (never the plaintext).

Generate the hash and pass it as SUPER_ADMIN_PASSWORD_HASH:

Terminal window
node -e "console.log(require('bcryptjs').hashSync('your-password', 10))"

Single sign-on is not configured through environment variables. The Super Admin configures OIDC per workspace from the /admin panel, and the settings are stored in the database. Each workspace has its own issuer URL and client ID; SSO is on for a workspace once both are set. Chorus uses PKCE and does not require a client secret. The deployment-level bootstrap gets the Super Admin in, and the Super Admin then sets up SSO for each workspace from the admin panel, with no separate secret provisioning at the deployment layer.

Chorus applies pending database migrations automatically at startup (prisma migrate deploy). You do not run migrations by hand — starting a new version applies whatever is outstanding before the web application begins serving.

To upgrade:

  1. Back up your database first. For an external PostgreSQL, take a backup; for an embedded or volume-backed database, back up the data volume.
  2. Pull the new version — npm update -g @chorus-aidlc/chorus for the npm package, or pull the new container image for a Docker deployment.
  3. Restart Chorus. Migrations apply automatically on boot, then the app starts.

0.19.1 includes a migration that only adds a nullable column, so existing data is untouched. Upgrade the Chorus server before upgrading the chorus CLI that runs your agent daemons. Older daemons keep working against the new server, receiving Idea creation and Research requests in the form they already understand. For an emergency rollback of the new request format, set CHORUS_DEDICATED_OPERATION_WRITES=false and restart the server: new requests use the older format, and ones already queued are still delivered. Roll back the CLI separately if you need to. Do not roll the server back to a version older than 0.19.1 while requests created by 0.19.1 are still pending or running, and do not remove the new column.

Back up the signing secret together with your database and keep it stable. To retain an auto-generated secret, Docker needs a persistent /app/data volume even with external PostgreSQL; the npm launcher uses ~/.chorus-data/.secret by default. If you previously used a public placeholder, the replacement secret requires users of the built-in email/password login and the Super Admin to sign in again. A secure secret you set explicitly is kept as is. For CDK redeployments, supply the same nextAuthSecret: omitting it generates a new value at each synth. API keys and OIDC tokens are unaffected by this rotation. See Docker migration guidance.

Two settings matter when Chorus runs behind TLS termination or a reverse proxy:

VariableSet toWhen
COOKIE_SECUREtrueThe site is served over HTTPS (including behind a proxy that terminates TLS). Secure cookies are only sent over encrypted connections.
COOKIE_SECUREfalseOnly for trusted, internal HTTP-only networks. Cookies are then sent over unencrypted HTTP, so never use this on the public internet.
NEXTAUTH_URLThe public base URLChorus runs behind a reverse proxy. Set it to the externally visible address (for example https://chorus.example.com) so redirects and links resolve correctly.