diff --git a/apps/authentik/authentik-blueprints.yaml b/apps/authentik/authentik-blueprints.yaml index 059d4af..fc5dce3 100644 --- a/apps/authentik/authentik-blueprints.yaml +++ b/apps/authentik/authentik-blueprints.yaml @@ -206,6 +206,63 @@ data: order: 10 attrs: stage: !Find [authentik_stages_redirect.redirectstage, [name, matrix-invitation-redirect]] + admin-mfa-enforcement.yaml: | + # yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json + version: 1 + metadata: + name: admin-mfa-enforcement + labels: + blueprints.goauthentik.io/instantiate: "true" + entries: + # MFA-Pflicht fuer Admins, ohne sie fuer alle anderen zu erzwingen. + # + # Warum eine ZWEITE Validate-Stage statt not_configured_action am + # bestehenden default-authentication-mfa-validation umzustellen: dieses Feld + # haengt an der Stage, nicht an der Bindung - eine Umstellung wuerde alle + # Mitglieder treffen. Und die Standard-Stage anzufassen hiesse, ein Objekt + # aus Authentiks eigenem Blueprint zu veraendern. + # + # Diese Loesung fasst KEIN Authentik-Standardobjekt an. Sie haengt eine + # eigene Stage hinter die vorhandene und bindet sie an die Admin-Gruppe. + - model: authentik_stages_authenticator_validate.authenticatorvalidatestage + state: present + identifiers: + name: admin-mfa-validation + id: admin_mfa_stage + attrs: + # configure statt deny: Wer keinen Faktor hat, wird beim Login durch die + # Einrichtung GEFUEHRT. deny wuerde ihn aussperren - und bei einem + # Admin-Konto gibt es dann keinen Weg zurueck ausser ueber den Cluster. + not_configured_action: configure + configuration_stages: + - !Find [authentik_stages_authenticator_totp.authenticatortotpstage, [name, default-authenticator-totp-setup]] + - !Find [authentik_stages_authenticator_webauthn.authenticatorwebauthnstage, [name, default-authenticator-webauthn-setup]] + # Verhindert die doppelte Abfrage: Die Standard-Stage auf Ordnung 30 + # validiert bereits, wer einen Faktor hat. Diese hier laeuft danach und + # ueberspringt sich, wenn das Geraet gerade eben benutzt wurde. Uebrig + # bleibt genau der Fall, um den es geht - Admin ohne zweiten Faktor. + last_auth_threshold: hours=1 + + # Ordnung 31: direkt hinter der Standard-MFA-Stage (30), vor dem Login (100). + - model: authentik_flows.flowstagebinding + state: present + identifiers: + target: !Find [authentik_flows.flow, [slug, default-authentication-flow]] + order: 31 + id: admin_mfa_binding + attrs: + stage: !KeyOf admin_mfa_stage + + # Eine PolicyBinding mit gesetztem "group" prueft Gruppenmitgliedschaft + # (PolicyResult(group.is_member(user))). Ohne diese Bindung wuerde die + # Stage fuer ALLE gelten - dann waere 2FA fuer die ganze Instanz Pflicht. + - model: authentik_policies.policybinding + state: present + identifiers: + target: !KeyOf admin_mfa_binding + order: 0 + attrs: + group: !Find [authentik_core.group, [name, "authentik Admins"]] matrix-brand-default-app.yaml: | # yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json version: 1