From 4645e320d5025f0227a12be3f4caf414c487ae70 Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Thu, 13 Aug 2026 08:56:37 -0700 Subject: [PATCH] =?UTF-8?q?fix(authentik):=20label=20argocd=20oidc-secret?= =?UTF-8?q?=20part-of=3Dargocd=20=E2=80=94=20argocd's=20$secret=20substitu?= =?UTF-8?q?tion=20only=20reads=20labelled=20Secrets;=20without=20it=20OIDC?= =?UTF-8?q?=20login=20failed=20with=20oauth2=20invalid=5Fclient=20(empty?= =?UTF-8?q?=20client=5Fsecret=20to=20IdP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- k8s/infra/iam/scripts/authentik-provision.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/k8s/infra/iam/scripts/authentik-provision.py b/k8s/infra/iam/scripts/authentik-provision.py index afd0de6..b1aba19 100644 --- a/k8s/infra/iam/scripts/authentik-provision.py +++ b/k8s/infra/iam/scripts/authentik-provision.py @@ -88,7 +88,7 @@ def kubectl_get_secret_key(namespace, name, key): return base64.b64decode(p.stdout).decode() -def kubectl_create_secret(namespace, name, literals: dict): +def kubectl_create_secret(namespace, name, literals: dict, labels: dict = None): """Idempotent: create-or-update via dry-run|apply, same pattern used elsewhere in this repo (setup_vault.sh, apply-vault-secrets.sh).""" args = ["kubectl", "-n", namespace, "create", "secret", "generic", name] @@ -103,6 +103,13 @@ def kubectl_create_secret(namespace, name, literals: dict): if apply.returncode != 0: die(f"applying secret {namespace}/{name}: {apply.stderr}") print(f" secret {namespace}/{name}: {apply.stdout.strip()}") + if labels: + # argocd's `$secret:key` substitution only reads Secrets carrying + # app.kubernetes.io/part-of: argocd — without it OIDC login fails with + # oauth2 "invalid_client" (empty client_secret sent to the IdP). + label_args = ["kubectl", "-n", namespace, "label", "secret", name, + "--overwrite"] + [f"{k}={v}" for k, v in labels.items()] + subprocess.run(label_args, capture_output=True, text=True) def get_or_create(list_path, create_path, query, payload, patch_existing=None): @@ -269,6 +276,8 @@ SERVICES = { "client_secret_source": ("argocd", "oidc-secret", "client-secret"), "generate_if_missing": True, "extra_secret_literals": {"client-id": "argocd"}, + # argocd only reads $secret refs from Secrets labelled part-of: argocd. + "secret_labels": {"app.kubernetes.io/part-of": "argocd"}, "redirect_uris": ["https://argocd.riotpiao.com/auth/callback"], "launch_url": "https://argocd.riotpiao.com", "display_name": "Argo CD", @@ -299,7 +308,8 @@ for name, cfg in SERVICES.items(): client_secret = gen_secret(40) literals = {key: client_secret} literals.update(cfg.get("extra_secret_literals", {})) - kubectl_create_secret(ns, secret_name, literals) + kubectl_create_secret(ns, secret_name, literals, + labels=cfg.get("secret_labels")) print(f" {name}: generated new client secret -> {ns}/{secret_name}") else: print(f" {name}: using existing client secret from {ns}/{secret_name}")