Files
homelab-infra/docs/AUTHELIA_OIDC_PLAN.md
T
Micha 2f3a029098 authelia-oidc: Grafana-Proof als erledigt dokumentieren + Secret eintragen
- SECRETS_MAP: grafana_oidc_client_secret (Datei + __FILE, Hash in Authelia-Host-Config)
- AUTHELIA_OIDC_PLAN: Stufe 1 (Grafana) als erledigt markiert
- MASTER_TODO: OIDC-Proof verifiziert, naechster Schritt Familien-Apps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 13:17:29 +02:00

7.5 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: Entwurf/Runbook. Noch kein Client produktiv ausgerollt. Reihenfolge bewusst klein: erst ein risikoarmer Proof (Grafana), dann Familien-Apps.


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 s. u. (Familie) mittel Familien-Fotos, viele Nutzer; nach erfolgreichem Proof
3 Nextcloud cloud.kaleschke.info App user_oidc s. u. mittel klassischer OIDC-Login parallel zu lokalem Admin
4 Mealie mealie.kaleschke.info nativ s. u. niedrig klein, gut zum Familien-Rollout
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-Entscheidung Familien-Apps

  • Admin-Apps (Grafana, Paperless): authorization_policy: two_factor.
  • Familien-Apps (Immich, Nextcloud, Mealie): offene Operator-Entscheidung ob one_factor (nur Authelia-Passwort, bequemer fuer Familie) oder two_factor. Empfehlung: mit one_factor starten, 2FA fuer Familie spaeter, sobald TOTP-Enrollment pro Person eingerichtet ist (sonst Lockout fuer Familienmitglieder).

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.

Offene Operator-Entscheidungen vor breitem Rollout

  1. Familien-Apps one_factor vs two_factor (Lockout-Risiko fuer Familie ohne TOTP).
  2. 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.
  3. Reihenfolge nach dem Grafana-Proof bestaetigen.