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

# Section Overview

> Using Kubernetes ValidatingAdmissionPolicy with CEL to reject invalid WebApp resources by enforcing image tag immutability and replica count limits before controllers reconcile.

Kubernetes operators focus on reconciliation: creating child objects, reporting status, emitting events, and cleaning up external state when a custom resource is deleted. Those reconciliation behaviors occur after a WebApp custom resource already exists in the API server—typically after you run:

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

Validating admission moves part of that safety boundary earlier, so Kubernetes can reject an invalid WebApp before it ever reaches the controller. The Kubernetes feature used here is ValidatingAdmissionPolicy: [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionpolicy](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionpolicy)

A validating admission policy executes during admission—the API server step that inspects create and update requests before persisting them. Policies are written with CEL (Common Expression Language) to evaluate expressions against the object in the incoming request. For a custom resource like WebApp, the API server can evaluate fields such as `spec.image` and `spec.replicas` before the controller ever sees the object.

If a CEL expression evaluates to true, the API server may allow the request to continue. If it evaluates to false and the associated binding enforces `deny`, the API server rejects the request and returns the policy's validation message.

<Frame>
  <img src="https://mintcdn.com/kodekloud-c4ac6d9a/_cG0RWHUHqfjYKx0/images/Kubernetes-Operators/Validation-Webhooks-And-CEL-Policies/Section-Overview/the-verdict-allow-deny-decision-process.jpg?fit=max&auto=format&n=_cG0RWHUHqfjYKx0&q=85&s=0e532028d691cbd942fd1a83e0fbe9b7" alt="The image illustrates a decision process titled &#x22;The Verdict: Allow or Deny,&#x22; where &#x22;CEL evaluates&#x22; requests. If true, the request continues; if false, the API server rejects the request." width="1920" height="1080" data-path="images/Kubernetes-Operators/Validation-Webhooks-And-CEL-Policies/Section-Overview/the-verdict-allow-deny-decision-process.jpg" />
</Frame>

A policy defines the validation logic, matching constraints, and the message returned on failure. A separate binding activates the policy and chooses the enforcement action and scope (namespaces, users, operations). This separation lets you stage policies in the cluster without affecting requests until a binding is applied.

For the WebApp API in this demo, we enforce two object-level checks using CEL:

* Images must not use the mutable `:latest` tag, because moving tags reduce repeatability and make rollouts unpredictable.
* Explicit replica counts must be within a supported range so extreme values are rejected before the controller begins reconciling.

Example CEL expressions for these checks:

```plaintext theme={null}
# Disallow images that end with ":latest"
!object.spec.image.endsWith(":latest")

# Ensure replicas are between 1 and 10 (inclusive)
object.spec.replicas >= 1 && object.spec.replicas <= 10
```

Summary of the rules enforced

| Check                      | Example CEL                                               | Rationale                                                         |
| -------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------- |
| Disallow moving image tags | `!object.spec.image.endsWith(":latest")`                  | Ensures reproducible deployments by forcing immutable tags.       |
| Replica count range        | `object.spec.replicas >= 1 && object.spec.replicas <= 10` | Prevents accidental scale-to-zero or unreasonably large replicas. |

This demo includes a ValidatingAdmissionPolicy and a matching ValidatingAdmissionPolicyBinding for these rules. You'll see two test cases: applying an invalid WebApp manifest (to observe rejection) and applying a valid manifest (to observe acceptance). The provided policy manifest uses placeholders so you can insert the CEL expressions and validate the API server behavior.

Example fragment in the policy manifest where you fill in CEL expressions:

```yaml theme={null}
validations:
  - expression: "<your CEL here>"
  - expression: "<your CEL here>"
```

<Callout icon="lightbulb" color="#1CB2FE">
  Policies and bindings are distinct: policies hold logic and messages, while bindings control scope and enforcement. This lets you stage validation rules in the cluster before applying them to requests.
</Callout>

References and further reading

* Validating Admission Policies: [https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionpolicy](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionpolicy)
* Common Expression Language (CEL): [https://opensource.google/docs/cel/](https://opensource.google/docs/cel/)

<CardGroup>
  <Card title="Watch Video" icon="video" cta="Learn more" href="https://learn.kodekloud.com/user/courses/kubernetes-operators/module/06ac03ac-518a-4bc6-b2f8-6ed63fcb26d5/lesson/4201bc54-9684-4c44-afda-8553eab1dd40" />
</CardGroup>
