> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Supply Chain Guardrails with Kyverno

> Demonstrates Kyverno policies to validate, mutate, and generate Kubernetes resources with examples, audit mode, and PolicyReports for enforcing supply chain guardrails

[OPA Gatekeeper](https://open-policy-agent.github.io/gatekeeper/) is a powerful engine, but it requires learning the Rego policy language. [Kyverno](https://kyverno.io/) takes a different approach: policies are written in Kubernetes-native YAML, so teams can author policies without learning a new language. Kyverno supports three primary rule types in a single ClusterPolicy: validate, mutate, and generate.

Kyverno rule types:

* validate: allow or deny resources (enforce or audit)
* mutate: automatically modify resources (patch merge)
* generate: create resources in response to events (for example, when a Namespace is created)

Below we first confirm Kyverno is running, then demonstrate one example of each rule type (validate, mutate, generate). Finally, we show how to switch to audit mode and inspect PolicyReports.

## Verify Kyverno is running

List Kyverno pods to confirm the controllers and admission webhook are active:

```bash theme={null}
kubectl get pods -n kyverno
```

Example output:

```bash theme={null}
NAME                                           READY   STATUS    RESTARTS   AGE
kyverno-admission-controller-659d58644b-8bifb  1/1     Running   0          115m
kyverno-background-controller-778bffc669-ccw58 1/1     Running   0          115m
kyverno-cleanup-controller-8bfc4f578-cmqbj     1/1     Running   0          115m
kyverno-reports-controller-6c666d96-7xzq7      1/1     Running   0          115m
```

If the admission-controller Pod is not Running, Kyverno won't be able to validate or mutate requests.

## Quick reference: policy files and purposes

| File | Purpose |
| - | - |
| `validate-registry.yaml` | Validate that container images come from `docker.io` |
| `mutate-labels.yaml` | Mutate Pods in `team-dev` to add labels via strategic merge |
| `generate-netpol.yaml` | Generate a default-deny `NetworkPolicy` when a Namespace is created |

## 1) Validate rule (deny or audit)

This example enforces that Pod container images must originate from `docker.io`. The policy uses Kyverno's YAML `pattern` matching—no Rego required.

ClusterPolicy (`validate-registry.yaml`):

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-image-registries
spec:
  validationFailureAction: Enforce
  rules:
  - name: validate-registries
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "Image must be from docker.io"
      pattern:
        spec:
          containers:
          - image: "docker.io/*"
```

Apply the policy:

```bash theme={null}
kubectl apply -f validate-registry.yaml
```

Test the policy using an untrusted Pod that pulls from `quay.io` (test-pod-untrusted.yaml):

```yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  name: untrusted-pod
spec:
  containers:
  - name: app
    image: quay.io/prometheus/prometheus:latest
```

Attempt to create it in the `team-dev` namespace:

```bash theme={null}
kubectl apply -f test-pod-untrusted.yaml -n team-dev
```

Kyverno will block the request and return a validation error:

```bash theme={null}
Error from server: error when creating "test-pod-untrusted.yaml": admission webhook "validate.kyverno.svc-fail" denied the request:

resource Pod/team-dev/untrusted-pod was blocked due to the following policies

restrict-image-registries:
  validate-registries: 'validation error: Image must be from docker.io. rule validate-registries failed at path /spec/containers/0/image/'
```

Create a trusted Pod that uses `docker.io` (test-pod-trusted.yaml):

```yaml theme={null}
apiVersion: v1
kind: Pod
metadata:
  name: trusted-pod
spec:
  containers:
  - name: app
    image: docker.io/library/nginx
```

Apply it:

```bash theme={null}
kubectl apply -f test-pod-trusted.yaml -n team-dev
```

Result:

```bash theme={null}
pod/trusted-pod created
```

Note: Kyverno's `pattern` acts like a YAML overlay pattern. The wildcard `"docker.io/*"` ensures the image string begins with `docker.io/`.

## 2) Mutate rule (automatic changes)

Mutate rules can automatically patch resources as they are created or updated. This example injects labels into Pods created in the `team-dev` namespace using `patchStrategicMerge`.

ClusterPolicy (`mutate-labels.yaml`):

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-labels
spec:
  rules:
  - name: add-managed-by
    match:
      any:
      - resources:
          kinds:
          - Pod
          namespaces:
          - team-dev
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            managed-by: kyverno
            environment: dev
```

Apply the policy and create a pod to test the mutation:

```bash theme={null}
kubectl apply -f mutate-labels.yaml
kubectl run mutation-test --image=docker.io/library/nginx -n team-dev
```

Verify the Pod's labels:

```bash theme={null}
kubectl get pod -n team-dev mutation-test --show-labels
```

Example output:

```bash theme={null}
NAME            READY   STATUS    RESTARTS   AGE   LABELS
mutation-test   1/1     Running   0          17s   environment=dev,managed-by=kyverno,run=mutation-test
```

Kyverno injected `managed-by=kyverno` and `environment=dev` into the Pod metadata using a strategic merge patch.

Mutations modify resources as they are admitted. Choose the correct patch type (`patchStrategicMerge`, `patchJson6902`, or `overlay`) for the structure you target to avoid unintentional overwrites.

## 3) Generate rule (create resources automatically)

Generate rules create resources in response to events. This example automatically creates a default-deny `NetworkPolicy` when a Namespace is created.

ClusterPolicy (`generate-netpol.yaml`):

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-networkpolicy
spec:
  rules:
  - name: default-deny
    match:
      any:
      - resources:
          kinds:
          - Namespace
    generate:
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      name: default-deny
      namespace: "{{request.object.metadata.name}}"
      data:
        spec:
          podSelector: {}
          policyTypes:
          - Ingress
          - Egress
```

Note: The `namespace` field uses the Namespace name that triggered the rule via `{{request.object.metadata.name}}`.

Apply the generate policy and create a Namespace for testing:

```bash theme={null}
kubectl apply -f generate-netpol.yaml
kubectl create namespace auto-np-test
```

Verify the NetworkPolicy in the new namespace:

```bash theme={null}
kubectl get netpol -n auto-np-test
```

Example output:

```bash theme={null}
NAME           POD-SELECTOR   AGE
default-deny   <none>         11s
```

Kyverno created the `default-deny` `NetworkPolicy` inside `auto-np-test` automatically when the Namespace was created.

## Audit mode and PolicyReports

Kyverno supports an audit mode similar to Gatekeeper's dry-run. Set a policy's `validationFailureAction` to `Audit` to record violations without blocking resource creation.

Patch the existing `restrict-image-registries` policy to audit mode:

```bash theme={null}
kubectl patch clusterpolicy restrict-image-registries \
  --type=merge \
  -p '{"spec":{"validationFailureAction":"Audit"}}'
```

Now apply the previously failing untrusted pod:

```bash theme={null}
kubectl apply -f test-pod-untrusted.yaml -n team-dev
```

The pod will be admitted, but Kyverno records the violation in PolicyReports. List PolicyReports in the namespace:

```bash theme={null}
kubectl get policyreport -n team-dev
```

Example output:

```bash theme={null}
NAME                                   KIND  NAME           PASS  FAIL  WARN  ERROR  SKIP  AGE
579d07e7-7422-4c99-9147-8e7c5845106c   Pod   untrusted-pod  1     1     0     0      0     0s
5e1854a7-8f50-44ba-a72a-49cbc9a5f6e8   Pod   trusted-pod    1     0     0     0      0     7m9s
7b668dcf-ca90-4ee0-8d7e-b21cf6ba9881   Pod   mutation-test  2     0     0     0      0     4m19s
```

Describe a PolicyReport to inspect individual results (replace the name and namespace as needed):

```bash theme={null}
kubectl describe policyreport 579d07e7-7422-4c99-9147-8e7c5845106c -n team-dev
```

Use audit mode when you want to evaluate policy impact before enforcing them. PolicyReports provide a searchable, reviewable record of policy evaluations.

## Summary and best practices

* Kyverno uses Kubernetes-native YAML and supports three rule types: validate, mutate, and generate.
* validate enforces or audits resource compliance (set `validationFailureAction` to `Enforce` or `Audit`).
* mutate modifies resources using patches (use the appropriate patch type for your target).
* generate creates resources in response to events (e.g., create a default-deny `NetworkPolicy` when a Namespace is created).
* Use audit mode and PolicyReports to assess impact and reduce blast radius before switching policies to `Enforce`.

## Links and references

* Kyverno project: [https://kyverno.io/](https://kyverno.io/)
* Kyverno PolicyReports: [https://kyverno.io/docs/usage/policy-reports/](https://kyverno.io/docs/usage/policy-reports/)
* OPA Gatekeeper: [https://open-policy-agent.github.io/gatekeeper/](https://open-policy-agent.github.io/gatekeeper/)
* Rego policy language: [https://www.openpolicyagent.org/docs/latest/policy-language/](https://www.openpolicyagent.org/docs/latest/policy-language/)

> **[Watch Video](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/a82e67a7-e75e-4ef0-be81-4862c665ef4f)**

> **[Practice Lab](https://learn.kodekloud.com/user/courses/prep-course-certified-cloud-native-platform-engineer-cnpe/module/35a7fadb-02d8-4557-a819-2e4dcfa970cc/lesson/11c61a43-720a-4ba7-b400-2bc8580dfd1f)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.