From be2a56ccf5d282f0434b72ec03f7cd857930768e Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Wed, 22 Jul 2026 08:09:15 -0700 Subject: [PATCH] =?UTF-8?q?fix(iam):=20don't=20PATCH=20existing=20authenti?= =?UTF-8?q?k=20applications=20=E2=80=94=20detail=20endpoint=20enforces=20a?= =?UTF-8?q?ccess=20policy=20and=20404s=20for=20akadmin,=20aborting=20the?= =?UTF-8?q?=20loop=20before=20all=20providers=20got=20grant=5Ftypes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iam/scripts/authentik-provision.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/k8s/security/iam/scripts/authentik-provision.py b/k8s/security/iam/scripts/authentik-provision.py index fab4cfa..7373dcc 100644 --- a/k8s/security/iam/scripts/authentik-provision.py +++ b/k8s/security/iam/scripts/authentik-provision.py @@ -301,14 +301,21 @@ for name, cfg in SERVICES.items(): }, ) + # superuser_full_list=true is REQUIRED on the LIST: the applications list + # applies access-policy filtering to the results array (these apps are bound + # to homelab-admins, and the bootstrap-token user akadmin is not a member), + # so without it the GET returns an empty results list even though the app + # exists -> fall through to POST -> 400 "already exists". + # + # We deliberately do NOT patch_existing here: the application DETAIL endpoint + # (PATCH /applications/{pk}/) enforces the same access policy and does NOT + # honor superuser_full_list, so PATCH-by-pk returns 404 for akadmin once the + # homelab-admins binding exists. That 404 aborted the loop before later + # providers got their grant_types. slug/provider/launch_url are set at + # creation and are stable (provider is get_or_create'd by name, stable pk), + # so find-or-create is sufficient. application = get_or_create( "/api/v3/core/applications/", "/api/v3/core/applications/", - # superuser_full_list=true is REQUIRED: the applications list applies - # access-policy filtering to the results array (these apps are bound to - # homelab-admins, and the bootstrap-token user akadmin is not a member), - # so without it the GET returns an empty results list even though the app - # exists -> get_or_create falls through to POST -> 400 "already exists", - # which aborted the whole loop before later providers got grant_types. f"slug={name}&superuser_full_list=true", { "name": cfg["display_name"], @@ -316,10 +323,6 @@ for name, cfg in SERVICES.items(): "provider": provider["pk"], "meta_launch_url": cfg["launch_url"], }, - patch_existing={ - "provider": provider["pk"], - "meta_launch_url": cfg["launch_url"], - }, ) app_pks_for_binding.append((name, application["pk"])) print(f" {name}: provider pk={provider['pk']} application pk={application['pk']}")