soft guideINFRASTRUCTURE & ADVISORY

Note 05

Testing admission policies both ways

Kyverno CEL policies with fixtures that must pass and fixtures that must fail, reported in development and enforced in production from the same files.

The failure nobody sees

An admission policy that blocks nothing looks exactly like one that works. A verb that does not exist, a check on a field an attacker controls, a match that never fires: all pass review, all are silent, and all are discovered during an incident.

Tested both ways

Every policy ships with fixtures that must be admitted and fixtures that must be rejected by that policy, by name. The test fails if a good fixture is rejected or a bad one gets through.

results:
  - { policy: require-approved-registries, resources: [good-app], kind: Deployment, result: pass }
  - { policy: require-approved-registries, resources: [bad-registry], kind: Deployment, result: fail }
  - { policy: restrict-load-balancers, resources: [bad-public-lb, bad-misspelled-ranges], kind: Service, result: fail }

What the policies cover

Pod Security Admission handles privileged pods, host access and capabilities natively. Kyverno, in CEL, adds what it does not: images only from the cell registry and signed by the release workflow, pinned versions, requests and memory limits, probes, read-only root filesystems, no default service account, internal load balancers unless exposure is approved, cluster-admin bound only by GitOps, and a namespace syncing only its own secrets.

One policy rejects a misspelled load balancer annotation. The controller ignores the misspelling and opens the load balancer to the internet while the manifest looks restricted. That kind of rule comes from incidents, and it is exactly the kind a test must prove.

Same files, two modes

The action comes from the cell: Audit in development, Deny in staging and production. Teams see violations in their dev cell before production rejects them. Exceptions exist, but each names an owner, a reason and an expiry date, and exempts a workload, never a namespace.

Start a conversation

Bring your infrastructure
into focus.

Tell me what you are building, operating, or trying to improve.

Let’s talk