> ## 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.

# Pod Security Exemptions

> Explains creating narrow Kyverno PolicyException to exempt specific Pod Security Standard controls for targeted workloads without weakening central policies

Previously we covered why and how policy exceptions are used. In this lesson we apply that knowledge to a concrete and common scenario: a critical monitoring agent must run as root, but the cluster enforces the Kubernetes Pod Security Standards (PSS) at the `restricted` level and blocks that behavior. Rather than weakening the central policy, we'll create a narrow, auditable exception that allows only the specific workload to run as root.

Scenario recap

* Alice runs a ClusterPolicy that enforces the official Kubernetes Pod Security Standards at the `restricted` level.
* One control in that profile—`Running as Non-root`—prevents containers from running as root.
* Alex needs a monitoring agent to run as root in a specific namespace (`delta`).
* Goal: create a scoped exception that targets only that control for the targeted workload(s) without modifying the global policy.

Cluster-level policy enforcing PSS (example)

```yaml theme={null}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: psa
spec:
  rules:
    - name: restricted
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        failureAction: Enforce
        podSecurity:
          level: restricted
          version: latest
```

Why the Block Occurs

* The `restricted` profile includes a `Running as Non-root` control.
* Any Pod that tries to run containers as root will be rejected by this policy.
* We do not want to disable the control cluster-wide; we want a narrowly scoped exception.

Minimal PolicyException that targets a single PSS control

```yaml theme={null}
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
  name: delta-pss-exception
  namespace: policy-exception-ns
spec:
  exceptions:
    - policyName: psa
      ruleNames:
        - restricted
  match:
    any:
      - resources:
          namespaces:
            - delta
  # The new part:
  podSecurity:
    controlName: "Running as Non-root"
```

How this PolicyException works

* `match` selects resources in the `delta` namespace.
* `spec.exceptions` points to the `psa` policy and its `restricted` rule.
* `podSecurity.controlName` instructs Kyverno to ignore only the `Running as Non-root` control for the matched scope.
* Effect: only the specified control is ignored for resources in `delta`; the rest of the `restricted` profile still applies.

<Callout icon="lightbulb" color="#1CB2FE">
  The `podSecurity` block in a PolicyException mirrors the `exclude` block you can add inside a `podSecurity` rule. This makes exceptions expressive and predictable, and easier to reason about when auditing policy changes.
</Callout>

Policy modification vs scoped exception

* Policy modification (not recommended for scoped needs)
  * Adding an `exclude` to the policy weakens enforcement for every resource matched by that policy.
  * Changes apply cluster-wide (or to all resources matched by the policy) and affect all teams.

* PolicyException (recommended)
  * Keeps the central policy intact.
  * Provides an auditable, separate object that grants a narrow allowance for a specific scope (namespace, image, etc.).
  * Supports separation of duties and easier review / rollback.

Comparison table

| Action                               | Scope                                    | Auditable                       | Use when                                                                  |
| ------------------------------------ | ---------------------------------------- | ------------------------------- | ------------------------------------------------------------------------- |
| Modify central policy with `exclude` | Cluster-wide or policy-matched resources | No (changes directly to policy) | You must permanently change enforcement for all matched resources         |
| Create `PolicyException`             | Narrow (namespace, images, labels, etc.) | Yes (exception object)          | A temporary or scoped allowance is needed for a specific workload or team |

Example of weakening the policy (not recommended if you only need a scoped exception)

```yaml theme={null}
# This makes the central policy weaker for all matched resources
clusterpolicy:
  validate:
    podSecurity:
      level: restricted
      version: latest
      exclude:
        - controlName: "Running as Non-root"
```

Equivalent scoped exception (preferred)

```yaml theme={null}
# This leaves the central policy intact and creates a scoped exception
exception:
  spec:
    exceptions:
      - policyName: psa
        ruleNames:
          - restricted
        podSecurity:
          controlName: "Running as Non-root"
```

Granular, container-level exceptions
Some PSS controls apply to the Pod as a whole (for example, `hostPath` restrictions). Others operate at the container level (for example, `Capabilities`). When a control applies to containers, Kyverno supports finer-grained exceptions using an `images` field so you can target only the containers that need the exemption.

Policy-level `exclude` example (applies at policy authoring time)

```yaml theme={null}
validate:
  podSecurity:
    level: restricted
    version: latest
    exclude:
      - controlName: Capabilities
        images:
          - nginx*
          - redis
```

Scoped PolicyException (recommended approach)

```yaml theme={null}
spec:
  exceptions:
    - policyName: psa
      ruleNames:
        - restricted
  match:
    any:
      - resources:
          namespaces:
            - delta
  podSecurity:
    controlName: Capabilities
    images:
      - nginx*
      - redis
```

Behavior notes

* With this exception, only containers whose image matches `nginx*` or `redis` will be exempted from the `Capabilities` control.
* Other containers in the same Pod (for example, an Ubuntu-based sidecar) still must comply with the `Capabilities` control.
* Use image patterns carefully to avoid accidentally broadening the exception.

<Callout icon="warning" color="#FF6B6B">
  Keep exceptions as narrow, well-documented, and time-limited as possible. Exceptions expand risk when left open or when they are overly broad (for example, matching many image names or many namespaces).
</Callout>

Best practices and recap

* Prefer PolicyException to modifying a central PodSecurity rule when you need a scoped exemption.
* Use `controlName` for pod-wide exemptions (e.g., `Running as Non-root`).
* For container-level controls, add `images` to target only specific images and avoid exempting sidecars or unrelated containers.
* Make exceptions:
  * Narrow in scope (namespace, image, label selector).
  * Audited and documented (reason, owner, expiration).
  * Temporary when possible; review regularly.
* Document the business or technical reason for each exception and record its owner and planned removal date.

References and further reading

* [Kyverno PolicyException docs](https://kyverno.io/docs/writing-policies/policy-exception/)
* [Kubernetes Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/)
* [Kyverno Pod Security support](https://kyverno.io/docs/writing-policies/policy-exception/#pod-security)

That concludes this lesson on creating Pod Security exceptions with Kyverno.

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kyverno-certified-associate/module/26478d8e-69b0-4b48-bc9a-173ba8b28d7b/lesson/890acc40-3bb3-48e1-a455-1a44633dc0ba" />
</CardGroup>
