- Enable OIDC in Kavita appsettings.json (Authority, ClientId, Enabled) - Add OIDC env vars to BookStack compose + APP_URL + kitestacks network - Add OIDC env vars to OpenProject compose + kitestacks network declaration - Add kitestacks network + error reporting setting to Authentik compose - Create .env secret placeholders for BookStack and OpenProject - Add comprehensive SSO setup guide: docs/authentik-sso-setup.md - Version bump: v1.3.883 → v1.3.884 Services getting native OIDC: Grafana, OpenWebUI, Forgejo, BookStack, OpenProject, Kavita Services getting proxy auth: Shaarli, Uptime Kuma, LiteLLM Excluded: Portainer, Prometheus, Node Exporter, OpenRouter Manual steps pending: Authentik admin UI app creation, Forgejo OAuth source, Cloudflare tunnel updates. See docs/authentik-sso-setup.md for the full checklist. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 KiB
KiteStacks Authentik SSO Setup
Established: 2026-06-08
Author: kenpat
Status: In Progress — config files deployed, manual Authentik UI steps pending
Architecture
All services sit behind Cloudflare Tunnels on the kitestacks Docker network.
cloudflared routes external traffic directly to each service container by hostname.
Authentik (authentik:9000) is the single identity provider.
Internet → Cloudflare → cloudflared → [service container]
↕
Authentik auth check
Two integration patterns are used:
| Pattern | How it works | Services |
|---|---|---|
| Native OIDC/OAuth2 | App calls Authentik directly for login | Grafana, OpenWebUI, Forgejo, BookStack, OpenProject, Kavita |
| Authentik Proxy Provider | Cloudflare tunnel → Authentik (embedded outpost) → service | Shaarli, Uptime Kuma, LiteLLM |
SSO Status
| Service | Subdomain | Port | Method | Status |
|---|---|---|---|---|
| Authentik | auth.kitestacks.com | 9000 | (is the IdP) | ✅ Running |
| Grafana | grafana.kitestacks.com | 3000 | OAuth2 | ⚠️ env set, Authentik app needed |
| Kite AI (OpenWebUI) | ai.kitestacks.com | 8080 | OIDC | ⚠️ env set, Authentik app needed |
| Forgejo | gitforge.kitestacks.com | 3000 | OAuth2 | ⚠️ Forgejo admin UI config needed |
| BookStack | books.kitestacks.com* | 80 | OIDC | ⚠️ env set, Authentik app needed, CF tunnel needed |
| OpenProject | tasks.kitestacks.com | 80 | OIDC | ⚠️ env set, Authentik app needed |
| Kavita | kavita.kitestacks.com | 5000 | OIDC | ⚠️ appsettings.json updated, Authentik app needed |
| Shaarli | links.kitestacks.com | 80 | Proxy | ⚠️ Authentik Proxy Provider needed + CF tunnel update |
| Uptime Kuma | status.kitestacks.com | 3001 | Proxy | ⚠️ Authentik Proxy Provider needed + CF tunnel update |
| LiteLLM | llm.kitestacks.com | 4000 | Proxy | ⚠️ Authentik Proxy Provider needed + CF tunnel update |
| Portainer | portainer.kitestacks.com | 9000 | — | 🚫 SSO excluded |
| Prometheus | prometheus.kitestacks.com | 9090 | — | 🚫 SSO excluded |
| Node Exporter | node-exporter.kitestacks.com | 9100 | — | 🚫 SSO excluded |
| OpenRouter | openrouter.ai | — | — | 🚫 external, excluded |
*BookStack subdomain placeholder — update APP_URL in apps/bookstack/docker-compose.yml.
Files Changed (2026-06-08)
| File | What changed |
|---|---|
apps/authentik/docker-compose.yml |
Added kitestacks network declaration, AUTHENTIK_ERROR_REPORTING__ENABLED: false |
apps/kavita/config/appsettings.json |
OpenIdConnectSettings.Enabled → true, Authority set |
apps/bookstack/docker-compose.yml |
OIDC env vars added, kitestacks network added, APP_URL updated |
apps/bookstack/.env |
Created with BOOKSTACK_OIDC_SECRET placeholder |
apps/openproject/docker-compose.yml |
OIDC env vars added, kitestacks network declared |
apps/openproject/.env |
Created with OPENPROJECT_OIDC_SECRET placeholder |
Step 1 — Authentik Admin UI: Create Providers and Applications
Go to https://auth.kitestacks.com → Admin Interface.
For each native OIDC service, create one OAuth2/OpenID Provider:
General settings (all providers):
- Signing Key: select the default RS256 key
- Token validity: 10 minutes (access), 30 days (refresh)
1. Grafana
- Providers → Create → OAuth2/OpenID Provider
- Name:
Grafana - Client type:
Confidential - Client ID:
grafana - Redirect URIs:
https://grafana.kitestacks.com/login/generic_oauth - Scopes:
openid,email,profile
- Name:
- Applications → Create
- Name:
Grafana, Slug:grafana - Provider:
Grafana(above)
- Name:
- Copy the Client Secret → put it in
/home/kenpat/docker/grafana/.env:GRAFANA_OAUTH_CLIENT_SECRET=<paste_secret> - Restart:
cd ~/docker/grafana && docker compose up -d
2. Kite AI (Open WebUI)
- Providers → Create → OAuth2/OpenID Provider
- Name:
Open WebUI, Client ID:open-webui - Redirect URIs:
https://ai.kitestacks.com/oauth/oidc/callback - Scopes:
openid,email,profile
- Name:
- Applications → Create: Name:
Kite AI, Slug:open-webui - Copy secret →
/home/kenpat/docker/kite-ai/.env:OPENWEBUI_OAUTH_CLIENT_SECRET=<paste_secret> - Restart:
cd ~/docker/kite-ai && docker compose up -d
3. Kavita
- Providers → Create → OAuth2/OpenID Provider
- Name:
Kavita, Client ID:kavita - Redirect URIs:
https://kavita.kitestacks.com/api/Account/OIDCCallback - Scopes:
openid,email,profile
- Name:
- Applications → Create: Name:
Kavita, Slug:kavita - Copy secret →
/home/kenpat/docker/kavita/config/appsettings.json:"Secret": "<paste_secret>" - Restart:
cd ~/docker/kavita && docker compose restart(if a compose exists) ordocker restart kavita
4. BookStack
- Providers → Create → OAuth2/OpenID Provider
- Name:
BookStack, Client ID:bookstack - Redirect URIs:
https://books.kitestacks.com/oidc/callback(adjust to your actual BookStack subdomain) - Scopes:
openid,email,profile
- Name:
- Applications → Create: Name:
BookStack, Slug:bookstack - Copy secret →
/home/kenpat/docker/bookstack/.env:BOOKSTACK_OIDC_SECRET=<paste_secret> - Set the real subdomain in
/home/kenpat/docker/bookstack/docker-compose.yml:- Update
APP_URL=https://<your-actual-bookstack-subdomain>.kitestacks.com
- Update
- Restart:
cd ~/docker/bookstack && docker compose up -d - In Cloudflare dashboard: add tunnel route
<bookstack-subdomain>.kitestacks.com→http://bookstack:80
5. OpenProject
- Providers → Create → OAuth2/OpenID Provider
- Name:
OpenProject, Client ID:openproject - Redirect URIs:
https://tasks.kitestacks.com/auth/oidc/callback - Scopes:
openid,email,profile
- Name:
- Applications → Create: Name:
OpenProject, Slug:openproject - Copy secret →
/home/kenpat/docker/openproject/.env:OPENPROJECT_OIDC_SECRET=<paste_secret> - Restart:
cd ~/docker/openproject && docker compose up -d- Note: Container is currently running
openproject/community:13but compose specifiesopenproject/openproject:15. Recreation will upgrade it. Verify data migration after restart. The Cloudflare tunnel fortasks.kitestacks.commay need updating fromopenproject:8080→openproject:80after the upgrade.
- Note: Container is currently running
For proxy services, create Proxy Providers:
These services have no native OIDC. Authentik will act as the reverse proxy.
After creating each Proxy Provider + Application, add all three to the Embedded Outpost:
Outposts → authentik Embedded Outpost → Edit → move all three proxy applications to "Selected Applications".
6. Shaarli
- Providers → Create → Proxy Provider
- Name:
Shaarli - Mode:
Reverse Proxy - External host:
https://links.kitestacks.com - Internal host:
http://shaarli:80 - Internal host SSL validation: off
- Name:
- Applications → Create: Name:
Shaarli, Slug:shaarli - Cloudflare Tunnel: Change
links.kitestacks.comroute fromhttp://shaarli:80→http://authentik:9000
7. Uptime Kuma
- Providers → Create → Proxy Provider
- Name:
Uptime Kuma - Mode:
Reverse Proxy - External host:
https://status.kitestacks.com - Internal host:
http://uptime-kuma:3001
- Name:
- Applications → Create: Name:
Uptime Kuma, Slug:uptime-kuma - Cloudflare Tunnel: Change
status.kitestacks.comroute fromhttp://uptime-kuma:3001→http://authentik:9000
8. LiteLLM (when ready to expose publicly)
- Providers → Create → Proxy Provider
- Name:
LiteLLM - Mode:
Reverse Proxy - External host:
https://llm.kitestacks.com - Internal host:
http://kite-litellm:4000
- Name:
- Applications → Create: Name:
LiteLLM, Slug:litellm - Cloudflare Tunnel: Add route
llm.kitestacks.com→http://authentik:9000
Step 2 — Forgejo: Add Authentik OAuth2 Source
Forgejo stores OAuth sources in its database (not in app.ini), so this requires the Forgejo admin UI.
- Go to https://gitforge.kitestacks.com → Site Administration → Authentication Sources
- Click Add Authentication Source
- Settings:
- Authentication Type:
OAuth2 - Authentication Name:
authentik - OAuth2 Provider:
OpenID Connect - Client ID:
forgejo - Client Secret: (create an Authentik app first — see below)
- OpenID Connect Auto Discovery URL:
https://auth.kitestacks.com/application/o/forgejo/.well-known/openid-configuration - Additional scopes:
email profile
- Authentication Type:
- Save
Create the Authentik app for Forgejo first:
- Provider: OAuth2/OpenID, Client ID:
forgejo - Redirect URI:
https://gitforge.kitestacks.com/user/oauth2/authentik/callback - Application slug:
forgejo
Step 3 — Cloudflare Tunnel Updates
In the Cloudflare Zero Trust Dashboard → Networks → Tunnels → your tunnel → Configure → Public Hostnames:
| Hostname | Change From | Change To |
|---|---|---|
links.kitestacks.com |
http://shaarli:80 |
http://authentik:9000 |
status.kitestacks.com |
http://uptime-kuma:3001 |
http://authentik:9000 |
llm.kitestacks.com |
(new) | http://authentik:9000 |
tasks.kitestacks.com |
http://openproject:8080 |
http://openproject:80 (after OpenProject upgrade) |
<bookstack-subdomain>.kitestacks.com |
(new) | http://bookstack:80 |
Step 4 — Restart Containers After Config Changes
After filling in all secrets in the .env files:
cd ~/docker/grafana && docker compose up -d
cd ~/docker/kite-ai && docker compose up -d
cd ~/docker/bookstack && docker compose up -d
cd ~/docker/openproject && docker compose up -d
cd ~/docker/authentik && docker compose up -d
docker restart kavita
Troubleshooting
OIDC redirect loop / 400 error
- Check that the Redirect URI in the Authentik provider exactly matches what the app sends.
- Grafana:
https://grafana.kitestacks.com/login/generic_oauth(no trailing slash)
Kavita "OIDC is not configured" message
- The
appsettings.jsonchange requires a container restart:docker restart kavita - Verify
Enabled: trueandSecretis not empty.
BookStack redirects to http://192.168.1.205:6875
APP_URLmust be updated to the real HTTPS domain and the container recreated.
OpenProject: OIDC provider not visible in login
- Env var format is version-specific. If env vars don't work in v15, configure via: Administration → Authentication → OpenID Connect Providers → Add
Proxy services (Shaarli/Uptime Kuma) show Authentik login but then 502
- Verify the Embedded Outpost has the proxy providers assigned.
- Verify internal host is reachable:
docker exec authentik curl -v http://shaarli:80
Service-to-Container Name Reference
| Subdomain | Container Name | Internal Port |
|---|---|---|
| auth.kitestacks.com | authentik | 9000 |
| grafana.kitestacks.com | grafana | 3000 |
| ai.kitestacks.com | kite-openwebui | 8080 |
| gitforge.kitestacks.com | forgejo | 3000 |
| tasks.kitestacks.com | openproject | 80 (after upgrade) |
| kavita.kitestacks.com | kavita | 5000 |
| links.kitestacks.com | shaarli | 80 |
| status.kitestacks.com | uptime-kuma | 3001 |
| llm.kitestacks.com | kite-litellm | 4000 |
| www.kitestacks.com | homepage | 3000 |
| portainer.kitestacks.com | portainer | 9000 (excluded) |
| prometheus.kitestacks.com | prometheus | 9090 (excluded) |
| node-exporter.kitestacks.com | node-exporter | 9100 (excluded) |