πŸ•ΈοΈ Ada Research Browser

kyverno-patterns.md
← Back

Kyverno Policy Patterns for SRE

Read this before creating or modifying anything in policies/.

Directory Structure

policies/
β”œβ”€β”€ baseline/              # Pod Security Standards baseline (applied cluster-wide)
β”‚   β”œβ”€β”€ disallow-privileged.yaml
β”‚   β”œβ”€β”€ disallow-host-namespaces.yaml
β”‚   β”œβ”€β”€ disallow-host-ports.yaml
β”‚   └── restrict-sysctls.yaml
β”œβ”€β”€ restricted/            # Pod Security Standards restricted (applied to tenant namespaces)
β”‚   β”œβ”€β”€ require-run-as-nonroot.yaml
β”‚   β”œβ”€β”€ require-drop-all-capabilities.yaml
β”‚   β”œβ”€β”€ restrict-volume-types.yaml
β”‚   └── disallow-privilege-escalation.yaml
β”œβ”€β”€ custom/                # SRE-specific policies
β”‚   β”œβ”€β”€ require-labels.yaml
β”‚   β”œβ”€β”€ require-resource-limits.yaml
β”‚   β”œβ”€β”€ restrict-image-registries.yaml
β”‚   β”œβ”€β”€ verify-image-signatures.yaml
β”‚   β”œβ”€β”€ disallow-default-namespace.yaml
β”‚   β”œβ”€β”€ disallow-latest-tag.yaml
β”‚   β”œβ”€β”€ require-network-policies.yaml
β”‚   └── require-probes.yaml
└── tests/                 # Test cases for every policy
    β”œβ”€β”€ require-labels/
    β”‚   β”œβ”€β”€ policy.yaml
    β”‚   β”œβ”€β”€ resource-pass.yaml
    β”‚   β”œβ”€β”€ resource-fail.yaml
    β”‚   └── kyverno-test.yaml
    └── ...

Policy Template

Every policy follows this structure:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: <descriptive-kebab-case-name>
  labels:
    app.kubernetes.io/part-of: sre-platform
    sre.io/policy-category: <baseline|restricted|custom>
  annotations:
    policies.kyverno.io/title: <Human Readable Title>
    policies.kyverno.io/description: >-
      Brief description of what this policy enforces and why.
    policies.kyverno.io/category: <Pod Security Standards Baseline|Best Practices|Supply Chain>
    policies.kyverno.io/severity: <critical|high|medium|low>
    sre.io/nist-controls: "AC-6, CM-7"  # Map to NIST 800-53 control IDs
spec:
  validationFailureAction: Enforce    # Use Audit in dev environments
  background: true
  rules:
    - name: <rule-name>
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Clear message explaining why this was denied and how to fix it."
        pattern:
          spec:
            # ... validation pattern

Key Design Rules

Image Verification with Cosign

This is a critical supply chain security policy:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
  annotations:
    sre.io/nist-controls: "SA-10, SI-7"
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "harbor.sre.internal/*"
          attestors:
            - entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      REPLACE_ME_WITH_COSIGN_PUBLIC_KEY
                      -----END PUBLIC KEY-----

Mutation Policies

Use mutation for injecting defaults, not for security enforcement:

spec:
  rules:
    - name: add-default-labels
      match:
        any:
          - resources:
              kinds:
                - Pod
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              sre.io/managed: "true"

Writing Tests

EVERY policy MUST have tests. No exceptions.

Test directory structure

policies/tests/<policy-name>/
β”œβ”€β”€ policy.yaml          # Copy of the policy (or symlink)
β”œβ”€β”€ resource-pass.yaml   # Resource that SHOULD be allowed
β”œβ”€β”€ resource-fail.yaml   # Resource that SHOULD be denied
└── kyverno-test.yaml    # Test definition

kyverno-test.yaml template

apiVersion: cli.kyverno.io/v1alpha1
kind: Test
metadata:
  name: <policy-name>-test
policies:
  - policy.yaml
resources:
  - resource-pass.yaml
  - resource-fail.yaml
results:
  - policy: <policy-name>
    rule: <rule-name>
    resource: <passing-resource-name>
    kind: Pod
    result: pass
  - policy: <policy-name>
    rule: <rule-name>
    resource: <failing-resource-name>
    kind: Pod
    result: fail

Running tests

# Test a single policy
kyverno test policies/tests/<policy-name>/

# Test all policies
kyverno test policies/tests/

# Also run via task
task validate

Kyverno Reporter

Kyverno Reporter sends policy violation metrics to Prometheus. It is deployed alongside Kyverno and integrated with Grafana dashboards.

Policy reports are queryable:

kubectl get policyreport -A          # Namespace-scoped reports
kubectl get clusterpolicyreport      # Cluster-scoped reports

Common Mistakes