Skip to content

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 with kyverno 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 plan gating 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 generate and mutate cover 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