Self-hosting: SSO, SCIM, and updates

Single sign-on (OIDC)#

  1. In god mode, open Integrations → Auth provider and copy the redirect URI it shows (<API_URL>/api/auth/oauth2/callback/oidc).
  2. Create a confidential client at your provider with that redirect URI.
  3. Paste the discovery URL (.../.well-known/openid-configuration), the client ID, and the client secret back into the page. Name the sign-in button and turn the provider on.

Credentials are stored in the database, not in .env, so enabling a provider needs no restart.

The registration mode under Authentication decides whether a first sign-in may create an account:

Mode Behavior
open creates the account
invite only needs a pending project invite
closed refuses it — provision people with SCIM instead

A sign-in whose address already has an account joins that account instead of creating a second one, but only if the provider reports the address as verified and the existing account has confirmed its own. Authentication → Trust addresses from sign-in providers drops both conditions — turn it on only where you control who can register at the provider, since anyone who registers an address there would take over the account that holds it here.

Once a provider works, you can turn off Authentication → Email and password. Sign-in/sign-up forms and password reset are then hidden and refused, and the provider becomes the only way in — the switch stays disabled until a provider is configured, so an instance can't be left with no way in. Passkeys keep working since they can only be added to an account that already exists.

SCIM provisioning#

An identity provider can create, update, and deactivate accounts over SCIM 2.0, and grant project access through its groups.

  1. In god mode, open Integrations → SCIM, generate a token (shown once), and turn provisioning on.
  2. Point your provider's SCIM application at <API_URL>/scim/v2, authenticating with Authorization: Bearer <token>.
  3. Push users, and groups if you use them.

Deactivating someone at the provider (active: false) ends their sessions and refuses their API keys; reactivating restores them with their projects intact. The instance owner's account is outside SCIM's reach.

A pushed group grants nothing until you map it: open the group under Integrations → SCIM, add the projects its members should join, and the role they join on. Removing a project from that list removes the memberships the group granted. A membership from an invite is never touched by sync; one the sync created can't be edited from the project's members page — it changes at the identity provider.

Updating#

git pull
docker compose pull
docker compose up -d

The api applies migrations automatically on startup. Before applying anything it dumps the database into the db-backups volume (/backups in the api container) and refuses to start if the dump fails. Dumps are deleted after 30 days by default (BACKUP_RETENTION_DAYS changes the window); SKIP_PRE_MIGRATION_BACKUP=1 skips the dump for operators who back up another way.

Attachments live in RustFS. An instance set up with MinIO switches over automatically on the next docker compose up -d — nothing is copied, and files stay readable. Back up the volume first if you want a copy:

docker run --rm -v itsaplan_minio-data:/data -v "$PWD":/out alpine tar czf /out/minio-data.tgz -C /data .

The project is under active development — check the changelog for API path changes before upgrading an instance that scripts or an MCP client depend on.

Updated

Was this page helpful?