Files
homelab-infra/docs/AUTHELIA_OIDC_PLAN.md
T

9.0 KiB

Authelia OIDC fuer Apps - Plan & Runbook

Stand: 2026-06-06. Authelia-Version: v4.39.20.

Ziel: App-uebergreifendes Single-Sign-On ueber Authelia als OpenID-Connect-Provider (https://auth.kaleschke.info). Statt pro App eigener Logins meldet man sich einmal bei Authelia an (inkl. 2FA) und wird per OIDC an die App durchgereicht.

Status: aktives Runbook. Grafana und Mealie sind seit 2026-06-06 live und per Login-Smoke verifiziert. Der weitere Rollout bleibt additiv: lokale App-Logins bleiben als Fallback aktiv.


Grundregeln (wichtig)

  • Secrets gehoeren nie ins Repo. OIDC-Client-Secrets (Klartext und pbkdf2-Hash) liegen ausschliesslich in der Host-Config /mnt/user/appdata/authelia/config/configuration.yml (Hash) und im jeweiligen App-Stack (Klartext, via Komodo Stack-ENV / Secret-Datei), plus optional Vaultwarden. Dieses Dokument enthaelt nur Schema und Variablennamen.
  • OIDC-Clients leben host-seitig, wie der bestehende beszel-Client. Die Repo-Baseline security/authelia/configuration.yml haelt nur die nicht-geheime Struktur (access_control etc.); services/authelia-diff.sh vergleicht standardmaessig nur access_control, OIDC-Clients auf dem Host loesen also keinen Drift-Alarm aus.
  • Issuer/Endpoints (Authelia OIDC):
    • Issuer: https://auth.kaleschke.info
    • Authorization: https://auth.kaleschke.info/api/oidc/authorization
    • Token: https://auth.kaleschke.info/api/oidc/token
    • Userinfo: https://auth.kaleschke.info/api/oidc/userinfo
    • JWKS: https://auth.kaleschke.info/jwks.json
    • Discovery: https://auth.kaleschke.info/.well-known/openid-configuration
  • PKCE an, wo moeglich (require_pkce: true, S256), wie beim Beszel-Client.

Client-Schema (Authelia v4.39, gespiegelt vom bestehenden beszel-Client)

Pro App ein Block unter identity_providers.oidc.clients in der Host-Config:

identity_providers:
  oidc:
    clients:
      - client_id: '<app>'
        client_name: '<App-Name>'
        client_secret: '<pbkdf2-sha512-Hash - NUR auf dem Host>'
        public: false
        authorization_policy: 'two_factor'   # admin-Apps: two_factor; Familien-Apps: s.u.
        require_pkce: true
        pkce_challenge_method: 'S256'
        redirect_uris:
          - 'https://<app>.kaleschke.info/<oidc-callback-pfad>'
        scopes:
          - 'openid'
          - 'profile'
          - 'email'
          - 'groups'
        response_types:
          - 'code'
        grant_types:
          - 'authorization_code'
        token_endpoint_auth_method: 'client_secret_basic'
        userinfo_signed_response_alg: 'none'

Client-Secret erzeugen (auf dem Host)

docker exec authelia authelia crypto hash generate pbkdf2 \
  --variant sha512 --random --random.length 72 --random.charset rfc3986
  • Ausgabe: Random Password (Klartext) + Digest (pbkdf2-Hash).
  • Hash -> Host-Config client_secret.
  • Klartext -> App-Stack (Komodo Stack-ENV/Secret) + optional Vaultwarden.
  • Klartext nicht ins Repo, nicht in Logs.

Reihenfolge / Rollout

Stufe App Domain OIDC-Support Policy Risiko Begruendung
1 (Proof) ERLEDIGT 2026-06-06 Grafana (monitoring) monitoring.kaleschke.info nativ (generic_oauth) two_factor niedrig Live + Login verifiziert. Authelia-Client grafana (host), Secret als Datei /mnt/user/appdata/secrets/grafana_oidc_client_secret via __FILE, ForwardAuth-Middleware durch OIDC ersetzt, lokaler Admin bleibt Fallback
2 Immich immich.kaleschke.info nativ (Admin-UI/Config-File) s. u. (Familie) mittel GEPARKT bis Onboarding (Entscheidung 2026-06-06): nur micha hat Authelia-Account, Familien-SSO-Nutzen entsteht erst mit Familien-Accounts; Immich ist mobil-lastig (hoechste Stoeranfaelligkeit) und braucht UI/Config-File. Erst nach Onboarding gezielt. Runbook bereit.
3 Nextcloud cloud.kaleschke.info App user_oidc (+occ) s. u. mittel GEPARKT bis Onboarding (Entscheidung 2026-06-06): wie Immich; braucht user_oidc-App-Install + occ. Lokaler Login bleibt. Erst nach Onboarding. Runbook bereit.
4 ERLEDIGT 2026-06-06 Mealie mealie.kaleschke.info nativ one_factor niedrig Live + Login verifiziert. OIDC-Env additiv (lokaler Login bleibt), Secret als Stack-ENV ${MEALIE_OIDC_CLIENT_SECRET}, extra_hosts noetig (s. Gotchas)
5 Paperless-ngx paperless.kaleschke.info django-allauth (Umgebungsvariablen) two_factor mittel dokumentenlastig, Operator-nah

Nicht OIDC: Vaultwarden hat kein Standard-Endnutzer-OIDC (SSO ist Enterprise/Bitwarden-Feature) -> bleibt eigener Login. ntfy bleibt wie gehabt.

Policy Familien-Apps

  • Admin-Apps (Grafana, Paperless): authorization_policy: two_factor.
  • Familien-Apps (Immich, Nextcloud, Mealie): Start mit one_factor und lokalen App-Logins als Fallback. 2FA fuer Familie erst spaeter, sobald TOTP-Enrollment pro Person eingerichtet ist; sonst entsteht unnoetiges Lockout-Risiko.

Stufe 1 konkret: Grafana (empfohlener Erststart)

A) Authelia (Host) - Client anlegen

  1. Secret erzeugen (Befehl oben). Klartext + Hash notieren.
  2. In /mnt/user/appdata/authelia/config/configuration.yml unter identity_providers.oidc.clients neuen Block einfuegen:
    - client_id: 'grafana'
      client_name: 'Grafana'
      client_secret: '<HASH>'
      public: false
      authorization_policy: 'two_factor'
      require_pkce: true
      pkce_challenge_method: 'S256'
      redirect_uris:
        - 'https://monitoring.kaleschke.info/login/generic_oauth'
      scopes: ['openid', 'profile', 'email', 'groups']
      response_types: ['code']
      grant_types: ['authorization_code']
      token_endpoint_auth_method: 'client_secret_basic'
      userinfo_signed_response_alg: 'none'
    
  3. docker restart authelia, Health + Log pruefen (Startup complete, keine Fehler).

B) Grafana (Komodo Stack-ENV) - generic_oauth

Im monitoring-Stack (Grafana) setzen (Klartext-Secret aus Schritt A):

GF_AUTH_GENERIC_OAUTH_ENABLED=true
GF_AUTH_GENERIC_OAUTH_NAME=Authelia
GF_AUTH_GENERIC_OAUTH_CLIENT_ID=grafana
GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET=<KLARTEXT-SECRET>
GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email groups
GF_AUTH_GENERIC_OAUTH_AUTH_URL=https://auth.kaleschke.info/api/oidc/authorization
GF_AUTH_GENERIC_OAUTH_TOKEN_URL=https://auth.kaleschke.info/api/oidc/token
GF_AUTH_GENERIC_OAUTH_API_URL=https://auth.kaleschke.info/api/oidc/userinfo
GF_AUTH_GENERIC_OAUTH_USE_PKCE=true
GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP=true
# optional Rollen-Mapping ueber groups:
# GF_AUTH_GENERIC_OAUTH_ROLE_ATTRIBUTE_PATH=contains(groups[*], 'admins') && 'Admin' || 'Viewer'
  • GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET als Stack-ENV-only (kein _FILE-Support) -> in docs/SECRETS_MAP.md als grafana_oidc_client_secret (Stack-ENV) nachziehen.

C) Test + Rollback

  • Test: monitoring.kaleschke.info -> "Sign in with Authelia" -> Authelia-Login (2FA) -> zurueck in Grafana, eingeloggt.
  • Fallback bleibt: lokaler Grafana-Admin-Login (/login) ist weiter aktiv -> kein Lockout.
  • Rollback: GF_AUTH_GENERIC_OAUTH_ENABLED=false (Grafana redeploy) und/oder Client-Block in Authelia entfernen + docker restart authelia.

Doku-Nachzug bei jedem neuen Client

  • docs/SECRETS_MAP.md: pro App <app>_oidc_client_secret (Stack-ENV) + Hinweis "Hash in Authelia-Host-Config".
  • docs/SERVICE_CATALOG.md: App-Zeile um "OIDC via Authelia" ergaenzen.
  • Dieses Dokument: Rollout-Tabelle abhaken.
  • docs/MASTER_TODO.md: Fortschritt im OIDC-Punkt nachziehen.

Gotchas (aus dem realen Rollout 2026-06-06)

  • extra_hosts ist Pflicht fuer App-Container, die selbst zu Authelia connecten (OIDC-Discovery/Token sind Server-zu-Server): Der App-Container loest auth.kaleschke.info per Docker-DNS oft nicht auf -> httpx.ConnectTimeout / 500 beim OAuth-Start. Fix wie Komodo:
    extra_hosts:
      - "auth.kaleschke.info:192.168.178.58"
    
    Cert validiert weiter (SNI/Hostname bleibt gleich, nur die IP wird gemappt). Gilt fuer Mealie (bestaetigt) und sehr wahrscheinlich Paperless/Immich/Nextcloud.
  • Additiv heisst additiv: OIDC als zusaetzlichen Login aktivieren, lokalen Login NICHT abschalten, AUTO_REDIRECT/Force-OIDC aus -> kein Lockout.
  • Account-Linking per E-Mail: Apps verknuepfen den OIDC-User i. d. R. per E-Mail-Claim. Stimmt die Authelia-E-Mail mit dem App-Account, wird verknuepft; sonst legt die App (bei aktivem Signup) einen neuen User an.
  • Secret-Mechanik je App verschieden: Grafana __FILE (Docker-Secret), Mealie Stack-ENV ${...}. Hash immer in der Authelia-Host-Config, Klartext nie ins Repo.

Spaetere Feinschliffe vor breitem Rollout

  1. Gruppen/Rollen-Mapping: braucht es Authelia-Gruppen (z. B. admins, family) fuer App-Rollen (Grafana Admin/Viewer, Nextcloud-Gruppen)? Wenn ja, in der Authelia User-Datenbank Gruppen pflegen.
  2. Familien-2FA spaeter neu bewerten, nachdem echte Familien-Accounts in Authelia angelegt und TOTP pro Person verstanden ist.