fix(sec): the R-SEC-02 admission policy was never applied #16

Merged
jakman85 merged 1 commits from fix/kyverno-policy-was-never-applied into main 2026-09-29 18:28:54 +00:00
Owner

#13's security policy was never applied to the cluster, and every signal said it was.

platform/kyverno/ holds three lists and only one applies anything:

File What it actually does
admission/kustomization.yaml reference only — its sibling says "kept as reference"
kyverno/kustomization.yaml the render root — namespace + HelmRelease only
platform-config/kustomization.yaml applies the ClusterPolicies (they need the CRDs first)

#13 added the policy to the first. Everything went green: the file parsed, kyverno test
exercised it by path and passed, the merge gate passed, and Flux reported platform Ready at
the new revision
. Measured on prod afterwards:

kubectl get clusterpolicy conformance-trigger-job-shape
Error from server (NotFound)

…while ns/conformance, the conformance-trigger ServiceAccount, its Role and RoleBinding were
all live. That is precisely the state that identity's own RBAC header says must never exist —
the trigger present with nothing bounding it. The blast radius was small only because no trigger
kubeconfig exists yet. That's luck, not design.

The fix

Wires the policy into platform-config. Verified: the render goes 7 → 8 ClusterPolicies and
contains conformance-trigger-job-shape.

Closing the class, which matters more

New L0 check admission-policies-actually-applied: every ClusterPolicy under
platform/kyverno/ is either referenced by platform-config/kustomization.yaml or named in a
CI_ONLY list with a reason — and CI_ONLY may not name a policy that is applied, so the
exemption can't rot in either direction.

Scope is whole-repo deliberately: a policy wired nowhere touches no requirement the diff
attributes, so a path-scoped run would have skipped it on the exact commit that introduced the bug.

Proven both ways:

State Result
fix reverted FAIL, naming conformance-trigger-job-shape as never applied
fix applied PASS — 9 policy files, 8 applied, 1 CI-only with a reason

kyverno test proves a policy is correct. This proves it is deployed. Nothing did before.

Gate: PASS (run with a settings token, since REQUIRE_GITEA_SETTINGS is now live on main).

Co-Authored-By: Claude Opus 5 (1M context) [email protected]

🤖 Generated with Claude Code

**#13's security policy was never applied to the cluster, and every signal said it was.** `platform/kyverno/` holds three lists and only one applies anything: | File | What it actually does | |---|---| | `admission/kustomization.yaml` | **reference only** — its sibling says *"kept as reference"* | | `kyverno/kustomization.yaml` | the render root — namespace + HelmRelease **only** | | `platform-config/kustomization.yaml` | **applies the ClusterPolicies** (they need the CRDs first) | #13 added the policy to the first. Everything went green: the file parsed, `kyverno test` exercised it *by path* and passed, the merge gate passed, and Flux reported `platform` **Ready at the new revision**. Measured on prod afterwards: ``` kubectl get clusterpolicy conformance-trigger-job-shape Error from server (NotFound) ``` …while `ns/conformance`, the `conformance-trigger` ServiceAccount, its Role and RoleBinding were all live. **That is precisely the state that identity's own RBAC header says must never exist** — the trigger present with nothing bounding it. The blast radius was small only because no trigger kubeconfig exists yet. That's luck, not design. ### The fix Wires the policy into `platform-config`. Verified: the render goes 7 → 8 ClusterPolicies and contains `conformance-trigger-job-shape`. ### Closing the class, which matters more New L0 check **`admission-policies-actually-applied`**: every ClusterPolicy under `platform/kyverno/` is either referenced by `platform-config/kustomization.yaml` or named in a `CI_ONLY` list *with a reason* — and `CI_ONLY` may not name a policy that **is** applied, so the exemption can't rot in either direction. Scope is `whole-repo` deliberately: a policy wired nowhere touches no requirement the diff attributes, so a path-scoped run would have skipped it on the exact commit that introduced the bug. **Proven both ways:** | State | Result | |---|---| | fix reverted | **FAIL**, naming `conformance-trigger-job-shape` as never applied | | fix applied | **PASS** — 9 policy files, 8 applied, 1 CI-only with a reason | `kyverno test` proves a policy is **correct**. This proves it is **deployed**. Nothing did before. Gate: PASS (run with a settings token, since `REQUIRE_GITEA_SETTINGS` is now live on main). Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> 🤖 Generated with [Claude Code](https://claude.com/claude-code)
gitea-admin added 1 commit 2026-09-29 18:24:41 +00:00
fix(sec): the R-SEC-02 admission policy was never applied -- and nothing could tell
gate / gate (pull_request) Successful in 1m37s
gate / conformance (pull_request) Has been skipped
8c7a770de2
PR #13 added conformance-trigger-job-shape.yaml to platform/kyverno/admission/
kustomization.yaml. That file applies NOTHING. Its own sibling says so: "kept as
reference; THIS file is the buildable render root" -- and that render root
(platform/kyverno/kustomization.yaml) ships only the namespace and the HelmRelease,
noting that ClusterPolicies are applied a tier later, by platform-config, because they
need the Kyverno CRDs first.

So three lists exist and only platform-config/kustomization.yaml applies anything. The
policy went into the wrong one and EVERYTHING WENT GREEN: the file parsed, kyverno test
exercised it by path and passed, the merge gate passed, and Flux reported `platform`
Ready at the new revision. Measured on prod afterwards:

    kubectl get clusterpolicy conformance-trigger-job-shape
    Error from server (NotFound)

while ns conformance, the conformance-trigger ServiceAccount, its Role and its
RoleBinding were all live. That is exactly the state that identity's own RBAC header
says must never exist -- the trigger identity present with nothing bounding it. Blast
radius was small only because no trigger kubeconfig exists yet, which is luck, not design.

Wires the policy into platform-config (verified: the render goes from 7 ClusterPolicies to
8 and contains conformance-trigger-job-shape).

CLOSES THE CLASS, which matters more than the instance. Adds the L0 check
admission-policies-actually-applied: every ClusterPolicy file under platform/kyverno/ is
either referenced by platform-config/kustomization.yaml or named in a CI_ONLY list with a
reason -- and CI_ONLY may not name a policy that IS applied, so the exemption cannot rot in
either direction. Declared scope whole-repo deliberately: a policy wired nowhere touches no
requirement the diff attributes, so a path-scoped run would have skipped it on the exact
commit that introduced the defect.

Proven both ways, not assumed:
  with the fix reverted -> FAIL, naming conformance-trigger-job-shape as never applied
  with the fix          -> PASS, 9 policy files, 8 applied, 1 CI-only with a reason

`kyverno test` proves a policy is CORRECT. This proves it is DEPLOYED. Nothing did before.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
jakman85 approved these changes 2026-09-29 18:28:52 +00:00
jakman85 merged commit 20ea70d221 into main 2026-09-29 18:28:54 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Home-Network/home-network-k3s-impl#16