# 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**: ```yaml identity_providers: oidc: clients: - client_id: '' client_name: '' client_secret: '' public: false authorization_policy: 'two_factor' # admin-Apps: two_factor; Familien-Apps: s.u. require_pkce: true pkce_challenge_method: 'S256' redirect_uris: - 'https://.kaleschke.info/' 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) ```bash 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)** | Grafana (monitoring) | `monitoring.kaleschke.info` | nativ (`generic_oauth`) | `two_factor` | niedrig | Admin-only, lokaler Grafana-Admin bleibt als Fallback -> kein Lockout-Risiko | | 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: ```yaml - client_id: 'grafana' client_name: 'Grafana' client_secret: '' 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= 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 `_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.