open-webui: SSO via authentik (OIDC authorization-code flow)
- quadlet: OAUTH_*/OPENID_* env + EnvironmentFile for the client secret (secret stays off-repo in /home/dank/Containers/open-webui/env, mode 600) - authentik objects created live: application 'open-webui', OAuth2 provider 'Open WebUI' (Strict redirect URI), 'Open WebUI roles' scope mapping, entitlements Open WebUI Users/Admins bound to openwebui_users/admins - e2e: 18-openwebui-sso.spec.ts (silent SSO round-trip) + prefix in config - unit tests: OIDC wiring + secret-hygiene assertions - docs: SSO section + history entry
This commit is contained in:
@@ -84,6 +84,40 @@ Chat web search is served by [[SearXNG]] on this host, wired in the quadlet
|
||||
table on first start (fill-missing only); afterwards the DB is authoritative
|
||||
and Admin-UI edits persist there.
|
||||
|
||||
## SSO (authentik)
|
||||
|
||||
Login is authentik via the OIDC authorization-code flow (wired 2026-09-24).
|
||||
The vhost stays exempt from the Anubis guard chain: the OAuth dance is
|
||||
browser-driven and only touches the two exempt vhosts (`ai.` and `auth.`).
|
||||
|
||||
- **authentik objects** (created via the admin API, 2026-09-24): application
|
||||
`open-webui` (slug `open-webui`) with the OAuth2 provider `Open WebUI`
|
||||
(confidential client, `authorization_code` + `refresh_token`, Strict
|
||||
redirect URI `https://ai.franksdank.cloud/oauth/oidc/callback`, implicit
|
||||
consent flow). The client ID is in the quadlet; the client secret lives in
|
||||
the git-ignored host file `/home/dank/Containers/open-webui/env` (mode 600,
|
||||
loaded via `EnvironmentFile=`).
|
||||
- **Roles:** the scope mapping `Open WebUI roles` (scope `roles`) reads the
|
||||
application entitlements `Open WebUI Users` → `user` and `Open WebUI
|
||||
Admins` → `admin`. The entitlements are bound to the groups
|
||||
`openwebui_users` / `openwebui_admins`. `akadmin` (frank8465@protonmail.com)
|
||||
is in `openwebui_admins`; `qa-e2e-admin` is in `openwebui_users`.
|
||||
- **Account merge:** `OAUTH_MERGE_ACCOUNTS_BY_EMAIL=true` folds an SSO login
|
||||
into the existing local account with the same email — the pre-SSO admin
|
||||
(frank8465@protonmail.com) keeps its data. `ENABLE_OAUTH_SIGNUP=true` lets
|
||||
other `openwebui_users` create accounts on first login.
|
||||
- **IdP reachability:** the container is on its own bridge (10.89.3.0/24) and
|
||||
cannot reach `authentik-server:9000` by name. It reaches the IdP over the
|
||||
public URL `https://auth.franksdank.cloud` — Caddy publishes `0.0.0.0:443`
|
||||
(netavark DNATs published ports from other containers) and Pi-hole resolves
|
||||
the name to the host LAN IP. The server-side code exchange rides that path.
|
||||
- **Config authority:** the OAuth env vars in the quadlet seed the per-key
|
||||
config DB on first run (fill-missing only); on the live data dir the Admin
|
||||
Panel is authoritative. To rotate the client secret: create a new token in
|
||||
authentik, update the host env file, and set the new value in the Admin
|
||||
Panel (or the DB), then restart the container.
|
||||
|
||||
|
||||
## Boot persistence (Quadlet)
|
||||
|
||||
The unit lives at `dankclaw/open-webui/quadlet/open-webui.container`. On the host it installs to `~/.config/containers/systemd/open-webui.container`. The generator turns it into `open-webui.service`. Because the unit sets `[Install] WantedBy=default.target` and user linger is on, it starts at boot. `systemctl --user is-enabled open-webui.service` reports `generated` (the quadlet boot-start state).
|
||||
@@ -124,6 +158,8 @@ The quadlet carries a built-in healthcheck (30s interval, 3 retries, 300s start
|
||||
|
||||
- **2026-09-21 — model picker rebuilt for the 3-model fleet.** The picker carried 39 stale rows (37 dead Ollama models + 2 `frank-default-*`) and was missing `frank-medium`. Rebuilt the `model` table to exactly `frank-large`/`frank-medium`/`frank-small` and set `model_ids` on each connection (llama.cpp's Ollama-shaped `/v1/models` is invisible to OpenWebUI's discovery). Pointed the two on-host endpoints at `host.containers.internal` — the bridge refuses the host LAN IP for non-published ports. All three verified end-to-end via `/openai/chat/completions`.
|
||||
|
||||
- **2026-09-24 — SSO via authentik.** OIDC authorization-code flow wired per the [SSO (authentik)](#sso-authentik) section: application/provider/entitlements created in authentik, client secret in the host env file, roles from the `roles` scope claim. E2E coverage in `tests/e2e/specs/18-openwebui-sso.spec.ts`.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Dankclaw Stack]]
|
||||
|
||||
Reference in New Issue
Block a user