Add a policy to the baseline¶
Extend the Kyverno policy baseline the constitutional way: every rule ships with a violating manifest that CI must see rejected, and delivery is git-and-Argo only. A rule without a failing counter-example does not ship.
Preconditions¶
- A clone of the platform repository and
make. kubectlaccess for the on-cluster verification step.
Steps¶
1. Write the ClusterPolicy¶
Add one file per policy under deploy/policies/kyverno/<name>.yaml, with
the baseline enforcement posture (model it on an existing policy such as
registry-only-images.yaml):
spec:
validationFailureAction: Enforce # refuse at admission, not audit
background: true # scan pre-existing objects too
rules:
- name: …
2. Write the counter-example — CI requires it¶
Create deploy/policies/kyverno/tests/<policy-name>/ containing:
resources.yaml— at least one violating manifest and one compliant manifest;kyverno-test.yaml— acli.kyverno.io/v1alpha1Testdeclaring the compliant resourcespassand the violating onesfail;values.yamlif the rule matches on namespace labels (the CLI needs the label mapping to treat fixtures as in-scope).
make policy-check fails any ClusterPolicy that has no tests/<name>/
directory (SC-001). The single exemption is verify-attestation, whose
counter-example is proven live in CI against kind + Kyverno because a unit
fixture cannot verify cosign signatures.
3. Run the suite locally¶
This downloads the pinned Kyverno CLI (v1.18.2) to ./bin if it is not on
your PATH, runs kyverno test over the tests tree with detailed results,
and enforces the counter-example discipline. Fix failures before opening a
PR — the same check gates CI.
4. Deliver via git and Argo CD — never kubectl apply¶
Commit the policy and its tests, open a PR, merge. The tend-policies
Argo CD Application syncs deploy/policies recursively and excludes
tests/ and examples/, so CI-only fixtures never reach the cluster.
Hand-applied policies do not survive
The policy baseline is versioned and GitOps-delivered. The
tend-policies Application runs automated sync with prune and
self-heal, so a kubectl applyd policy is off-contract and will be
reverted. Change git, let Argo CD reconcile.
Verify it worked¶
Then check what the background scan found. Enforcement bites at the next admission — pre-existing violators are reported, not evicted:
Finally, prove the deny direction live: apply your violating manifest to a scoped namespace and confirm it is refused at admission with your rule named in the error.
Related pages¶
- Why the counter-example is mandatory, and why enforcement is contract-not-code: Governance model.
- The shipped baseline, rule by rule: the ClusterPolicies in
deploy/policies/kyverno/, each with the violating manifest that proves it. - Why one admission engine: ADR-0006.