Common Expression Language -- specification and binary representation


Common Expression Language

Build Status

The Common Expression Language (CEL) implements common semantics for expression evaluation, enabling different applications to more easily interoperate.

Key Applications

  • Security policy: organization have complex infrastructure and need common tooling to reason about the system as a whole
  • Protocols: expressions are a useful data type and require interoperability across programming languages and platforms.

Guiding philosophy:

  1. Keep it small & fast.
    • CEL evaluates in linear time, is mutation free, and not Turing-complete. This limitation is a feature of the language design, which allows the implementation to evaluate orders of magnitude faster than equivalently sandboxed JavaScript.
  2. Make it extensible.
    • CEL is designed to be embedded in applications, and allows for extensibility via its context which allows for functions and data to be provided by the software that embeds it.
  3. Developer-friendly.
    • The language is approachable to developers. The initial spec was based on the experience of developing Firebase Rules and usability testing many prior iterations.
    • The library itself and accompanying toolings should be easy to adopt by teams that seek to integrate CEL into their platforms.

The required components of a system that supports CEL are:

  • The textual representation of an expression as written by a developer. It is of similar syntax to expressions in C/C++/Java/JavaScript
  • A binary representation of an expression. It is an abstract syntax tree (AST).
  • A compiler library that converts the textual representation to the binary representation. This can be done ahead of time (in the control plane) or just before evaluation (in the data plane).
  • A context containing one or more typed variables, often protobuf messages. Most use-cases will use attribute_context.proto
  • An evaluator library that takes the binary format in the context and produces a result, usually a Boolean.

Example of boolean conditions and object construction:

// Condition
account.balance >= transaction.withdrawal
    || (account.overdraftProtection
    && account.overdraftLimit >= transaction.withdrawal  - account.balance)

// Object construction
common.GeoPoint{ latitude: 10.0, longitude: -5.5 }

For more detail, see:

A dashboard that shows results of conformance tests on current CEL implementations can be found here.

Released under the Apache License.

Disclaimer: This is not an official Google product.

  • Heterogeneous equality

    Heterogeneous equality

    Since [1, "foo"] is a valid list and _==_ is defined on lists, [1, "foo"] == ["foo", 1] should evaluate to false. It would be least surprising if list equality was determined by elementwise equality. Equivalently, [x] == [y] should have the same meaning as x == y. Therefore, _==_ should have signature A x B --> bool.

    Similarly, _!=_ should work on heterogeneous types.

    Restricting equality to homogeneous types was meant to prevent user errors. After all, heterogeneously 1 == 1u evaluates surprisingly to false. However the type checker can work with a stricter A x A --> bool signature for equality, catching these errors.

    We might want to make heterogeneous order operators (_<_ and friends) too. We'll want an ordering across all values for deterministic map comprehensions, so why not expose it to users? The surprising consequences (e.g. if int < uint, then 1u < 2) can again be mitigated by having the type checker work heterogeneously.

    opened by JimLarson 16
  • Clarify how self_eval_int_negative_min test will be passed

    Clarify how self_eval_int_negative_min test will be passed

    It seems like the literal value in the expression -9223372036854775808 is outside the range of positive values. It's not clear this int64 object can exist as a CEL Value before the negation function (-_) is applied to it.

    This seems like this should be a range error creating the initial integer value.

    If it's not an immediate range error, this seems to imply the range check is deferred until the final value is returned. If negation is allowed on out-of-range int64 values, how much other computation can occur on out-of-range values?

    opened by slott56 7
  • String.size() definition is ambiguous

    String.size() definition is ambiguous

    Standard Definitions states that string.size() should be the string length - but is it the number of UTF8 bytes or the number of unicode code points?

    It's a bit confusing because values states that String is Strings of UTF-8 code points but later is defined as sequences of Unicode code points.. Should strings be treated as UTF-8 bytes or Unicode code points? I'd like to hope that it's Unicode code points, but the golang implementation uses Go's len() function which usually is UTF-8 bytes (demo) but are really just arbitrary byte containers, check out this blog post and this stack overflow post for details about golang. C++ is the same WRT to string encodings, but I couldn't find the size() function in my quick looking.

    /cc @TristonianJones @ryanpbrewster

    opened by rockwotj 6
  • Packing conformance test structures instead

    Packing conformance test structures instead

    The conformance tests send very deeply nested structures to test the depth 32 required by the spec. For some cases, this unfortunately causes Java gRPC to run in to parsing stack limits. A suggestion would be to pack values into an Any instead for conformance, to make life easier for gRPC implementations with such limits (C# is the same for example, as I understand it).

    opened by jsannemo 5
  • Add notation and/or constructors for durations in days, hours, or minutes

    Add notation and/or constructors for durations in days, hours, or minutes

    The current duration constructor takes only a decimal string with a number of seconds, e.g. duration("5184000s"). There is desire for more handy units, e.g. duration("60d"). (Assuming we ignore leap seconds.)

    The underlying protobuf well-known type goes down to nanoseconds, so we could potentially have "ms", "µs", and "ns" too.

    A week is unambiguous, but month, quarter, year, etc. seem error-prone.

    We could go full ISO 8601 and allow durations like "2h30m45s", but it's easy enough to compose them with addition: duration("2h") + duration("30m") + duration("45s"), although it's clunkier.

    We could alternatively have separate constructors, e.g. hours(7), maybe in an extension library.

    opened by JimLarson 5
  • configurations support for the CEL?

    configurations support for the CEL?

    Hi experts,

    CEL is great, we are moving some server functions to cel. We have some functions depending on the user environment configuration.
    The function behavior and output depend on some user conf.

    in a runtime application, we can have a configuration for the app, the applications can read this conf at start time.

    and for the CEL, if there is any way to do the same thing? thanks.

    opened by wzhanw 4
  • Syntax: has with map keys

    Syntax: has with map keys

    CEL treats map lookups and field dereferences similarly in many ways, except for has() macro. In some cases, we have to use bracket notation because the key has illegal ident characters. This prevents the use of has macro in such keys. For example:


    Because headers use dashes, we cannot use field notation.

    The workaround is using in operator, but I wonder if permitting has(a[f]) would be better.

    opened by kyessenov 4
  • Fix map comparison and make fixed tests live.

    Fix map comparison and make fixed tests live.

    This PR closes by fixing map comparisons in the conformance driver.

    Additionally, this PR moves the broken tests fixed by this change and by from broken.textproto to basic.textproto

    opened by TristonianJones 4
  • Conformance test driver

    Conformance test driver

    Driver for conformance tests.

    CEL implementations will write a server for the ConformanceService. Here in the cel-spec repository we have the conformance tests themselves as data files plus a ConformanceService client which interprets the files and talks to the implementation-dependent server. An example will be given in cel-go for how to set this up as a bazel test for the implementation.

    opened by JimLarson 4
  • Suggestion: Become a subset of ECMAScript

    Suggestion: Become a subset of ECMAScript

    I'm sorry, this is just feedback, since the Issues feature is disabled I created a dummy PR instead to put this.

    I was looking for a cross-language expression language and CEL seems to be a great match.

    I noticed that it borrows some JavaScript/ECMAScript-like syntax but not always. For example: Account{name: "Eamonn"}.

    I was wondering if CEL's syntax can be a subset of ECMAScript, while remaining specific to its restricted use case of expression language. For example, Account{name: "Eamonn"} may become new Account({name: "Eamonn"}) which would be a valid ES syntax, while (I think) not making it harder for CEL parser.

    A nice benefit is that any ECMAScript parser can be used to parse CEL, even if not explicitly supported. For example I'm looking for an EL that is implemented in Python, and either @Kronuz's or @jeffkistler's would work well here, even if cel-python is not yet developed.

    BTW I submitted a Wikipedia article on CEL:

    Thank you!

    opened by ceefour 4
  • Semantics 0.1.0

    Semantics 0.1.0

    Big overhaul of language definition to:

    • incorporate clarifications from semantics effort for which we have language council consensus;
    • rearrange presentation for better flow;
    • expand discussions in several places;
    • convert to Github-flavored markdown.
    opened by JimLarson 4
  • Fix `Member`/`Primary` BNF for messages

    Fix `Member`/`Primary` BNF for messages

    Messages can't start with anything other than simple or qualified names.

    a message by M{f1: e1, f2: e2, ..., fN: eN}, where M must be a simple or qualified name which resolves to a message type (see Name Resolution)

    Name Resolution

    ... Resolution works as follows. If a.b is a name to be resolved in the context of a protobuf declaration with scope A.B, then resolution is attempted, in order, as A.B.a.b, A.a.b, and finally a.b. To override this behavior, one can use .a.b; this name will only be attempted to be resolved in the root scope, i.e. as a.b.

    Also messages are a valid Primary for Member expressions.

    A field selection expression, e.f, can be applied both to messages and to maps

    opened by Daniel-Bloom-dfinity 0
  • CEL spec is too protobuf centric?

    CEL spec is too protobuf centric?

    We're using CEL in Kubernetes to integrate with OpenAPIv3 schema types. When providing developers with the CEL spec as reference, it's a bit difficult to explain how our "object with fields" type maps to CEL types, because the spec doesn't have a term for this type that is independent of protobuf. For now we say in our documentation that our "object with fields" type maps to "message", but this gets a bit confusing.

    opened by jpbetz 2
  • Convenience feature: make map values available to predicates in macros

    Convenience feature: make map values available to predicates in macros

    I'm new to CEL but it looks like when you use one of the macros evaluating predicates (currently all, exists, and exists_one) on a map, only the current key is made available to the predicate. With the key, you can get the value, of course, but this may be tedious in programs such as

    some.very.deeply.nested.message.some_map_field.exists(k, some.very.deeply.nested.message.some_map_field[k] == 42)

    where you have to repeat a long path to the map field. Would it make sense to have, in addition to the two argument form of these macros (not counting the map receiver) to also have a three argument form to conveniently include the value as well? The above example would then become

    some.very.deeply.nested.message.some_map_field.exists(k, v, v == 42)

    which, for me at least, is easier to read.

    opened by TheCount 0
  • Widen duration to match google.protobuf.Duration from protocol buffer messages

    Widen duration to match google.protobuf.Duration from protocol buffer messages

    Currently CEL's duration is limited to a range of +/- 290 years while timestamps support 10000 years. This makes it awkward when calculating the difference between two timestamps. We should widen CEL's duration to match google.protobuf.Duration.

    opened by jcking 0
  • Add examples in the

    Add examples in the "standard definitions" table

    Every time I find myself referencing the spec, language definition doc, I have a hard time figuring out how each of the standard definitions can actually be used, because they just talk about an operator/function, but without context.

    I'd like to see examples for as many of the entries in that table as possible, in the description column. For example, it took me a while to figure out that a string -> int cast is done by doing int("string"), when I might've guessed it might be (int) "string" like in some C-like languages.

    For the symbols column I think code styling should be used (backticks in markdown) to use a monospaced font, because some of the entries like _[_] are hard to read on their own, it would look better as _[_].

    A note that _ means "where the operands go" would help clarify as well, I didn't find that immediately obvious.

    opened by francislavoie 1
  • v0.7.0(Mar 25, 2022)

    Release v0.7.0 marks an important milestone for CEL as it introduces heterogeneous equality at runtime. The spec also documents a uniform definition of protobuf equality, and support for cross-type numeric comparison to assist with evaluation over JSON data.

    Spec Changes

    The spec introduces heterogeneous equality to ensure that the following expressions agree with the type-checker behavior and match user expectations. The following examples are expressions which might have errors at runtime, but will now return successfully:

    json.number < 1
    json.number == 2u
    json.struct['key'] != null
    json.number in [1, 2, 3]

    For more details on the changes in semantics, see the spec updates in #232.
    Typically, this change will not result in a breaking behavior as it shifts errors to non-errors; however, some users may be relying on these errors and find the non-error result requires a change in how CEL is used within their application.

    • Document the duration string format supported by core implementations [#200]
    • Update the spec to support trailing commas in list, map, and struct literals [#202]
    • CEL Spec update to document heterogeneous equality, NaN, and ordering [#232]


    • Additional tests for overflow and documentation of overflow conditions [#201]
    • Update the get_milliseconds test to match the spec [#206]
    • Heterogeneous null conformance tests [#218]
    • Add tests to list and map for heterogeneous null comparisons [#219]
    • Add tests for heterogenous numeric comparison [#220]
    • Add conformance tests for message equality [#223]
    • Numeric in/equality tests across numeric types [#230]
    • Edge case tests for cross-type numeric comparisons [#231]


    • Fix double to int min case. [#204]
    • Remove all references to v1beta1 by removing testdata/ [#203]
    • Ensure that numeric timezones in tests are spec-consistent [#199]
    • Minor typos and grammar fixes [#229]
    • Fix spec ESCAPE definition mismatch [#226]

    New Contributors

    • @jnthntatum made their first contribution in
    • @Daniel-Bloom-dfinity made their first contribution in
    • @git-sgmoore made their first contribution in

    Full Changelog:

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 1, 2021)

    This release introduces some fixes to the conformance tests where the behavior either was incorrect or should not have been under test.


    • Convert double to integer via truncation. [#192]
    • Disable typecheck for null < x conformance test [#196]
    • Remove bad type specification in example [#188]


    • Add string conversion for timestamp and duration to spec [#195]
    • Update the proto options for cel-spec protos [#189]

    Conformance Tests

    • More tests for corners of numeric conversions. [#183]
    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Mar 29, 2021)

    Point release for CEL specification to pick up a handful of testing tool changes and some additional tests.

    Testing Tools

    • Implement a pipe protocol for cel-spec conformance client/server. (#164)
    • Removed unused proto utilities. (#181)


    • Time and space costs for expressions. (#165)
    • Add ToC and clean up section headers. (#167)
    • Update (#168)

    Conformance Tests

    • Add overflow tests for all ways to exceed range. (#182)
    • Add timestamp conversion to string test to ensure nanoseconds are preserved
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Nov 18, 2020)


    • Test that unbound funs and vars are runtime errs. (#120)
    • Conformance tests for dynamic conversions. (#117)
    • No unicode normalization: spec and tests. (#125)
    • Clarify homogeneous equality on lists and maps (#128)
    • Document overflow behavior, add tests. (#130)
    • Remove unused list and map type conversions. (#132)
    • Add basic tests and update lexis (#136)
    • Doc and conformance test for parsing depth. (#147)
    • More detailed spec and tests for parse limits. (#148)
    • Conformance tests for double to big uint. (#151)
    • Conformance eval both checked and parsed ASTs. (#153)
    • Conformance tests for enums and no wrapper. (#157)


    • Flag to skip check phase on all conformance tests. (#160)
    • Document the open CEL governance process (#134)


    • Fix syntax of signs (#129)
    • Fix grammar for description of duration (#139)
    • Golang protobuf v2 API support (#161)
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Apr 20, 2020)


    • Added support for protos in conformance tests.
    • Added a cel-spec go module.


    • AND / OR error handling
    • Macro equivalence
    • Mixed type comparison
    • has macro tests on maps, proto2, and proto3
    • Empty proto fields, single-field proto literals
    • Unicode strings


    • Fix bad quoting in the conformance tests
    • Namespace tests split into their own suite
    • Document JSON conversion
    • Fixed nested protobuf.Any comparisons.
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Aug 20, 2019)


    • More timestamp and duration conformance tests
    • Environment declaration / definition tests
    • A new --skip_test flag for bypassing unimplemented parts of the spec.


    • Off-by-one issues in Timestamp helpers
    • Byte literal examples.
    • Clarifications in the language specification.
    Source code(tar.gz)
    Source code(zip)
A set of tests to check compliance with the Prometheus Remote Write specification

Prometheus Remote Write Compliance Test This repo contains a set of tests to check compliance with the Prometheus Remote Write specification. The test

Tom Wilkie 88 May 8, 2022
Open Source runtime scanner for Linux containers (LXD), It performs security audit checks based on CIS Linux containers Benchmark specification

lxd-probe Scan your Linux container runtime !! Lxd-Probe is an open source audit scanner who perform audit check on a linux container manager and outp

Chen Keinan 12 Dec 27, 2021
Supporting your devops by shortening your strings using common abbreviations and clever guesswork

abbreviate Shorten your strings using common abbreviations. Supported by Tidelift Motivation This tool comes out of a frustration of the name of resou

Pascal Dennerly 180 May 1, 2022
YAML and Golang implementations of common Kubernetes patterns.

Kubernetes Patterns Types Patterns Foundational Patterns Behavioral Patterns Structural Patterns Configuration Patterns Usage To run, simply do go run

Sharad Bhat 70 Apr 12, 2022
Static analysis for CloudFormation templates to identify common misconfigurations

cfsec What is it? cfsec scans your yaml or json CloudFormation configuration files for common security misconfigurations. Installation Home Brew - Mac

Aqua Security 53 Apr 4, 2022
Common Image Registry for Testcontainers-Go

Testcontainers-Go Common Image Registry Common Image Registry for Testcontainers-Go Prerequisites Go >= 1.16 Install go get

Nhat 1 Feb 3, 2022
Copy files and artifacts via SSH using a binary, docker or Drone CI.

drone-scp Copy files and artifacts via SSH using a binary, docker or Drone CI. Feature Support routines. Support wildcard pattern on source list. Supp

Bo-Yi Wu 100 May 11, 2022
Go package that aids in binary analysis and exploitation

sploit Sploit is a Go package that aids in binary analysis and exploitation. The motivating factor behind the development of sploit is to be able to h

Brandon Miller 168 Apr 27, 2022
k6 extension supporting avro textual and binary representations

xk6-avro This extension wraps the goavro library into a k6 extension. You can build the extension using: xk6 build --with Exa

Matthias Riegler 0 Dec 8, 2021
Simple binary reader and writer

Simple Binary Stream Reader/Writer This package contains a set of simple utility reader and writer that can be used to efficiently read/write binary i

Roman Atachiants 6 Dec 22, 2021
Becca - A simple dynamic language for exploring language design

Becca A simple dynamic language for exploring language design What is Becca Becc

Nicholas Bailey 0 Mar 29, 2022
Nvidia GPU exporter for prometheus using nvidia-smi binary

nvidia_gpu_exporter Nvidia GPU exporter for prometheus, using nvidia-smi binary to gather metrics. Introduction There are many Nvidia GPU exporters ou

Utku Özdemir 94 May 17, 2022
Binary program to restart unhealthy Docker containers

DeUnhealth Restart your unhealthy containers safely Features Restart unhealthy containers marked with deunhealth.restart.on.unhealthy=true label Recei

Quentin McGaw 43 May 2, 2022
Lightweight, single-binary Backup Repository client. Part of E2E Backup Architecture designed by RiotKit

Backup Maker Tiny backup client packed in a single binary. Interacts with a Backup Repository server to store files, uses GPG to secure your backups e

RiotKit 1 Apr 4, 2022
Running Go binary into Docker

This go file make a get into an API, that API provides a JSON with a cat information

David Casado Masllorens 0 Feb 7, 2022
:paw_prints: Detect if a file is binary or text

Binary Go module and command line utility for checking if the given file or data is likely to be binary or text. It does so by reading the first, midd

Alexander F. Rødseth 4 Apr 25, 2022
A binary to control the Z-Cam line of cameras via API

The Z-Cam flagship line has an API of sorts. This can be used to control the camera--via a StreamDeck, say. This seems like a good enough reason to me

Corey Quinn 9 Apr 20, 2022
Build powerful pipelines in any programming language.

Gaia is an open source automation platform which makes it easy and fun to build powerful pipelines in any programming language. Based on HashiCorp's g

Gaia 4.7k May 14, 2022
A serverless cluster computing system for the Go programming language

Bigslice Bigslice is a serverless cluster data processing system for Go. Bigslice exposes composable API that lets the user express data processing ta

GRAIL 497 Apr 26, 2022