Milestone 544, step 6217 (follow-up to #1778, which rewrote features.md and api-reference.md in July but left architecture.md and configuration.md alone). - architecture.md, configuration.md, development.md: rewritten against the code. They still described Ollama, chat, SSE generation, voice, project summaries, image caching, Docker secrets that the compose files don't use, a raw-SQL migration convention the migrations no longer follow, a 27-entry migration list, CalVer YY.MM.DD.N tags and the removed infra/ files. - features.md: adds what shipped since July (spikes, claims, moments, rule versions and verification, lessons, reply shapes, snippets and the shape ledger, forge integration, family canon, design systems, retrieval tuning) and corrects the Settings tabs and keyboard shortcuts (g g is the graph). - api-reference.md: adds the endpoints for snippets, lessons, design systems, family canon, platforms, shared areas, retrieval, rule versions, relations and verification, forge connections, webhooks, scheduled backups and the newer plugin hooks. - api-keys-and-mcp.md: Settings tab is "MCP Access"; a plugin install section; the tool-family table matches the tools that exist. - design-system.md: the dated "decisions in progress" changelog (April PR log, chat/journal/calendar surfaces) becomes a short present-tense section; the stored design system is named as the authority. - sso-oauth.md: the app is Scribe, not "Fabled Assistant". - README: feature summary and doc table brought current. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.5 KiB
OAuth / OIDC SSO Setup
Scribe supports single sign-on via any OpenID Connect provider. This guide covers Authentik, but the same pattern works with Keycloak, Authelia, Zitadel, etc.
1. Create the provider in Authentik
- Log in to the Authentik admin UI.
- Go to Applications → Providers → Create → OAuth2/OpenID Provider.
- Fill in:
- Name:
Scribe(or whatever you like) - Authorization flow: your default authorization flow
- Client type:
Confidential - Redirect URIs:
https://your-fabled-domain/api/auth/oauth/callback(must matchBASE_URLexactly, including scheme and any path prefix)
- Name:
- Note the generated Client ID and Client Secret.
- Go to Applications → Create, give it a name, and bind it to the provider you just created.
- Note the Issuer URL from the provider detail page — it looks like:
https://auth.example.com/application/o/fabled-assistant/
2. Configure Scribe
Add the following environment variables to the app service in docker-compose.yml:
services:
app:
environment:
# --- Required ---
OIDC_ISSUER: "https://auth.example.com/application/o/fabled-assistant/"
OIDC_CLIENT_ID: "abc123xyz"
OIDC_CLIENT_SECRET: "supersecret"
# --- Optional ---
# Scopes to request (default: "openid profile email")
# OIDC_SCOPES: "openid profile email"
# Disable local username/password login once SSO is working
# LOCAL_AUTH_ENABLED: "false"
# Make sure BASE_URL matches the redirect URI you registered
BASE_URL: "https://your-fabled-domain"
Docker Secrets alternative: Use
OIDC_CLIENT_SECRET_FILEpointing to a Docker secret file instead ofOIDC_CLIENT_SECRET.
Rebuild and restart:
docker compose up --build -d
3. Verify
- Open
/api/auth/status— it should return:{ "oauth_enabled": true, "local_auth_enabled": true, ... } - Go to the login page — you should see a "Login with [Provider]" button.
- Click it → redirected to provider → authenticate → redirected back → logged in.
- Check
/api/auth/meto confirm your user record.
4. Account Linking
When a user logs in via OAuth for the first time, Scribe checks in this order:
- Existing OAuth sub — returns that user immediately.
- Matching email — if a local account already exists with the same email, the OAuth identity is linked to it automatically. The user retains all their notes and tasks.
- New user — a fresh account is created. Username defaults to
preferred_usernamefrom the provider; if taken,_2,_3, etc. is appended.
5. Disable Local Login (Optional)
Once everyone is using SSO:
LOCAL_AUTH_ENABLED: "false"
The backend will reject any POST /api/auth/login or POST /api/auth/register request with a 403. The login page will only show the SSO button.
Warning: Make sure at least one account has been linked via OAuth before disabling local login, or you will be locked out.
6. Other Providers
| Provider | Issuer URL format |
|---|---|
| Authentik | https://auth.example.com/application/o/<app-slug>/ |
| Keycloak | https://keycloak.example.com/realms/<realm> |
| Authelia | https://auth.example.com |
| Zitadel | https://your-instance.zitadel.cloud |
https://accounts.google.com |
The OIDC discovery endpoint (<issuer>/.well-known/openid-configuration) must be publicly reachable from the Scribe container (server-to-server call at login time).