Kubernetes now embeds the Common Expression Language (CEL) into its API server. Developers can declare validation rules and policy logic directly in CustomResourceDefinitions (CRDs). This approach removes the need for external webhooks and improves API reliability and performance.
TL;DR
- Kubernetes CEL runs expressions in the API server process for validations and policy enforcement.
- CEL uses familiar C-style syntax with static typing, short-circuit logic and safe built-ins.
- CRDs accept CEL through
x-kubernetes-validations
inopenAPIV3Schema
. - Engine enforces limits on source length, compile time and evaluation steps.
- CEL reduces reliance on external admission webhooks and cuts latency.
- Users must consider security contexts, sandbox restrictions and upgrade paths.
Overview of Kubernetes CEL
Kubernetes integrates the Common Expression Language (CEL) directly into its API server. CEL functions like a micro-policy engine. It runs inside the kube-apiserver process. This design avoids network hops to webhook services. It ensures validation and mutation logic remain available as long as control-plane pods run. Kubernetes CEL supports validation.XPath-style paths into resource fields and type checking at compile time.
Why Use CEL in Kubernetes
Deployers often rely on validating and mutating admission webhooks for policy enforcement. Webhooks add network dependencies and complexity. Kubernetes CEL offers a simpler path. You write CEL expressions instead of Go or external services. The API server compiles and caches expressions. It executes them on each admission request. This model reduces latency and operational overhead while maintaining strong safety guarantees.
Kubernetes CEL Syntax and Semantics
CEL syntax resembles C, Java and JavaScript. It supports literals, operators, functions and comprehensions. CEL enforces static types on field access and function calls. It rejects ill-typed expressions at compile time. Expressions support:
- Arithmetic:
+
,-
,*
,/
. - Logical:
&&
,||
,!
. - Comparison:
==
,!=
,<
,>
,<=
,>=
. - Field navigation:
self.spec.count
. - Comprehensions:
list.exists(x, x > 5)
.
CEL limits its function set to safe operations. It omits file I/O, network calls and reflection. The engine sandbox prevents resource exhaustion.
Defining CEL Expressions in CRDs
You add CEL rules under the validation.openAPIV3Schema.x-kubernetes-validations
field in a CRD spec. Each rule includes a rule
string and a message
for failures. Kubernetes compiles these rules at CRD installation time. Example:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: widgets.example.com
spec:
group: example.com
names:
kind: Widget
plural: widgets
scope: Namespaced
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
ports:
type: array
items:
type: integer
x-kubernetes-validations:
- rule: "size(self.spec.ports) <= 5"
message: "You can specify at most five ports"
The API server rejects creations and updates if any CEL rule evaluates to false.
Validating Resources with CEL
Kubernetes uses CEL to validate built-in and custom resources. You can target fields or whole objects. CEL supports cross-field checks and conditional logic. For example, ensure spec.replicas
stays within bounds:
x-kubernetes-validations:
- rule: "self.spec.replicas >= 1 && self.spec.replicas <= 10"
message: "Replicas must be 1-10"
At admission time, the API server binds self
to the incoming object. It compiles CEL to an abstract syntax tree and executes it under a timeout. If execution fails or times out, the request fails.
Limits and Behaviour of Kubernetes CEL
The CEL integration enforces safe limits to prevent denial-of-service. Key limits include:
- Max source length: 512 bytes of CEL code.
- Max compile duration: 10ms.
- Max evaluation steps: 1,000 iterations.
- Disabled host functions: no file I/O, no networking.
If a rule exceeds any limit, the API server rejects the CRD registration or fails the admission request. Administrators can adjust these defaults via --validation-max-duration
and related flags on the API server.
Security and Performance Considerations
Embedding CEL in the API server reduces attack surface by avoiding external webhooks. CEL expressions operate in a sandbox. They cannot escape the process or access unintended resources. However, complex expressions may degrade API server performance. Follow best practices:
- Keep rules simple and focused on key fields.
- Avoid nested comprehensions on large arrays.
- Test rule performance under realistic load.
- Monitor API server latency metrics.
You can still use dynamic policy frameworks like OPA Gatekeeper for richer logic. Use CEL for straightforward validations and metrics.
Example Workflow: CEL Policy Enforcement
This diagram shows how CEL rules run during resource admission:

In this flow, the API server caches compiled CEL ASTs per CRD version. It invokes evaluation on each create/update. The result determines admission.
References
- Common Expression Language in Kubernetes
- Extend the Kubernetes API with CustomResourceDefinitions – Validations
Suggested Reading
PostHashID: 9fd5600f7b785c04923a13799adc6996db31fef9a5e0872392425d702a0fcf01