Recent Posts
Archives

Posts Tagged ‘CEL’

PostHeaderIcon [DevoxxFR2026] Common Expression Language (CEL): A Fast, Portable, and Secure Expression Language for Modern Applications

Lecturer

Alex Snaps is a Tech Lead at Red Hat working on the Quarkus project. He maintains the Rust implementation of CEL and contributes to the broader ecosystem, bringing deep expertise in language runtimes, performance, and secure extensibility.

Abstract

Alex Snaps introduces the Common Expression Language (CEL), a domain-agnostic expression language designed for safe, high-performance evaluation within larger applications. Originating from Google, CEL emphasizes strong typing, sandboxed execution, and extensibility while maintaining portability across implementations in Go, Java, C++, Rust, and others. Through syntax exploration, type checking, cost estimation, and practical integration examples, the talk demonstrates why CEL excels for policy enforcement, validation, filtering, and authorization in cloud-native and API-driven environments.

Origins and Design Philosophy of CEL

CEL emerged from Google’s need for a lightweight, embeddable expression evaluator capable of running safely in performance-critical paths. First released around 2017 (with earlier internal variants), it targets scenarios where user-provided or configuration-driven logic must execute with predictable latency and strict safety guarantees. Unlike general-purpose scripting languages, CEL deliberately restricts Turing-completeness to prevent denial-of-service through infinite loops or excessive computation.

Core tenets include:

  • Strong Static Typing: All expressions are type-checked before evaluation.
  • Predictable Performance: Cost estimation and constant folding occur at check time.
  • Portability: Abstract Syntax Tree (AST) format enables cross-language evaluation.
  • Extensibility: Custom functions, macros, and types can be added per domain.

These properties make CEL ideal for Kubernetes (Custom Resource Definition validation), API gateways, authorization systems, and configuration engines.

Syntax and Core Language Features

CEL syntax resembles a blend of C-style expressions and modern collection comprehensions. Basic operations, conditionals, and field access feel familiar:

  • Arithmetic and comparisons
  • Logical operators
  • Ternary expressions
  • Optional chaining with ? and or
  • Collection operations via macros like exists, all, map

Notable features include:

  • Macros: all(resources, r, r.startsWith('email')) binds variables and applies predicates.
  • Optional Navigation: obj.?field.or(0) safely accesses potentially absent fields.
  • Message Construction: Direct construction of Protocol Buffer messages within expressions.
  • Strict Typing: No implicit coercion; uint(1) == 1 fails type checking.

The language integrates seamlessly with Protocol Buffers, treating well-known types like timestamps and durations as first-class citizens.

The Evaluation Pipeline: Parse, Check, Evaluate

CEL processing follows a clear separation optimized for control-plane versus data-plane workloads:

  1. Parse: Validates syntax and produces an AST. Feature flags can disable risky syntax (e.g., optional navigation).
  2. Check: Performs type resolution, overload selection, constant folding, and cost estimation. This phase catches errors early and enables optimization.
  3. Evaluate: Executes the (potentially optimized) AST against a bound environment in the hot path.

Environments declare variables and functions available to expressions. Cost limits prevent expensive evaluations in production.

Portability shines here: an AST checked in one language can be evaluated in another, facilitating polyglot systems.

Extensibility and Real-World Integration

CEL’s power emerges through domain-specific extensions. Custom functions, member overloads, and macros allow tailoring to specific needs without compromising safety.

In the Quarkus/Gateway API context, CEL evaluates policies attached to Kubernetes resources. Expressions navigate complex object graphs, enforce authorization, and implement fine-grained controls. The Rust implementation (maintained by Snaps) demonstrates low-level integration, including trait-based value handling and flexible indexing.

Examples illustrate adding domain functions like isPrime or complex policy logic matching gateways and routes.

Performance, Security, and Ecosystem Maturity

CEL achieves high performance through ahead-of-time type checking, constant folding, and minimal runtime overhead. Implementations in Go and Java (reference) are mature; Rust and others continue evolving toward full specification compliance.

Security model emphasizes sandboxing: no arbitrary code execution, bounded computation, and explicit environment control. This makes CEL suitable for untrusted user input in API filters, validation rules, and authorization decisions.

The ecosystem includes playgrounds, conformance test suites, and codelabs across languages, lowering the barrier to adoption.

Conclusion

Common Expression Language offers a compelling balance of expressiveness, safety, and speed for embedding dynamic logic in applications. Its strong typing, cost awareness, and extensibility address real challenges in cloud-native policy and configuration management. As organizations seek safer alternatives to full scripting engines, CEL provides a mature, battle-tested solution that continues gaining traction across diverse technology stacks.

Links: