kitestacks-homelab/homelab-mastery/build-guide/with-ai/06-sso.md
kenpat 1e8319ee75 docs: comprehensive homelab-mastery rewrite with full build guides
Complete documentation suite for KiteStacks covering all 11 services across
2-host active-active architecture. Includes beginner track (with AI, 8 files)
and advanced track (without AI, 7 files) with time estimates, real troubleshooting
cases, and command-by-command explanations. Updates certifications roadmap to
reflect July 7 2026 A+ Core 2 exam goal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 01:08:43 -05:00

7.7 KiB
Raw Blame History

Step 6 — Single Sign-On (SSO)

Track: With AI (Beginner)
Time for this step: 35 hours

SSO (Single Sign-On) means one login for everything. After this step, you will log in with your Authentik account once and every service will recognize you automatically. No more logging in to each service separately.


How SSO Works (Plain English)

Without SSO:

You → Grafana login page → type username + password → logged in to Grafana
You → Forgejo login page → type username + password → logged in to Forgejo
(repeat for every service)

With SSO:

You → Grafana "Sign in with Authentik" button
    → Authentik asks for login (once, or already remembered)
    → Authentik tells Grafana "this is kenpat, let them in"
    → Logged in to Grafana

You → Forgejo "Sign in with Authentik"
    → Already logged into Authentik → instantly logged in to Forgejo

The technology behind this is called OAuth2 and OIDC. For now, you do not need to know the details — just follow the steps. (The concepts file explains it deeply if you are curious: concepts/oauth2-oidc.md)


The Process for Each Service

For every service, you do the same three things:

In Authentik:

  1. Create an OAuth2 Provider for the service
  2. Create an Application that links to that Provider
  3. (Optional) Add a Policy to restrict who can access it

In the service: 4. Enter the Authentik credentials (client ID, client secret, URLs)

Your AI will guide you through each one. Use this prompt template:

"I want to configure SSO for [service name] using Authentik as the OIDC provider. The service is at https://[service].yourdomain.com. Walk me through:

  1. Creating an OAuth2 provider in Authentik's admin panel
  2. What redirect URI to use
  3. How to configure the service to use Authentik for login"

SSO for Grafana

In Authentik admin panel (auth.yourdomain.com/if/admin/):

  1. Go to Applications → Providers → Create

  2. Choose OAuth2/OpenID Provider

  3. Name: Grafana

  4. Client type: Confidential

  5. Redirect URIs: https://grafana.yourdomain.com/login/generic_oauth

  6. Scopes: openid, email, profile

  7. Save — note the Client ID and Client Secret

  8. Go to Applications → Applications → Create

  9. Name: Grafana, Slug: grafana

  10. Provider: select the Grafana provider you just created

  11. Save

In Grafana's .env or docker-compose.yml environment:

GF_AUTH_GENERIC_OAUTH_ENABLED=true
GF_AUTH_GENERIC_OAUTH_NAME=Authentik
GF_AUTH_GENERIC_OAUTH_CLIENT_ID=paste-client-id-here
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=paste-client-secret-here
GF_AUTH_GENERIC_OAUTH_SCOPES=openid email profile
GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://auth.yourdomain.com/application/o/authorize/
GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://auth.yourdomain.com/application/o/token/
GF_AUTH_GENERIC_OAUTH_API_URL=https://auth.yourdomain.com/application/o/userinfo/
GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(groups, 'homelab-admin') && 'Admin' || 'Viewer'

Restart Grafana: docker compose restart grafana

Visit grafana.yourdomain.com — you should see a "Sign in with Authentik" button.


SSO for Forgejo

In Authentik: Create an OAuth2 Provider with:

  • Redirect URI: https://gitforge.yourdomain.com/user/oauth2/authentik/callback

In Forgejo:

  • Site Administration → Authentication Sources → Add Authentication Source
  • Type: OAuth2
  • Name: authentik
  • OAuth2 Provider: OpenID Connect
  • Client ID and Secret from Authentik
  • OpenID Connect Discovery URL: https://auth.yourdomain.com/application/o/forgejo/.well-known/openid-configuration

Ask your AI: "Walk me through adding an OAuth2 authentication source in Forgejo's admin panel."


SSO for Karakeep

Important: Karakeep uses NextAuth.js internally. The redirect URI is NOT the usual /callback/authentik — it is /api/auth/callback/custom.

In Authentik: Create OAuth2 Provider with:

  • Redirect URI: https://links.yourdomain.com/api/auth/callback/custom

In Karakeep's environment:

NEXTAUTH_URL=https://links.yourdomain.com
NEXTAUTH_SECRET=generate-a-random-secret
OAUTH_WELLKNOWN_URL=https://auth.yourdomain.com/application/o/karakeep/.well-known/openid-configuration
OAUTH_CLIENT_ID=paste-client-id
OAUTH_CLIENT_SECRET=paste-client-secret
OAUTH_PROVIDER_NAME=Authentik
OAUTH_ALLOW_DANGEROUS_EMAIL_ACCOUNT_LINKING=true

SSO for Kavita

In Authentik: Create OAuth2 Provider with:

  • Redirect URI: https://kavita.yourdomain.com/api/auth/callback

In Kavita: Go to Settings → OIDC (must be done through the UI, not by editing files):

  • Authority: https://auth.yourdomain.com/application/o/kavita/ ← trailing slash required
  • Client ID and Client Secret from Authentik
  • Enabled: on

Critical: The trailing slash in the Authority URL is required. Without it, Kavita gives an "issuer does not match" error.


SSO for Open WebUI

In Authentik: Create OAuth2 Provider with:

  • Redirect URI: https://ai.yourdomain.com/oauth/oidc/callback

In Open WebUI's environment:

ENABLE_OAUTH_SIGNUP=true
OAUTH_PROVIDER_NAME=Authentik
OPENID_PROVIDER_URL=https://auth.yourdomain.com/application/o/openwebui/.well-known/openid-configuration
OAUTH_CLIENT_ID=paste-client-id
OAUTH_CLIENT_SECRET=paste-client-secret

SSO for BookStack

In Authentik: Create OAuth2 Provider with:

  • Redirect URI: https://wiki.yourdomain.com/oidc/callback
  • Issuer mode: Per Provider (important — set this in Authentik's provider settings)

In BookStack's .env:

AUTH_METHOD=oidc
AUTH_AUTO_INITIATE=false
OIDC_NAME=Authentik
OIDC_DISPLAY_NAME_CLAIMS=name
OIDC_CLIENT_ID=paste-client-id
OIDC_CLIENT_SECRET=paste-client-secret
OIDC_ISSUER=https://auth.yourdomain.com/application/o/bookstack/
OIDC_ISSUER_DISCOVER=true

After setting this up, the BookStack cache directory needs to be writable:

docker exec bookstack chown -R abc:users /config/www/framework/cache/
docker compose restart bookstack

SSO for Portainer

In Authentik: Create OAuth2 Provider with:

  • Redirect URI: https://portainer.yourdomain.com

In Portainer: Settings → Authentication → OAuth:

  • Provider: Custom
  • Client ID and Secret from Authentik
  • Authorization URL: https://auth.yourdomain.com/application/o/authorize/
  • Token URL: https://auth.yourdomain.com/application/o/token/
  • Userinfo URL: https://auth.yourdomain.com/application/o/userinfo/
  • Redirect URL: https://portainer.yourdomain.com
  • Scopes: openid email profile

Security note: In Authentik, add a Policy Binding to the Portainer application to restrict access to your admin group only. This prevents anyone with an Authentik account from accessing the Docker management panel.


Restricting Access by Group (Security)

For sensitive services like Portainer, you want only administrators to access them:

  1. In Authentik, go to Directory → Groups → Create

  2. Name: homelab-admin

  3. Add yourself to this group

  4. Go to Applications → Applications → [Portainer] → Policy Bindings

  5. Add a binding: Group → homelab-admin → Allow

Now only members of homelab-admin can use the Portainer application through SSO.


Checkpoint

Test SSO for each service:

  • Grafana — "Sign in with Authentik" works
  • Forgejo — OAuth2 login works
  • Karakeep — SSO login works
  • Kavita — "Sign in with Authentik" works
  • Open WebUI — SSO login works
  • BookStack — OIDC login works
  • Portainer — OAuth login works

If any fail, check the error message and ask your AI: "I'm getting this error when signing in to [service] with Authentik: [paste the error]. What does it mean and how do I fix it?"


Next: Step 7 — Cloud Failover (kscloud1)