CI parity with Conftest and opa eval
Catch violations before the cluster sees them.
In short. If admission is the only enforcement point, developers discover policy when their deploy fails at 5 p.m. CI parity means the same rules (or faithful equivalents) fail the pull request earlier.
If admission is the only enforcement point, developers discover policy when their deploy fails at 5 p.m. CI parity means the same rules (or faithful equivalents) fail the pull request earlier. Conftest runs Rego against YAML/JSON in pipelines; opa eval and opa test catch unit issues; some teams render Helm/Kustomize first so CI sees the same shapes the cluster will see.
Parity is not identical binaries — it is identical decisions. When CI allows what admission denies, trust collapses. Version policy bundles and pin them in both places.
Conftest in CI
conftest test --policy policy/ k8s/deployment.yamlecho exit=$?
FAIL - kubernetes/deployment.yaml - missing app labelexit=1
Avoiding false confidence
Scanning only incomplete manifests (unrendered Helm) creates false greens. Feed CI the rendered output. For Gatekeeper, extract Rego into a tested package Conftest can import. For Kyverno, use kyverno apply in CI where possible.
Going deeper
Cache policy bundles in CI to keep PR feedback fast, but verify checksums against the pinned version. Stale caches that silently miss new denies are dangerous.
Monorepos should run policy tests only on affected rendered packages when possible, plus a nightly full estate run. Correctness of the full run matters more than micro-optimizing PR minutes.
Publish human-readable failure annotations on PRs (GitHub checks) quoting the deny message. A red X without the registry allowlist hint just trains people to rerun.
Mutating policies complicate CI parity — rendered fixtures must include the post-mutate shape or CI will allow what the cluster mutates-then-validates differently. Prefer validating the post-mutation object in both places when mutate is in play.
For pull requests that only change application code without manifests, skip heavy renders but still run opa unit tests on the policy library itself when policy files change. Selective gates must never skip policy self-tests.
Publish a green/red sample repository that demonstrates passing and failing manifests for every critical rule. Onboarding goes faster when engineers can clone a known-good pattern.
Keep a changelog of policy bundle versions consumed by CI pins so rollbacks are a one-line revert, not an archaeology exercise.
Try this
Run conftest against a bad Deployment fixture and a good one; wire exit codes into a sample CI job script.
conftest test --policy policy/ fixtures/bad.yaml || echo blockedconftest test --policy policy/ fixtures/good.yaml && echo allowed
FAIL - …blockedPASSallowed
Takeaway
CI policy gates give the same answer earlier. Render real manifests, pin bundle versions, and keep one rule library behind both CI and admission.
Next: distribute those bundles across many clusters without snowflake YAML.