HackBlue

Tools · Containers and Kubernetes security · 18 / 20

Kubernetes policy as code with Kyverno: validate, mutate, and audit mode

Write Kyverno policies that require labels, disallow latest tags, and enforce resource limits, start in Audit mode, and read policy reports.

11 min read · practice only with authorization

Beyond Pod Security

Pod Security Admission covers a fixed set of pod controls. Organizations usually need more: approved registries, no latest tags, required ownership labels, limits on every container. Kyverno is a policy engine that runs as an admission webhook and expresses rules as Kubernetes resources. The built-in ValidatingAdmissionPolicy with CEL expressions and OPA Gatekeeper with Rego are alternatives.

A validate policy

validationFailureAction Audit records violations in PolicyReports without blocking. Enforce rejects. Start every new policy in Audit, review the reports, then switch to Enforce.

Snippet
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-and-require-limits
spec:
  validationFailureAction: Audit
  background: true
  rules:
    - name: no-latest-tag
      match: { any: [ { resources: { kinds: [Pod] } } ] }
      validate:
        message: Use a pinned image tag, not latest.
        pattern:
          spec:
            containers:
              - image: '!*:latest & *:*'
    - name: require-memory-limit
      match: { any: [ { resources: { kinds: [Pod] } } ] }
      validate:
        message: Memory limits are required.
        pattern:
          spec:
            containers:
              - resources: { limits: { memory: '?*' } }

Lab: audit, then enforce

Install Kyverno with Helm in a lab cluster, apply the policy in Audit mode, and create a pod using nginx:latest without limits. The pod runs, but kubectl get policyreport shows failures. Change the action to Enforce and try again: the API server returns the policy message and rejects the pod. Use the kyverno CLI to test manifests in CI before they reach the cluster.

Snippet
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
kubectl apply -f policy.yaml
kubectl run bad --image=nginx:latest
kubectl get policyreport -A
kyverno apply policy.yaml --resource pod.yaml

Mutation and generation

Kyverno can also mutate objects, for example adding a default securityContext, and generate objects, such as a default-deny NetworkPolicy in every new namespace. Use mutation sparingly and keep it visible, so teams are not surprised by changes they did not write.

Diagram

Audit versus Enforce

Roll out in two steps.

Audit

Violating pod. Admitted

Record. PolicyReport entry

Use. Measure impact before blocking

Enforce

Violating pod. Rejected with message

Record. Admission error and event

Use. After reports are clean

Check yourself

1. Which Kyverno validation action records violations but still admits the resource?

2. Where do you read Kyverno audit results?

3. Which is a built-in Kubernetes alternative for custom validation rules?