# ============================================================================= # L0 STATIC — Keycloak client secrets are declared consistently, ordered by a REAL # Flux edge, and healed by a reconciler whose behaviour is proven offline # Catalog: docs/14 L0 row ("Pre-apply, in CI") — runs WITHOUT a cluster. # # R-IDP-03 (identity config is declarative) and R-IDP-04 (IdP secrets SOPS-encrypted) # are both implemented through ONE mechanism that FAILS OPEN: the KeycloakRealmImport # resolves each client's secret from a `(env:NAME)` placeholder mapped to a key of the # SOPS-encrypted keycloak-realm-clients Secret. When the operator cannot resolve a # placeholder it stores the LITERAL placeholder text as the client secret AND THE IMPORT # JOB STILL REPORTS SUCCESS — then rests at Done=True / Started=False and never re-runs. # # Measured 2026-09-06: prod had all 12 clients holding the literal placeholder (every # OIDC login failed with "Invalid client or Invalid client credentials"); dev had exactly # one (oauth2-proxy), because that Secret key was added AFTER dev's import completed. # Declarative config that silently does not apply is not declarative config. # # GIVEN the repository as authored, # THEN every confidential client declares a placeholder, every placeholder is defined, # resolves to the keycloak-realm-clients Secret, and names a key that EXISTS in the # SOPS file under the `-client-secret` contract the reconciler derives # from; public clients declare no secret; the Flux Kustomization applying the Secret # is a transitive `dependsOn` ancestor (wait: true) of the ones applying the import # and the reconciler — a real edge, not a comment; the reconciler is reconciled from # BOTH cluster entrypoints, mounts only what it needs, carries no ServiceAccount # token and contains no dollar sign; and its own `--selftest` (extracted from the # shipped ConfigMap and executed) proves compare-then-write, idempotence, # no-secret-logging, the endpoint allow-list and fail-closed behaviour. # # STATUS: EXECUTABLE. `check.sh` is a pure offline assertion script (git + PyYAML + # stdlib); conformance/run.sh --layer l0 and ci/l0.sh run it directly, and this Chainsaw # Test wraps the SAME script. # # NOT proven here: that the LIVE realm's stored secrets match git (that is # tests/l2-behavioral/keycloak-client-secrets-match-git), that the SOPS ciphertext # decrypts to a usable value (key PRESENCE is offline-checkable; plaintext is not), or # that the CronJob's schedule fires. # ============================================================================= apiVersion: chainsaw.kyverno.io/v1alpha1 kind: Test metadata: name: keycloak-client-secret-reconciler labels: conformance.home.k3s/R-IDP-03: "true" conformance.home.k3s/R-IDP-04: "true" annotations: conformance.home.k3s/requirements: "R-IDP-03, R-IDP-04" conformance.home.k3s/layer: "L0" conformance.home.k3s/safety-critical: "false" conformance.home.k3s/executable: "true" conformance.home.k3s/intent: >- Every OIDC client's secret is declared once, resolvable, ordered behind a real Flux dependency, and continuously reconciled — so an unresolved import placeholder can neither be merged nor silently persist in the realm. spec: steps: - name: audit-declaration-ordering-and-reconciler description: >- Assert the realm import, the SOPS Secret and the reconciler agree; that the Flux ordering is a real dependsOn edge; and run the reconciler's own selftest. try: - script: content: bash ./check.sh