- CEL is the standard language Kyverno uses for validation logic.
- Common built-in variables include
object,oldObject,namespaceObject, andrequest. - You can write
validate.celexpressions to block or allow admission requests.

1) Use parameter resources (params) to separate policy logic from environment configuration
Hard-coding environment-specific values inside policy expressions makes policies brittle and operationally expensive. For example, this simple enforce rule restricts Deployment replicas to fewer than 4:
params variable so you can keep logic in the policy and supply environment-specific configuration separately.
Refactor the previous rule to use a parameter resource:
- Adjust deployment limits by editing a single parameter resource — policy manifests remain unchanged.
- Use different parameter resources per namespace or environment and bind policies accordingly.
- You can use native Kubernetes resources (for example, a
ConfigMap) as the parameter resource as long as Kyverno can read it.
Parameter resources can be a custom resource or native types like
ConfigMap. Kyverno exposes the selected resource to CEL via the params variable so your policy logic remains environment-agnostic.2) Filter by content with CEL preconditions
match and exclude select resources by metadata (kinds, names, labels), but they are limited when you need to inspect nested fields. Use celPreconditions as a content-aware gate: they evaluate after match and before the main validate logic runs.
Goal: enforce that any Service of type NodePort must set externalTrafficPolicy: Local.
matchselects allServiceresources.celPreconditionsevaluates; only Services withobject.spec.type == 'NodePort'proceed to validation.- Services that are
ClusterIPorLoadBalancerwill skip the rule entirely (no error).
- Services that are
validate.celruns for resources that pass preconditions and enforces the required field.

3) Reduce repetition with variables to build reusable expressions
Complex policies often need to aggregate fields like all containers in a Pod spec (containers, initContainers, ephemeralContainers). Repeating the same aggregation in multiple expressions makes rules verbose and error-prone.
Example (repetitive, hard to read):
variables and reference it in expressions. This improves readability and maintainability.

variables:
- Single source of truth for the container aggregation logic.
- Validation expressions become concise and self-documenting.
- Changes (e.g., include/exclude ephemeral containers) require a single edit in
variables.
Quick reference: common CEL/Kyverno built-ins
Summary — Patterns to make CEL policies robust and maintainable

- Kyverno documentation: https://kyverno.io/documentation/
- CEL (Common Expression Language) spec: https://github.com/google/cel-spec
- Kubernetes admission control concepts: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
When using
paramKind with custom resources, ensure the referenced resource exists and Kyverno has permission to read it. A missing or inaccessible parameter resource will prevent the policy from evaluating as intended.params, celPreconditions, and variables you can author Kyverno CEL policies that are configurable, precise, and easy to maintain.