0002. Kyverno as the Kubernetes policy engine
- Status: Accepted
- Date: 2026-05-25
- Formalizes: D5
- Deciders: Sagar, SnowOps engineering
Context
The AKS baseline needs admission-time policy enforcement: block unsigned images, require resource limits, enforce non-root, mutate defaults, and generate per-namespace resources (network policies, quotas). The two mainstream options are Kyverno and OPA Gatekeeper. We already use OPA/Conftest for Terraform plan policy (D3/X3), so a naive instinct is to standardize on OPA everywhere.
Decision
We will use Kyverno as the Kubernetes policy engine, kept separate from the Terraform-plan OPA bundle.
- K8s policies live in
policy/kyverno/{rules,tests}; tested offline withkyverno test. - The same rules are reused by the GitOps bundle (F8/D24) via an ArgoCD Application
pointing at
policy/kyverno/rules— never forked. - OPA/Conftest remains the engine for
terraform plangating only.
Consequences
- Easier: policies are written as Kubernetes-native YAML — no Rego required for the K8s surface, lowering the barrier for validate/mutate/generate rules.
- Easier: Kyverno's
generateandmutatecover namespace-scaffolding use cases that Gatekeeper handles awkwardly. - Harder / accepted: two policy languages in the repo (Rego for TF plans, Kyverno YAML for K8s). We accept this because the two domains and their authors differ; a single language would force Rego onto the K8s surface where it adds friction.
Alternatives considered
- OPA Gatekeeper (unify on Rego): rejected — weaker mutate/generate story; Rego raises the authoring bar for cluster policies with no offsetting benefit.
- Pod Security Admission only: rejected — insufficient; no image-signature or custom-resource policy, no generation.
References
policy/kyverno/(D4, X4),gitops/(F8, D24)- Decision D5 in
docs/context/07-decisions.md