cel-go
The Go implementation of the Common Expression Language for fast, safe, embeddable expression evaluation.
Repository Health
Technical Analysis
cel-go is Google’s Go implementation of the Common Expression Language (CEL), a small, non-Turing-complete expression language designed to be embedded inside larger applications. Rather than shipping a general-purpose scripting runtime, CEL gives host programs a narrow, sandboxed way to let users or operators supply logic at runtime — a permission check, a validation rule, a routing condition — without the security and performance risks of a full interpreter. Its C-like syntax reads naturally to anyone familiar with Go, Java, or TypeScript.
The library exposes a three-stage pipeline: parse an expression into an AST, optionally type-check it against declared variables and functions, then compile it into a reusable, thread-safe cel.Program that can be evaluated repeatedly against different inputs. This separation lets applications pay the parsing and type-checking cost once and evaluate cheaply and safely on every request. CEL is best known as the policy language embedded in Kubernetes (CRD validation rules, admission control), Envoy, and other cloud-native infrastructure where untrusted or operator-supplied conditions need to run with bounded, predictable cost.
What You Get
- A
cel.NewEnvbuilder for declaring the variables, types, and functions an expression is allowed to reference, keeping the evaluation surface explicit and auditable - A combined parse-and-check
Compilestep that catches syntax errors and type mismatches ahead of evaluation, with source-position-aware error messages - Stateless, thread-safe, cacheable
cel.Programobjects that can be evaluated concurrently against many different input activations - Built-in macros (
all,exists,exists_one,filter,map,has) for bounded iteration and field-presence checks without opening up arbitrary loops - First-class support for JSON and Protocol Buffer message types, so expressions can operate directly on structured request/response data
- An
extpackage of optional extensions (strings, math, sets, regex, encoders, bindings) that can be added to an environment only when needed
Common Use Cases
- Evaluating Kubernetes CustomResourceDefinition validation rules and admission-control conditions supplied by cluster operators
- Letting end users define custom alerting, routing, or filtering conditions in a product UI without giving them a real scripting language
- Expressing fine-grained authorization and access-control policies (e.g. “is this user’s claim group a prefix of this resource path”) evaluated per request
- Building policy-as-code systems where business rules are stored as data and evaluated safely against live request context
- Powering dynamic feature-flag and experiment targeting rules that product teams edit without deploying new Go code
Under The Hood
Architecture
cel-go is organized as a strict pipeline of independent packages: parser turns source text into an untyped AST (via a hand-written Pratt parser plus a generated ANTLR grammar for compatibility), checker walks that AST against declarations registered on a cel.Env to produce a type-annotated expression, and interpreter plans the checked AST into a tree of Interpretable nodes that cel/program.go wraps as a stateless, reusable Program. The top-level cel package is a thin façade over these three: Env.Compile fuses parse+check, Env.Program fuses plan+bind. Because each stage consumes the previous stage’s immutable output and produces a new immutable value, expressions can be parsed once and evaluated concurrently many times against different Activation inputs, which is what makes the library safe to expose on hot request paths. Extension functionality (in ext/) attaches purely through cel.EnvOption registration, so the core evaluator stays small unless a caller opts into string, math, or regex helpers.
Tech Stack
The module (cel.dev/cel-go, Go 1.23) depends on github.com/antlr4-go/antlr/v4 for its ANTLR-generated lexer/parser, google.golang.org/protobuf and google.golang.org/genproto/googleapis/api for native Protocol Buffer and well-known-type support, and cel.dev/expr for the shared CEL AST/proto definitions used across Google’s C++/Java/Go implementations. Build and release tooling is dual-tracked: a standard go.mod/go test path for library consumers, and Bazel (MODULE.bazel, BUILD.bazel files throughout) for the conformance suite and cross-platform REPL binary builds, with GitHub Actions driving tagged releases across linux/darwin/windows on amd64/arm64.
Code Quality
The repository is extensively tested — 124 _test.go files cover the parser, checker, interpreter, and every ext extension individually, plus a dedicated examples/ package of runnable Example... tests that double as documentation for common patterns (custom functions, custom macros, execution cost limits, protocol buffers). Error handling favors typed, source-position-aware error values (checker/errors.go, parser/errors.go) surfaced through Issues, rather than panics or silently swallowed failures. Naming is consistent with idiomatic Go conventions, exported types carry doc comments, and the shared conformance test suite (run against the canonical CEL spec) adds a correctness check beyond unit tests that most single-language expression libraries don’t have.
API Design
The public surface is deliberately small and composable: cel.NewEnv(opts...) takes functional options for variables, functions, and extensions, env.Compile returns an Ast plus Issues, and env.Program turns that into an Eval-able Program — three calls cover the entire integration for most use cases. Boilerplate is minimal for the common case (declare variables, compile, eval with a map[string]any) while still exposing lower-level ContextEval, ConcurrentEval, and cost-tracking options for callers with stricter operational requirements. Documentation is strong: a long, example-driven README, a hosted Codelab, and a examples/ package of self-contained Example... tests give newcomers multiple on-ramps beyond raw GoDoc.
Used by 6 apps in this directory
agentgateway
AI Development · Developer Tools
An open source AI-native proxy that secures, observes, and governs agent-to-LLM, agent-to-tool, and agent-to-agent communication through MCP, A2A, and unified LLM routing.
Authelia
Security · Authentication
OpenID Certified SSO and MFA portal for securing self-hosted web applications behind reverse proxies.
Bytebase
Devops
An open-source database CI/CD and DevSecOps platform — schema migration review, GitOps-driven changes, data masking, and access control across MySQL, PostgreSQL, Oracle, Snowflake, MongoDB, and more.
Caddy
Devops · Security
The only web server that obtains and renews TLS certificates automatically, with HTTP/1-2-3 support and zero dependency on external runtimes.
Hatchet
AI Development · Developer Tools · Automation
A Postgres-backed orchestration engine for background tasks, AI agents, and durable workflows that replaces Redis queues and multi-datastore durable execution platforms with a single self-hostable service.
memos
Note Taking
Open-source, self-hosted note-taking built for quick capture — Markdown-native, lightweight, and fully yours.