Files
homelab-optimized/docs/infrastructure/authentik-sso.md
Gitea Mirror Bot c1a6970aa7
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m1s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-05 05:50:13 UTC
2026-04-05 05:50:13 +00:00

17 KiB

Authentik SSO Setup

Single Sign-On (SSO) for homelab services using Authentik.

Overview

Authentik provides centralized authentication for all homelab services via OAuth2/OpenID Connect.

Admin Credentials

  • Username: akadmin
  • Email: admin@example.com
  • Password: REDACTED_PASSWORD in password manager

Architecture

                    ┌──────────────────┐
                    │   Cloudflare     │
                    │   (DNS + SSL)    │
                    └────────┬─────────┘
                             │
                    ┌────────▼─────────┐
                    │  sso.vish.gg     │
                    │  (Authentik)     │
                    │  Calypso NAS     │
                    └────────┬─────────┘
                             │
        ┌────────────────────┼────────────────────┐
        │                    │                    │
        ▼                    ▼                    ▼
   ┌─────────┐         ┌─────────┐         ┌──────────┐
   │ Grafana │         │  Gitea  │         │Portainer │
   │gf.vish.gg│        │git.vish.gg│       │ internal │
   │homelab-vm│        │ Calypso │         │  Calypso │
   └─────────┘         └─────────┘         └──────────┘

OAuth2 Providers

Grafana

Setting Value
Client ID lEGw1UJ9Mhk6QVrNA61rAsr59Kel9gAvdPQ1FAJA
Client Secret ArP5XWdkwVyw9nvXZaqjE9sIjXdmIgpgI4ZR8oKvTUVLgmIGVvKU8T867diMGSQXgTcWQQPbdbEdXTU1v3y9RKMnAqu2k6V4xlmxwNYlCDuk5inxJSdoC0V8ICtZxk1X
Redirect URI https://gf.vish.gg
Scopes openid profile email

Configuration File: hosts/vms/homelab-vm/monitoring.yaml

Gitea

Setting Value
Client ID 7KamS51a0H7V8HyIsfMKNJ8COstZEFh4Z8Em6ZhO
Client Secret 3IjyKCbHtgev6eMb1hYpQGHoGwPSRKda4ijRtbWfkhguNomxexxTiWtoWtyrXwGaF0ORj4D7D0kzB3Z1YN9DN5iz0HOKjAn5AdWJrSyxan02MjiwKmEriAbSGyh53uph
Redirect URI https://git.vish.gg/user/oauth2/authentik/callback
Discovery URL https://sso.vish.gg/application/o/gitea/.well-known/openid-configuration

Configuration File: hosts/synology/calypso/gitea-server.yaml

Manual Setup Required: Add OAuth2 source in Gitea admin UI:

  1. Go to Site Administration → Authentication Sources
  2. Add new OAuth2 source
  3. Use Discovery URL for auto-configuration

Portainer

Setting Value
Client ID fLLnVh8iUyJYdw5HKdt1Q7LHKJLLB8tLZwxmVhNs
Client Secret xD9u47XbJd2g7vCeIyJC7MNvfEqytEnnHeVtJ7nU5Y1XGxYncXkejNAYkToUiRWcym3GpZIXgMpUnNNuUwud0Ff493ZwSHCiSKsk9n6RJLJ1iVvR20NdDnMe4YEGYXrt
Redirect URI http://vishinator.synology.me:10000
User Identifier email

Configuration: Via Portainer API (/api/settings)

Reactive Resume v5

Setting Value
Client ID QU5qA7jLP9ghxy7iGMJoyZsCja2vY2Y2oGaLGjxA
Client Secret wX1aFaby4aIABjLBBClYu4ukmIOjviL85GJBX8bAB3srQnt1BD31LcblRKyxzuv1yGwtsKLTFjwz12rUy6HknOqpIwk1QQ21jMjpWb1aa77iRG6lDkf4eNf8wWpE9Apo
Redirect URI https://rx.vish.gg/api/auth/callback/custom
Discovery URL https://sso.vish.gg/application/o/reactive-resume/.well-known/openid-configuration

Configuration File: hosts/synology/calypso/reactive_resume_v5/docker-compose.yml (also live at /volume1/docker/rxv5/docker-compose.yml on Calypso)

Homarr

Setting Value
Client ID 8oP0ha7gLjdz13MAPVsb7fe7TBkFBz7mt1eU8MEO
Client Secret SpJXIGDk3SJfiS9GJwzH0fKrePsrumvCOmvFd2h0hEfxXMO77aCtpPEs6FShLTaUW5YxqgEDFkQi7q9NIOQDJTPQHlSy3nIeyDQmS2tVIV1BpSdGpnLQedouOkXACwe2
Redirect URI https://dash.vish.gg/api/auth/callback/oidc
Admin Group Homarr Admins (Authentik group, pk=892da833-5283-4672-a906-7448ae3ba9b6)
Discovery URL https://sso.vish.gg/application/o/homarr/.well-known/openid-configuration

Configuration File: hosts/synology/atlantis/homarr.yaml

Note: SECRET_ENCRYPTION_KEY is required by Homarr — a 64-char hex key must be provided as an env var. The AUTH_OIDC_ADMIN_GROUP and AUTH_OIDC_OWNER_GROUP map to an Authentik group name.

Immich

Setting Value
Client ID XSHhp1Hys1ZyRpbpGUv4iqu1y1kJXX7WIIFETqcL
Client Secret mlbc4NbqiyRyUSqeUupaob7WsA3sURWExmoxYAcozClnmsdCPzGHlyO6zmErnS9YNyBsKOYoGUPvSTQPrE07UnYDLSMy286fycHoAJoc0cAN8BMc5cIif5kf88NSNCj2
Redirect URIs http://192.168.0.250:8212/auth/login, http://calypso.vish.local:8212/auth/login, app.immich:/
Issuer URL https://sso.vish.gg/application/o/immich/
Button Text Sign in with Authentik
Auto Register true

Configuration: Via immich-config.json mounted at /config/immich-config.json inside the container. Config file lives at /volume1/docker/immich/config/immich-config.json on Calypso and is tracked at /home/homelab/immich-config.json.

Note: Immich constructs the redirect URI dynamically from the hostname the browser used to access it — so every access hostname must be registered in Authentik. Currently registered: IP, calypso.vish.local, app.immich:/. mobileRedirectUri in the config file must be empty string — Immich's validator rejects custom URI schemes there.

Headplane

Setting Value
Provider PK 16
Client ID 1xLx9TkufvLGKgq8UmQV2RfTB6raSpEjZExBOhJ4
Client Secret 4r4n96jBGc8MlonyHStiN09ow0txTwERLupt9hsoNswpicEnJZHgKwi38jYP5zlou5J525dVFUmXNSvnxwBJgKIIAfpC43zi8yUVtT0NYNdEBeYQOsh1YW5jK8nVPSdc
Redirect URI https://headscale.vish.gg:8443/admin/oidc/callback
Issuer URL https://sso.vish.gg/application/o/headplane/
Scopes openid profile email
Sub Mode hashed_user_id

Configuration File: hosts/synology/calypso/headplane-config.yaml (reference, secrets redacted). Live config at /volume1/docker/headscale/headplane/config.yaml on Calypso.

Note: Headplane is served at https://headscale.vish.gg:8443/admin — no separate domain. NPM proxy host 44 routes /admin to port 3002. First user to log in via OIDC is automatically assigned the Owner role.

NetBox

Setting Value
Provider PK 23
Client ID BB7PiOu8xFOl58H2MUfl9IHISVLuJ4UwwMGvmJ9N
Client Secret CRdRVCM13JN9bSiT2aU74cFXSI9GpVBLBShOFGBpVHOQ4brnDWOzk8I02cEww8Gcrr6GnsU0XdBxHTEpfvX2u9rhmey7XDT3XUVVh9ADaSldww83hp4hAzH5eNx1zKvB
Redirect URI https://nb.vish.gg/oauth/complete/oidc/
Discovery URL https://sso.vish.gg/application/o/netbox/.well-known/openid-configuration
Scopes openid profile email

Configuration: NetBox configuration.py on homelab-vm (/home/homelab/docker/netbox/config/configuration.py). Uses python-social-auth with social_core.backends.open_id_connect.OpenIdConnectAuth backend. associate_by_email pipeline maps Authentik users to existing NetBox accounts by email.

Authentik Endpoints

Endpoint URL
Authorization https://sso.vish.gg/application/o/authorize/
Token https://sso.vish.gg/application/o/token/
User Info https://sso.vish.gg/application/o/userinfo/
JWKS https://sso.vish.gg/application/o/{app-slug}/jwks/
OpenID Config https://sso.vish.gg/application/o/{app-slug}/.well-known/openid-configuration
End Session https://sso.vish.gg/application/o/{app-slug}/end-session/

Docker Compose Configuration

Location: hosts/synology/calypso/authentik.yaml

Key environment variables:

  • AUTHENTIK_SECRET_KEY: Random secret for encryption
  • AUTHENTIK_REDIS__HOST: Redis container hostname
  • AUTHENTIK_POSTGRESQL__*: PostgreSQL connection settings

SSL/TLS Configuration

SSL is handled by Cloudflare Origin Certificate:

  • Certificate ID: lONWNn (Synology reverse proxy)
  • Covers: *.vish.gg
  • Origin: Cloudflare Full (Strict) mode

DNS Configuration

Domain Type Target Proxy
sso.vish.gg CNAME calypso DDNS Orange (proxied)

Adding New Services

Method 1: OAuth2/OpenID (for apps that support it)

  1. Create Provider in Authentik

    • Admin → Providers → Create → OAuth2/OpenID
    • Set name, redirect URIs, scopes
  2. Create Application

    • Admin → Applications → Create
    • Link to provider
    • Set launch URL
  3. Configure Service

    • Add OAuth2/OIDC settings to service config
    • Use Authentik endpoints
    • Test login flow

Method 2: Proxy Provider (for apps without OAuth support)

Use this for apps like Actual Budget, Paperless-NGX, etc.

  1. Create Proxy Provider in Authentik

    • Admin → Providers → Create → Proxy Provider
    • Name: e.g., "actual-proxy"
    • Authorization flow: default-provider-authorization-implicit-consent
    • External host: https://actual.vish.gg
    • Mode: Forward auth (single application)
  2. Create Application

    • Admin → Applications → Create
    • Name: e.g., "Actual Budget"
    • Slug: actual
    • Provider: Select the proxy provider
    • Launch URL: https://actual.vish.gg
  3. Create Outpost (if not exists)

    • Admin → Applications → Outposts
    • Create embedded outpost or deploy standalone
    • Add the application to the outpost
  4. Configure Nginx/Reverse Proxy

    Add forward auth to your reverse proxy config:

    location / {
        # Forward auth to Authentik
        auth_request /outpost.goauthentik.io/auth/nginx;
        error_page 401 = @goauthentik_proxy_signin;
    
        auth_request_set $auth_cookie $upstream_http_set_cookie;
        add_header Set-Cookie $auth_cookie;
    
        auth_request_set $authentik_username $upstream_http_x_authentik_username;
        auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
        auth_request_set $authentik_email $upstream_http_x_authentik_email;
    
        proxy_set_header X-authentik-username $authentik_username;
        proxy_set_header X-authentik-groups $authentik_groups;
        proxy_set_header X-authentik-email $authentik_email;
    
        # Your existing proxy_pass
        proxy_pass http://localhost:PORT;
    }
    
    location /outpost.goauthentik.io {
        proxy_pass https://sso.vish.gg/outpost.goauthentik.io;
        proxy_set_header Host $host;
        proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
    }
    
    location @goauthentik_proxy_signin {
        internal;
        add_header Set-Cookie $auth_cookie;
        return 302 /outpost.goauthentik.io/start?rd=$request_uri;
    }
    

For services like Seafile that have share links:

# Allow share links without auth
location /f/ {
    proxy_pass http://localhost:8611;
}

location /d/ {
    proxy_pass http://localhost:8611;
}

# Everything else requires auth
location / {
    auth_request /outpost.goauthentik.io/auth/nginx;
    # ... rest of auth config
    proxy_pass http://localhost:8611;
}

Services Protection Summary

OAuth2/OpenID Connect (Login Button)

Services with native OAuth support - users see a "Sign in with Authentik" button.

Domain Service Backend Port Status
gf.vish.gg Grafana 192.168.0.210 3300 Working
git.vish.gg Gitea 192.168.0.250 3052 Working
sf.vish.gg Seafile 192.168.0.250 8611 Working
vishinator.synology.me:10000 Portainer 192.168.0.250 9000 Working
rx.vish.gg Reactive Resume v5 192.168.0.250 4550 Working
dash.vish.gg Homarr 192.168.0.200 7575 Working
immich.vish.gg Immich 192.168.0.250 8212 Working
headscale.vish.gg/admin Headplane 192.168.0.250 3002 Working
nb.vish.gg NetBox 192.168.0.210 8443 Working

Proxy Provider (Forward Auth)

Services without OAuth support - Authentik intercepts all requests and requires login first.

Domain Service Backend Port Status
paperless.vish.gg Paperless-NGX 192.168.0.250 8777 Working
docs.vish.gg Paperless-NGX 192.168.0.250 8777 Working
actual.vish.gg Actual Budget 192.168.0.250 8304 Working
npm.vish.gg NPM Admin 192.168.0.250 81 Working
kuma.vish.gg Uptime Kuma 192.168.0.66 3001 Working — /status/* public, rest gated
ollama.vish.gg Ollama 192.168.0.200 11434 Working
wizarr.vish.gg Wizarr 192.168.0.200 5690 Removed — caused redirect loop; Wizarr uses own auth

Services Without SSO

These services use their own authentication or are public.

Domain Service Backend Notes
sso.vish.gg Authentik 192.168.0.250:9000 SSO itself
pw.vish.gg Vaultwarden 192.168.0.200:4080 Own auth
ntfy.vish.gg Ntfy 192.168.0.210:8081 Own auth
cal.vish.gg Baikal 192.168.0.200:12852 CalDAV auth
dav.vish.gg Seafile WebDAV 192.168.0.250:8612 WebDAV auth
mm.crista.love Mattermost 192.168.0.154:8065 Own auth
mastodon.vish.gg Mastodon 192.168.0.154:3000 Own auth
mx.vish.gg Mail 192.168.0.154:8082 Own auth
ollama.vish.gg Ollama 192.168.0.200:11434 See Forward Auth table above
retro.vish.gg Retro Site 192.168.0.250:8025 Static site
rackula.vish.gg Rackula 192.168.0.250:3891 Own auth
ost.vish.gg OpenSpeedTest 192.168.0.250:8004 Public

Other Domains

Domain Service Backend Notes
hoarder.thevish.io Hoarder 192.168.0.210:3000 Own auth
matrix.thevish.io Matrix 192.168.0.154:8081 Own auth
joplin.thevish.io Joplin Server 192.168.0.200:22300 Own auth
meet.thevish.io Jitsi 192.168.0.200:5443 Public
binterest.thevish.io Binternet 192.168.0.210:21544 Own auth
crista.love Personal Site 192.168.0.100:28888 Static
rxv4access.vish.gg Reactive Resume v4 192.168.0.250:9751 STALE - 525 SSL error, dead instance

Troubleshooting

OAuth Login Fails with "Unauthorized"

  • Verify user has email set in Authentik
  • Check redirect URI matches exactly
  • Verify client secret is correct

Certificate Errors

  • Ensure Cloudflare proxy is enabled (orange cloud)
  • Verify origin certificate is valid
  • Check Synology reverse proxy SSL settings

User Auto-Creation Not Working

  • Enable "Auto Create Users" in service OAuth settings
  • Verify email scope is requested
  • Check user identifier matches (email/username)

Recovery Access

If locked out of Authentik admin, you can create a recovery token:

# Via Portainer exec or SSH to Calypso
docker exec -it Authentik-SERVER ak create_recovery_key 10 akadmin

This generates a one-time recovery URL valid for 10 minutes.

Change Log

  • 2026-03-17: Added NetBox OIDC provider (pk=23) — nb.vish.gg, associate_by_email pipeline
  • 2026-03-17: Removed Wizarr forward auth from NPM (wizarr has own auth, forward auth caused redirect loop)
  • 2026-03-11: Added Headplane OIDC provider (pk=16) — Headscale web UI at headscale.vish.gg/admin, port 3002
  • 2026-03-08: Added Forward Auth for Uptime Kuma (kuma.vish.gg), Ollama (ollama.vish.gg), Wizarr (wizarr.vish.gg)
  • 2026-03-08: Kuma /status/* and Wizarr /i/* paths are public; all other paths gated
  • 2026-03-08: Removed Forward Auth from dash.vish.gg NPM proxy (Homarr handles auth natively via OIDC)
  • 2026-03-08: Disabled Uptime Kuma built-in auth (disableAuth=true in SQLite); Authentik is sole gate
  • 2026-03-08: Calibre-Web started on port 8183 (8083 was occupied by Watchtower)
  • 2026-03-08: Added OIDC for Reactive Resume v5 (rx.vish.gg), Homarr (dash.vish.gg), Immich (immich.vish.gg) — all working
  • 2026-03-08: Fixed Homarr startup crash — SECRET_ENCRYPTION_KEY is mandatory (64-char hex)
  • 2026-03-08: Immich OAuth configured via immich-config.json mount (not Admin UI); mobileRedirectUri must be empty
  • 2026-03-08: Immich stack.env added to repo so stack is self-contained (no Portainer env injection needed)
  • 2026-03-08: Flagged rxv4access.vish.gg as stale (dead RR v4 instance, 525 SSL error)
  • 2026-01-31: Verified all OAuth2 and Forward Auth services working
  • 2026-01-31: Fixed Grafana OAuth "InternalError" - added scope mappings to provider
  • 2026-01-31: Removed Forward Auth from NPM for gf.vish.gg (conflicts with native OAuth)
  • 2026-01-31: Added scope mappings to Gitea, Portainer, Seafile OAuth2 providers
  • 2026-01-31: Updated comprehensive service protection summary