diff --git a/docs/deployment-guides/02-authentik-identity-provider.md b/docs/deployment-guides/02-authentik-identity-provider.md index 5cfd7df..eb501ab 100644 --- a/docs/deployment-guides/02-authentik-identity-provider.md +++ b/docs/deployment-guides/02-authentik-identity-provider.md @@ -47,7 +47,8 @@ Nutzer wurden nie in Synapse angelegt. Behoben und als Authentik Blueprint (`apps/authentik/authentik-blueprints.yaml`) deklarativ ins Repo übernommen: vollständiger `matrix-invitation`-Flow (Invite → Prompt → Write → Password → Login → Redirect), leerer `matrix-recovery`-Flow ergänzt, `Brand.default_application` gesetzt. 2FA/Passkey-Selbst- -Einrichtung optional (`not_configured_action=skip`), auffindbar über +Einrichtung optional (`not_configured_action=skip`) — ⚠️ **gilt seit 2026-08-06 nur noch +für Mitglieder, für Admins ist MFA Pflicht**, siehe unten. Auffindbar über `axion1337.chat/docs/setup/security.html`. Details: siehe Wiki [Authentik-OIDC.md](https://rohana.axion1337.de/sorb/axion1337.chat-gitops/wiki/Authentik-OIDC). @@ -59,3 +60,50 @@ als Client-seitige Änderung nachgehalten: --- **Weitere Details**: Siehe Kapitel 2 in diesem Projekt. + +## MFA-Pflicht für Admins (2026-08-06, gitops#57) + +**Für Mitglieder bleibt 2FA freiwillig, für die Gruppe `authentik Admins` ist sie Pflicht.** + +Umgesetzt als eigener Blueprint `admin-mfa-enforcement.yaml` in +`apps/authentik/authentik-blueprints.yaml`. + +### Warum eine zweite Stage statt einer Umstellung + +`not_configured_action` hängt an der **Stage**, nicht an der Bindung. Die vorhandene +`default-authentication-mfa-validation` umzustellen hätte deshalb **alle Mitglieder** +getroffen — und wäre zugleich eine Änderung an einem Objekt aus Authentiks eigenem +Blueprint gewesen. + +Stattdessen: eine eigene `admin-mfa-validation` auf Ordnung **31**, direkt hinter der +Standard-Stage (30) und vor dem Login (100), eingeschränkt über eine `PolicyBinding` +mit gesetztem `group`. Eine solche Bindung wertet Gruppenmitgliedschaft aus +(`PolicyResult(group.is_member(user))`). **Kein Authentik-Standardobjekt wird +angefasst.** + +### Die drei Einstellungen, auf die es ankommt + +| Feld | Wert | Warum | +|---|---|---| +| `not_configured_action` | `configure` | führt durch die Einrichtung, statt auszusperren | +| `configuration_stages` | TOTP + WebAuthn | sonst kann `configure` nichts anbieten | +| `last_auth_threshold` | `hours=1` | verhindert die doppelte Abfrage | + +⚠️ **`configure`, niemals `deny`.** `deny` weist Admins ohne zweiten Faktor ab — und +danach gibt es keinen Weg zurück außer über den Cluster. `configure` erzwingt +genauso, führt aber durch die Einrichtung. + +⚠️ **`last_auth_threshold` ist kein Beiwerk.** Die Standard-Stage auf Ordnung 30 +validiert bereits, wer einen Faktor besitzt. Ohne Schwelle (`seconds=0`, der Default) +würde unsere Stage direkt danach ein zweites Mal fragen. Mit `hours=1` überspringt +sie sich, wenn das Gerät gerade benutzt wurde — übrig bleibt genau der Zielfall: +Admin ohne zweiten Faktor. + +### Die Falle beim Ändern + +**Der Gruppenname ist die ganze Wirkung.** Stimmt er nicht, greift die Regel für +**niemanden** — und wirft dabei keinen Fehler. Das ist schlechter als keine Regel, +weil es sich sicher anfühlt. Wer die Gruppe umbenennt, muss den Blueprint mitziehen. + +Prüfen lässt sich die Wirkung nur an einem Konto, das in der Gruppe ist: anmelden und +sehen, ob nach dem Passwort die Einrichtung kommt.