This is the actual production-breaking bug: the scope-mapping lookup
used ?managed__iexact=..., which this Authentik version doesn't
support as a filter - it silently returns the whole unfiltered list
instead of erroring, so d['results'][0]['pk'] always grabbed the same
first item (the "Proxy outpost" ak_proxy scope, not openid/profile/
email). Every run attached that single wrong scope to the provider,
which meant every real login would fail at the userinfo step with a
403 ("Scope mismatch", token had zero of the required openid scope).
Fixed by filtering on scope_name (the field that actually works) and
added a hard failure if a lookup ever comes up empty, instead of
silently proceeding with a broken scope list.
Manually verified against the live dev-lisilou.jerodrigged.com OIDC
login: full authorization-code+PKCE round trip against a disposable
test user, confirmed valid session cookie with correct admin group
claim. Also PATCHed the already-created provider's property_mappings
directly on auth.jerodrigged.com so dev doesn't need to wait for a
re-run to get the fix.
Two bugs found running this against the live Authentik instance for
the first time:
- jget's <<<"$1" here-string always overrode stdin, so `api ... | jget
- "expr"` never actually read curl's piped output - it fed the
literal string "-" to json.load() instead, and the abandoned pipe
made curl fail with "Failed writing body". Fixed by branching on
$1 == "-" to read the real stdin in that case.
- The prompt stage lives at /stages/prompt/stages/, not /stages/prompt/
(that path is prompt *fields*). Wrong path 404'd.
Also switched `python` -> `python3` throughout for portability.
Verified idempotent end-to-end against auth.jerodrigged.com: provider,
application, lisilou-admin group, and the full enrollment flow
(prompt -> write -> login stages, bound and set as the brand's
enrollment flow) all created successfully, second run reports
everything as already existing.
Creates the OAuth2 provider, application, lisilou-admin group, and the
client enrollment flow via the Authentik API, then prints ready-to-paste
api/.env lines. Run with AUTHENTIK_URL + AUTHENTIK_TOKEN once CT121 is up.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>