From 3c6f3645b37f923c9165ee1256199e1ebbc866e2 Mon Sep 17 00:00:00 2001 From: Thore Cimbal Date: Fri, 7 Aug 2026 12:00:00 +0000 Subject: [PATCH] fix(authentik): resolve recovery flow via Find instead of KeyOf Adding name and title was necessary but not sufficient - the blueprint kept failing. Running ak apply_blueprint by hand showed why the real error was never visible: when authentik logs a failed entry it calls str() on the KeyOf object, whose __repr__ resolves against an EMPTY blueprint and raises the very same exception. The logging path masks the actual validation error. KeyOf also couples every stage binding to that one entry succeeding in the same run. Find resolves against the database instead, which is what the neighbouring blueprints in this same ConfigMap already do, and the flow exists. Refs axion1337.chat/axion1337.chat-gitops#60 --- apps/authentik/authentik-blueprints.yaml | 28 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/apps/authentik/authentik-blueprints.yaml b/apps/authentik/authentik-blueprints.yaml index 1d548f4..f168411 100644 --- a/apps/authentik/authentik-blueprints.yaml +++ b/apps/authentik/authentik-blueprints.yaml @@ -114,7 +114,18 @@ data: # stages the built-in default-recovery-flow already uses successfully, # plus our own redirect stage instead of falling back to the authentik # dashboard (blocked for type=external Matrix users). - # ⚠️ name und title MUESSEN hier stehen. Der FlowSerializer verlangt beide + # ⚠️ Hier steckten ZWEI Fehler uebereinander (gitops#60). + # + # 1. !KeyOf koppelt jede Bindung daran, dass DIESER Eintrag im selben Lauf + # eine Model-Instanz erzeugt. Scheitert er, faellt der ganze Blueprint. + # Schlimmer: beim Protokollieren des Fehlers ruft Authentik str() auf das + # !KeyOf-Objekt, dessen __repr__ gegen ein LEERES Blueprint aufloest und + # dabei dieselbe Ausnahme wirft - die echte Fehlermeldung wird dadurch + # ueberdeckt. Man sieht nur noch "KeyOf: failed to find entry". + # Deshalb jetzt !Find gegen die Datenbank, wie in den Blueprints darunter + # ohnehin ueblich. Der Flow existiert, das ist stabiler und entkoppelt. + # + # 2. name und title MUESSEN gesetzt sein. Der FlowSerializer verlangt beide # (keine Model-Defaults). Fehlen sie, scheitert die Validierung, der Eintrag # bekommt keine Model-Instanz - und JEDES nachfolgende `!KeyOf # matrix_recovery_flow` laeuft ins Leere. Genau das war der Zustand bis @@ -129,7 +140,6 @@ data: state: present identifiers: slug: matrix-recovery - id: matrix_recovery_flow attrs: name: "Welcome to aXion1337! Please provide a username or mail-adress." title: "Welcome to aXion1337! Please provide a username or mail-adress." @@ -138,7 +148,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 10 attrs: stage: !Find [authentik_stages_identification.identificationstage, [name, default-recovery-identification]] @@ -146,7 +156,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 20 attrs: stage: !Find [authentik_stages_email.emailstage, [name, default-recovery-email]] @@ -154,7 +164,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 30 attrs: stage: !Find [authentik_stages_prompt.promptstage, [name, "Change your password"]] @@ -162,7 +172,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 40 attrs: stage: !Find [authentik_stages_user_write.userwritestage, [name, default-recovery-user-write]] @@ -170,7 +180,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 100 attrs: stage: !Find [authentik_stages_user_login.userloginstage, [name, default-recovery-user-login]] @@ -178,7 +188,7 @@ data: - model: authentik_flows.flowstagebinding state: present identifiers: - target: !KeyOf matrix_recovery_flow + target: !Find [authentik_flows.flow, [slug, matrix-recovery]] order: 110 attrs: stage: !Find [authentik_stages_redirect.redirectstage, [name, matrix-invitation-redirect]] @@ -189,7 +199,7 @@ data: identifiers: name: default-authentication-identification attrs: - recovery_flow: !KeyOf matrix_recovery_flow + recovery_flow: !Find [authentik_flows.flow, [slug, matrix-recovery]] matrix-mfa-setup-redirect.yaml: | # yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json version: 1