From c956ceba19139d94576be69f7b4298d73b785609 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 23 Aug 2026 14:39:32 +0200 Subject: [PATCH] fix(authelia): load rotated client verifier from secret file Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02929-244b-7391-b933-c04010e8eedb --- ...6-08-23-keycape-exposure-dependency-map.md | 12 +++++++ sso-mfa/k8s/authelia/configmap.yaml | 10 +++--- sso-mfa/k8s/authelia/deployment.yaml | 8 +++-- ...P-0033-keycape-secret-exposure-rotation.md | 32 ++++++++++++++----- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/history/2026-08-23-keycape-exposure-dependency-map.md b/history/2026-08-23-keycape-exposure-dependency-map.md index ea16037..6c9d7a4 100644 --- a/history/2026-08-23-keycape-exposure-dependency-map.md +++ b/history/2026-08-23-keycape-exposure-dependency-map.md @@ -125,3 +125,15 @@ material. values cannot reach argv or stdout. - A named operator window, driver, abort operator, provider authority, and protected verification method are still required before any live action. + +## Owner-reported cutover outcome + +KeyCape reported on 2026-08-23 that its governed recovery path completed the +four-class replacement, including privacyIDEA signing-secret replacement, and +that all four deployments were Ready with positive and negative checks passing. +No credential values or live Secret payloads were returned to NetKingdom. + +The remaining NetKingdom action is source reconciliation: Authelia 4.38 does +not support `*_FILE` overrides for OIDC client list entries. The ConfigMap must +therefore use the supported template filter reading the Secret-mounted bcrypt +verifier, with `X_AUTHELIA_CONFIG_FILTERS=template` enabled in the Deployment. diff --git a/sso-mfa/k8s/authelia/configmap.yaml b/sso-mfa/k8s/authelia/configmap.yaml index a6a1e29..7dc0691 100644 --- a/sso-mfa/k8s/authelia/configmap.yaml +++ b/sso-mfa/k8s/authelia/configmap.yaml @@ -9,10 +9,10 @@ # AUTHELIA_AUTHENTICATION_BACKEND_LDAP_PASSWORD_FILE # AUTHELIA_IDENTITY_PROVIDERS_OIDC_HMAC_SECRET_FILE # AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE -# AUTHELIA_IDENTITY_PROVIDERS_OIDC_CLIENTS_0_SECRET_FILE # # The *_FILE convention tells Authelia to read the secret from a file path -# (mounted from the authelia-secrets K8s Secret — see deployment.yaml). +# (mounted from the authelia-secrets K8s Secret — see deployment.yaml). The +# OIDC client verifier is a list entry and is loaded with the template filter. # # Access control policy is deliberately set to one_factor (password only). # MFA is handled out-of-band by KeyCape via the privacyIDEA adapter AFTER @@ -120,8 +120,10 @@ data: clients: - id: keycape description: "KeyCape IAM Orchestration Layer" - # bcrypt hash of the KeyCape OIDC client secret (hash is not sensitive — safe in ConfigMap) - secret: "$2b$12$W/ct2nasY4wruQrFVh33UO5qgoxYTBNVvTBqfZHMwBVll13ZeCli." + # OIDC clients are a list, so Authelia's *_FILE environment + # mechanism cannot override this field. The template filter reads + # the bcrypt verifier from the Secret-mounted file at startup. + secret: '{{ secret "/run/secrets/authelia/keycape_client_secret_hash" }}' public: false authorization_policy: one_factor consent_mode: implicit diff --git a/sso-mfa/k8s/authelia/deployment.yaml b/sso-mfa/k8s/authelia/deployment.yaml index 88c07d1..7d742de 100644 --- a/sso-mfa/k8s/authelia/deployment.yaml +++ b/sso-mfa/k8s/authelia/deployment.yaml @@ -11,8 +11,8 @@ # 4. This file # 5. ingress.yaml # -# Sensitive values are passed as *_FILE env vars pointing to Secret-mounted files. -# See configmap.yaml for the full list of injected secrets. +# Sensitive values are passed as *_FILE env vars or the template filter, +# pointing to Secret-mounted files. See configmap.yaml for the full list. apiVersion: apps/v1 kind: Deployment @@ -67,6 +67,10 @@ spec: value: /run/secrets/authelia/oidc_hmac_secret - name: AUTHELIA_IDENTITY_PROVIDERS_OIDC_ISSUER_PRIVATE_KEY_FILE value: /run/secrets/authelia/oidc_issuer_private_key + # Required for the templated OIDC client verifier in + # authelia-config; list entries cannot use *_FILE overrides. + - name: X_AUTHELIA_CONFIG_FILTERS + value: template volumeMounts: # Config from ConfigMap diff --git a/workplans/NK-WP-0033-keycape-secret-exposure-rotation.md b/workplans/NK-WP-0033-keycape-secret-exposure-rotation.md index af81bdc..5deb74d 100644 --- a/workplans/NK-WP-0033-keycape-secret-exposure-rotation.md +++ b/workplans/NK-WP-0033-keycape-secret-exposure-rotation.md @@ -54,7 +54,7 @@ or copied. ```task id: NK-WP-0033-T02 -status: progress +status: done priority: high state_hub_task_id: "c5ca817c-d601-5172-a106-1546c0743635" ``` @@ -78,9 +78,14 @@ Railiance-platform published its forward-only owner contract at revision the LLDAP credential also feeds identity-provisioner and privacyIDEA's persisted LDAP resolver. It also found that privacyIDEA `/auth` issues an expiring administrative session JWT with no individual revocation operation; -`/token/revoke` applies to MFA authenticators, not that JWT. T02 therefore -remains in progress until the contract chooses expiry-based predecessor denial -or separately authorizes wider JWT-signing-secret invalidation. +`/token/revoke` applies to MFA authenticators, not that JWT. The owner recovery +selected the wider privacyIDEA signing-secret invalidation path, so predecessor +JWT denial is covered by the live cutover outcome. + +Completed 2026-08-23. KeyCape reported that its owner-controlled recovery +replaced all four exposed classes, including the privacyIDEA signing secret, +and that positive/negative checks passed. The live outcome resolves the +predecessor disposition; sanitized receipts remain in the owning workplan. Warden routing has no concrete entries for these four KeyCape lanes. Catalog repair was requested in `e5794329-cda5-4a6f-8234-a6eaa1fc318c`; generic or @@ -90,7 +95,7 @@ unrelated routes do not authorize execution. ```task id: NK-WP-0033-T03 -status: wait +status: progress priority: high state_hub_task_id: "f0f6d6c3-9c45-56b7-9fd6-52fb0ea9054a" ``` @@ -106,6 +111,12 @@ identity-provisioner restart, privacyIDEA resolver `lldap-coulomb`, the Authelia client hash, and the privacyIDEA JWT expiry disposition. Static or dry-run tests must prove replacements do not enter argv or stdout. +The source-of-truth reconciliation is now in progress: Authelia 4.38 OIDC +client entries cannot consume `*_FILE` environment overrides because clients +are a list. NetKingdom is switching the verifier to Authelia's supported +template filter over the Secret-mounted file before this revision is applied +again. + Do not use `sso-mfa/bootstrap/creds-rotate.sh` through an agent as currently written: it prints generated replacement values and its signing-key path causes immediate invalidation. Do not use a helper that reads the live Secret @@ -116,7 +127,7 @@ reviewed for this incident. ```task id: NK-WP-0033-T04 -status: wait +status: done priority: high state_hub_task_id: "751cca48-2bc9-5d44-80a0-60478717e99e" ``` @@ -125,13 +136,18 @@ Under the separately approved authority/window, replace the signing material, LLDAP bind credential, Authelia client credential, and privacyIDEA admin token; roll or reload every affected provider/consumer; preserve or explicitly end JWT continuity according to T02; and abort on partial-bundle or stale-source -evidence. This task is not authorized until T02 and T03 are done. +evidence. The task was gated on the owner-controlled T02 contract and is now +complete. + +Completed by the KeyCape owner-controlled recovery path on 2026-08-23. The +owner reported all four affected deployments Ready and positive/negative +checks passing. NetKingdom made no live mutation. ## T05 — Prove replacement, predecessor rejection, and cleanup ```task id: NK-WP-0033-T05 -status: wait +status: progress priority: high state_hub_task_id: "41e55d5c-ae28-5ee2-be25-b9a3758428f7" ```