Skip to content

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.
  • kubectl access 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 — a cli.kyverno.io/v1alpha1 Test declaring the compliant resources pass and the violating ones fail;
  • values.yaml if 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

make policy-check

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

kubectl get clusterpolicy <name>          # present and Ready after the sync

Then check what the background scan found. Enforcement bites at the next admission — pre-existing violators are reported, not evicted:

kubectl get policyreport -A | grep <name>

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.

  • 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.