CEL-API-Referenz (Common Expression Language)

Dieses Dokument dient als einheitliche API-Dokumentationsreferenz für die Common Expression Language (CEL). Darin sind alle Makros, Operatoren und Standardfunktionen mit ihren Signaturen, Verhaltensweisen und dem Supportstatus für die offiziellen CEL-Stacks aufgeführt.

Weitere Informationen zum Sprachverhalten und zu den Spezifikationen finden Sie in der CEL-Sprachdefinition.

Stack-Versionen

Dieses Referenzdokument basiert auf den folgenden Versionen der CEL-Stacks:

  • CEL Go: v0.32.0 und höher
  • CEL C++: v0.16.1
  • CEL Java: v0.14.0
  • CEL Python: v0.1.3
  • CEL C: Entwicklungs-Snapshot (nicht veröffentlicht)

GitHub-Spiegelungen

Die offiziellen Implementierungen von CEL werden auf GitHub unter der Organisation cel-expr gespiegelt:


1. Core-Makros

Dies sind integrierte Makros, die zur Kompilierungszeit erweitert werden.

Macro Beschreibung Ok C++ Java Python C
has(container.field) Prüft, ob ein Feld in einer Nachricht oder ein Schlüssel in einer Map vorhanden ist.

Signaturen:
has(container.field) -> bool

Beispiele:
has(request.auth.claims.email)
list.all(var, predicate) Prüft, ob alle Elemente in einer Liste ein Prädikat erfüllen.

Signaturen:
list.all(var, predicate) -> bool

Beispiele:
[1, 2, 3].all(x, x > 0) // true
¹
list.exists(var, predicate) Prüft, ob mindestens ein Element in einer Liste ein Prädikat erfüllt.

Signaturen:
list.exists(var, predicate) -> bool

Beispiele:
[1, 2, 3].exists(x, x > 2) // true
¹
list.exists_one(var, predicate) Prüft, ob genau ein Element in einer Liste ein Prädikat erfüllt.

Signaturen:
list.exists_one(var, predicate) -> bool

Beispiele:
[1, 2, 3].exists_one(x, x == 2) // true
¹
list.filter(var, predicate) Filtert Elemente einer Liste anhand eines Prädikats.

Signaturen:
list.filter(var, predicate) -> list

Beispiele:
[1, 2, 3].filter(x, x > 1) // [2, 3]
¹
list.map(var, transform) Transformiert jedes Element einer Liste mithilfe eines Ausdrucks.

Signaturen:
list.map(var, transform) -> list

Beispiele:
[1, 2, 3].map(x, x * 2) // [2, 4, 6]
¹
list.map(var, filter, transform) Transformiert Elemente einer Liste, die ein Filterprädikat erfüllen.

Signaturen:
list.map(var, filter, transform) -> list

Beispiele:
[1, 2, 3].map(x, x > 1, x * 2) // [4, 6]
¹

¹ In der C-Laufzeitumgebung unterstützt, da Makros während der Kompilierung vom Hostcompiler in Comprehensions erweitert werden.


2. Kernoperatoren

Operator Beschreibung Ok C++ Java Python C
Arithmetisch (+, -, *, /, %) Standardmäßige arithmetische Operationen. Negation (-x) und Identität (+x). Die Listenverkettung (list + list) wird in Go, C++, Java und Python unterstützt.

Signaturen
T + T -> T
T - T -> T
T * T -> T
T / T -> T
T % T -> T
-T -> T
+T -> T
list + list -> list

Beispiele
1 + 2 * 3 // 7
[1] + [2] // [1, 2]
²
Vergleich (==, !=, <, <=, >, >=) Standardvergleich Numerische Vergleiche sind heterogen (z.B. 1 == 1.0).

Signaturen
T == T -> bool
T != T -> bool
T < T -> bool
T <= T -> bool
T > T -> bool
T >= T -> bool

Beispiele
x < 42.0
1 == 1.0 // true
Logisch (!, &&, ||, ? :) Logisches NICHT, UND, ODER und ternärer bedingter Operator. UND/ODER verwenden Sie die Kurzschlussauswertung.

Signaturen
!bool -> bool
bool && bool -> bool
bool || bool -> bool
bool ? T : T -> T

Beispiele
x > 0 ? "positive" : "non-positive"
Indexierung ([]) Greift über den Index auf ein Element einer Liste oder über den Suchschlüssel auf ein Element einer Map zu.

Signaturen:
list[int] -> T
map[K] -> V

Beispiele:
tags[0]
users['john']
Mitgliedschaft (in) Prüft, ob sich ein Element in einer Liste oder ein Schlüssel in einer Zuordnung befindet.

Signaturen:
T in list -> bool
K in map -> bool

Beispiele:
'admin' in roles

² Die Listenverkettung (list + list) wird in der C-Laufzeit nicht unterstützt, andere arithmetische Operatoren jedoch schon.


3. Hauptfunktionen

Allgemeine Funktionen und Stringfunktionen

Funktion Beschreibung Ok C++ Java Python C
size Gibt die Größe eines Strings (Zeichen), von Byte, einer Liste oder einer Map zurück.

Signaturen:
size(T) -> int (wobei T string, bytes, list oder map ist)

Beispiele:
size("hello") // 5
contains Gibt zurück, ob ein String einen Teilstring enthält.

Signaturen:
string.contains(string) -> bool

Beispiele:
"hello".contains("ell") // true
startsWith Gibt zurück, ob ein String mit einem Präfix beginnt.

Signaturen:
string.startsWith(string) -> bool

Beispiele:
"hello".startsWith("he") // true
endsWith Gibt zurück, ob ein String mit einem Suffix endet.

Signaturen:
string.endsWith(string) -> bool

Beispiele:
"hello".endsWith("lo") // true
matches Gibt zurück, ob der String mit dem regulären RE2-Ausdruck übereinstimmt.

Signaturen:
string.matches(string) -> bool

Beispiele:
"123".matches(r"^\d+$") // true

Funktionen für die Auswahl von Datum und Uhrzeit

Mit diesen Funktionen werden Komponenten aus google.protobuf.Timestamp oder google.protobuf.Duration extrahiert.

Funktion Beschreibung Ok C++ Java Python C
getFullYear Gibt das vierstellige Jahr zurück.

Signaturen:
timestamp.getFullYear([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026
getMonth Gibt den Monat (0–11) zurück.

Signaturen:
timestamp.getMonth([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getMonth() // 6
getDayOfMonth Gibt den Tag des Monats (1–31) zurück.

Signaturen:
timestamp.getDayOfMonth([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23
getDayOfWeek Gibt den Wochentag zurück (0 = Sonntag).

Signaturen:
timestamp.getDayOfWeek([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4
getDayOfYear Gibt den Tag des Jahres (0–365) zurück.

Signaturen:
timestamp.getDayOfYear([tz]) -> int

Beispiele:
timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203
getHours Gibt die Stunden (0–23) zurück.

Signaturen
timestamp.getHours([tz]) -> int
duration.getHours() -> int

Beispiele
duration("1h30m").getHours() // 1
getMinutes Gibt die Minuten (0–59) zurück.

Signaturen:
timestamp.getMinutes([tz]) -> int
duration.getMinutes() -> int

Beispiele:
duration("1h30m").getMinutes() // 30
getSeconds Gibt die Sekunden (0–59) zurück.

Signaturen:
timestamp.getSeconds([tz]) -> int
duration.getSeconds() -> int

Beispiele:
duration("1h30m45s").getSeconds() // 45
getMilliseconds Gibt die Millisekunden (0–999) zurück.

Signaturen:
timestamp.getMilliseconds([tz]) -> int
duration.getMilliseconds() -> int

Beispiele:
duration("1.5s").getMilliseconds() // 500

Typkonvertierungen

Zieltyp Beschreibung Ok C++ Java Python C
bool Wird in einen booleschen Wert konvertiert.

Signaturen:
bool(bool) -> bool
bool(string) -> bool

Beispiele:
bool("true") // true
bytes Wird in Byte konvertiert.

Signaturen
bytes(bytes) -> bytes
bytes(string) -> bytes

Beispiele
bytes("hello") // b"hello"
double Konvertiert in einen Gleitkommawert mit doppelter Genauigkeit.

Signaturen:
double(double) -> double
double(int) -> double
double(uint) -> double
double(string) -> double

Beispiele:
double(1) // 1.0
duration Wird in Dauer konvertiert.

Signaturen:
duration(duration) -> duration
duration(string) -> duration

Beispiele:
duration("1.5s") // 1.5s duration
int Wird in eine vorzeichenbehaftete 64-Bit-Ganzzahl umgewandelt.

Signaturen:
int(int) -> int
int(uint) -> int
int(double) -> int (rundet auf null)
int(string) -> int
int(timestamp) -> int (Sekunden seit der Epoche)

Beispiele:
int(1.5) // 1
string Wird in einen String umgewandelt.

Signaturen
string(T) -> string (unterstützt bool, int, uint, double, bytes, timestamp, duration)

Beispiele
string(1.5) // "1.5"
timestamp Wird in einen Zeitstempel konvertiert.

Signaturen:
timestamp(timestamp) -> timestamp
timestamp(string) -> timestamp (RFC3339)

Beispiele:
timestamp("2026-07-23T00:00:00Z")
uint Konvertiert in eine vorzeichenlose 64-Bit-Ganzzahl.

Signaturen
uint(uint) -> uint
uint(int) -> uint
uint(double) -> uint
uint(string) -> uint

Beispiele
uint(1) // 1u
dyn Wandelt einen Wert zur Typüberprüfung in den dynamischen Typ um.

Signaturen:
dyn(T) -> dyn

Beispiele:
dyn([1, "two"])
type Gibt den Typ des Werts zurück.

Signaturen:
type(T) -> type

Beispiele:
type(1) // int

4. Erweiterungen (Bibliotheken)

Bindings Library

Funktion Beschreibung Ok C++ Java Python C
cel.bind Bindet eine lokale Variable, um eine doppelte Auswertung zu vermeiden.

Signaturen:
cel.bind(varName, initExpr, resultExpr) -> T

Beispiele:
cel.bind(x, a + b, x * x)
(v0.15.0) (v0.10.0) (v0.2.0) (v0.1.1)

Aktivierung

Encoders Library

Funktion Beschreibung Ok C++ Java Python C
base64.encode Codiert Bytes in einen Base64-String.

Signaturen:
base64.encode(bytes) -> string

Beispiele:
base64.encode(b"hello") // "aGVsbG8="
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
base64.decode Decodiert einen base64-String in Byte. Gibt bei ungültiger Eingabe einen Fehler aus.

Signaturen:
base64.decode(string) -> bytes

Beispiele:
base64.decode("aGVsbG8=") // b"hello"
(v0.6.0) (v0.10.0) (v0.2.0) (v0.1.1)
json.encode Serialisiert einen CEL-Wert in einen JSON-String.

Signaturen:
json.encode(dyn) -> string

Beispiele:
json.encode([1, 2]) // "[1,2]"
(v0.29.0)

Aktivierung

Math-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
math.greatest Gibt den größten der numerischen Argumente (oder der Liste von numerischen Werten) zurück.

Signaturen:
math.greatest(arg, ...) -> T

Beispiele:
math.greatest(1, 3, 2) // 3
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.least Gibt den kleinsten der numerischen Argumente (oder eine Liste von numerischen Werten) zurück.

Signaturen:
math.least(arg, ...) -> T

Beispiele:
math.least([1, 3, 2]) // 1
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
math.abs Absoluter Wert.

Signaturen:
math.abs(T) -> T (unterstützt int, uint, double)

Beispiele:
math.abs(-1) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sqrt Quadratwurzel.

Signaturen:
math.sqrt(T) -> double (unterstützt int, uint, double)

Beispiele:
math.sqrt(9) // 3.0
(v0.25.1) (v0.12.0) (v0.11.0) (v0.1.1)
math.bitAnd Bitweises AND.

Signaturen
math.bitAnd(T, T) -> T (unterstützt int, uint)

Beispiele
math.bitAnd(5, 3) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitOr Bitweises OR.

Signaturen:
math.bitOr(T, T) -> T (unterstützt int, uint)

Beispiele:
math.bitOr(5, 3) // 7
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitXor Bitweises XOR.

Signaturen:
math.bitXor(T, T) -> T (unterstützt int, uint)

Beispiele:
math.bitXor(5, 3) // 6
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitNot Bitweises NOT.

Signaturen
math.bitNot(T) -> T (unterstützt int, uint)

Beispiele
math.bitNot(1) // -2
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftLeft Bitweise Linksverschiebung.

Signaturen:
math.bitShiftLeft(T, int) -> T (unterstützt int, uint)

Beispiele:
math.bitShiftLeft(1, 2) // 4
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.bitShiftRight Bitweise Rechtsverschiebung.

Signaturen:
math.bitShiftRight(T, int) -> T (unterstützt int, uint)

Beispiele:
math.bitShiftRight(4, 2) // 1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.ceil Aufrunden.

Signaturen
math.ceil(double) -> double

Beispiele
math.ceil(1.2) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.floor Abrunden.

Signaturen:
math.floor(double) -> double

Beispiele:
math.floor(1.8) // 1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.round Runden auf die nächste Ganzzahl.

Signaturen
math.round(double) -> double

Beispiele
math.round(1.5) // 2.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.trunc Abschneiden (Runden in Richtung null).

Signaturen:
math.trunc(double) -> double

Beispiele:
math.trunc(-1.8) // -1.0
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isInf Prüft, ob „double“ positiv oder negativ unendlich ist.

Signaturen:
math.isInf(double) -> bool

Beispiele:
math.isInf(1.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isNaN Prüft, ob der Double-Wert „NaN“ ist.

Signaturen:
math.isNaN(double) -> bool

Beispiele:
math.isNaN(0.0/0.0) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.isFinite Prüft, ob der Double-Wert endlich ist.

Signaturen
math.isFinite(double) -> bool

Beispiele
math.isFinite(1.2) // true
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)
math.sign Gibt das Vorzeichen des Werts zurück (-1, 0 oder 1).

Signaturen:
math.sign(T) -> T (unterstützt int, uint, double)

Beispiele:
math.sign(-42) // -1
(v0.21.0) (v0.11.0) (v0.10.1) (v0.1.1)

Aktivierung

Protos-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
proto.getExt Ruft das Proto2-Erweiterungsfeld ab oder den Standardwert, wenn es nicht festgelegt ist.

Signaturen:
proto.getExt(msg, extName) -> T

Beispiele:
proto.getExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)
proto.hasExt Prüft, ob das Proto2-Erweiterungsfeld festgelegt ist.

Signaturen:
proto.hasExt(msg, extName) -> bool

Beispiele:
proto.hasExt(msg, google.api.expr.test.int32_ext)
(v0.13.0) (v0.10.0) (v0.2.0) (v0.1.1)

Aktivierung

  • Go:Leite den Pass ext.Protos() an cel.NewEnv() weiter.
  • C++:Fügen Sie ProtoExtCompilerLibrary() zu CompilerBuilder hinzu. Die Laufzeit wird automatisch verwaltet.
  • Java:Fügen Sie CelExtensions.protos() zu CelCompiler- und CelRuntime-Buildern hinzu.
  • Python:Importieren Sie cel_expr_python.ext.ext_proto und verwenden Sie ExtProto() in cel.NewEnv(extensions=[...]).

Listenbibliothek

Funktion Beschreibung Ok C++ Java Python C
distinct Gibt eindeutige Elemente zurück.

Signaturen
list.distinct() -> list

Beispiele
[1, 2, 2].distinct() // [1, 2]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
flatten Verschachtelte Listen werden vereinfacht.

Signaturen
list.flatten([depth]) -> list

Beispiele
[[1], [2, 3]].flatten() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.7.1) (v0.1.1)
lists.range Gibt die Liste der Ganzzahlen [0, ..., n-1] zurück.

Signaturen
lists.range(int) -> list(int)

Beispiele
lists.range(3) // [0, 1, 2]
(v0.22.0) (v0.11.0) (v0.10.1) (v0.1.1)
reverse Kehrt die Liste um.

Signaturen:
list.reverse() -> list

Beispiele:
[1, 2].reverse() // [2, 1]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
slice Gibt eine Unterliste zurück (Start inklusive, Ende exklusive).

Signaturen:
list.slice(start, end) -> list

Beispiele:
[1, 2, 3].slice(1, 3) // [2, 3]
(v0.17.0) (v0.11.0) (v0.11.0) (v0.1.1)
sort Sortiert eine Liste vergleichbarer Elemente.

Signaturen:
list.sort() -> list

Beispiele:
[3, 1, 2].sort() // [1, 2, 3]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
sortBy Sortiert die Liste nach dem Schlüssel, der aus dem Ausdruck ausgewertet wird.

Signaturen:
list.sortBy(var, expr) -> list

Beispiele:
[{"val": 2}, {"val": 1}].sortBy(x, x.val) // [{"val": 1}, {"val": 2}]
(v0.22.0) (v0.11.0) (v0.11.0) (v0.1.1)
first Gibt das erste Element als optional zurück. Erfordert die optionale Erweiterung.

Signaturen
list.first() -> optional

Beispiele
[1, 2].first() // optional(1)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)
last Gibt das letzte Element als optional zurück. Erfordert die optionale Erweiterung.

Signaturen
list.last() -> optional

Beispiele
[1, 2].last() // optional(2)
(v0.23.0) (v0.15.0) (v0.11.0) (v0.1.2)

Aktivierung

Sets-Mediathek

Funktion Beschreibung Ok C++ Java Python C
sets.contains Prüft, ob list1 alle Elemente von list2 enthält.

Signaturen
sets.contains(list1, list2) -> bool

Beispiele
sets.contains([1, 2], [1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.equivalent Prüft, ob Listen mengenäquivalent sind (die gleichen eindeutigen Elemente enthalten).

Signaturen:
sets.equivalent(list1, list2) -> bool

Beispiele:
sets.equivalent([1, 2], [2, 1, 1]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)
sets.intersects Prüft, ob Listen mindestens ein gemeinsames Element haben.

Signaturen:
sets.intersects(list1, list2) -> bool

Beispiele:
sets.intersects([1, 2], [2, 3]) // true
(v0.15.0) (v0.10.0) (v0.6.0) (v0.1.1)

Aktivierung

  • Go:Leite den Pass ext.Sets() an cel.NewEnv() weiter.
  • C++:
  • Java:Fügen Sie CelExtensions.sets() zu CelCompiler- und CelRuntime-Buildern hinzu.
  • Python:Aktivieren Sie die Funktion über cel.EnvConfig, indem Sie sets der Liste extensions hinzufügen.

Strings-Bibliothek

Funktion Beschreibung Ok C++ Java Python C
charAt Gibt das Zeichen am Index zurück.

Signaturen:
string.charAt(int) -> string

Beispiele:
"hello".charAt(1) // "e"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
indexOf Gibt den Index des ersten Vorkommens des Teilstrings oder -1 zurück.

Signaturen:
string.indexOf(substr, [start]) -> int

Beispiele:
"hello".indexOf("l") // 2
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
lastIndexOf Gibt den Index des letzten Vorkommens des Teilstrings oder -1 zurück.

Signaturen:
string.lastIndexOf(substr, [end]) -> int

Beispiele:
"hello".lastIndexOf("l") // 3
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
join Verkettet Strings.

Signaturen:
list(string).join([separator]) -> string

Beispiele:
["a", "b"].join("-") // "a-b"
(v0.10.0) (v0.10.0) (v0.2.0) (v0.1.1)
split Teilt einen String anhand des Trennzeichens auf.

Signaturen:
string.split(separator, [limit]) -> list(string)

Beispiele:
"a-b".split("-") // ["a", "b"]
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
substring Gibt den Teilstring zurück (Start inklusive, Ende exklusive).

Signaturen:
string.substring(start, [end]) -> string

Beispiele:
"hello".substring(1, 3) // "el"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
trim Entfernt Unicode-Leerzeichen.

Signaturen
string.trim() -> string

Beispiele
" hello ".trim() // "hello"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
replace Ersetzt Vorkommen von „old“ durch „new“.

Signaturen:
string.replace(old, new, [limit]) -> string

Beispiele:
"hello".replace("l", "w") // "hewwo"
(v0.4.0) (v0.10.0) (v0.2.0) (v0.1.1)
reverse Kehrt Unicode-Codepunkte um.

Signaturen:
string.reverse() -> string

Beispiele:
"abc".reverse() // "cba"
(v0.18.0) (v0.14.0) (v0.13.0) (v0.1.1)
lowerAscii Wandelt ASCII-Zeichen in Kleinbuchstaben um.

Signaturen:
string.lowerAscii() -> string

Beispiele:
"Hello".lowerAscii() // "hello"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
upperAscii Konvertiert ASCII-Zeichen in Großbuchstaben.

Signaturen:
string.upperAscii() -> string

Beispiele:
"Hello".upperAscii() // "HELLO"
(v0.6.0) (v0.11.0) (v0.2.0) (v0.1.1)
quote Maskiert Strings für die sichere Ausgabe.

Signaturen:
strings.quote(string) -> string

Beispiele:
strings.quote("a\tb") // "\"a\\tb\""
(v0.14.0) (v0.14.0) (v0.13.0) (v0.1.1)
format Formatiert den String mit Platzhaltern im printf-Stil.

Signaturen
string.format(list) -> string

Beispiele
"str: %s, int: %d".format(["a", 1]) // "str: a, int: 1"
(v0.14.0) (v0.11.0) (v0.1.1)

Aktivierung

Mediathek mit regulären Ausdrücken

Funktion Beschreibung Ok C++ Java Python C
regex.replace Ersetzt Übereinstimmungen durch einen Ersatzstring (unterstützt Rückverweise).

Signaturen:
regex.replace(target, pat, repl, [limit]) -> string

Beispiele:
regex.replace("123-456", r"(\d+)-(\d+)", r"\2-\1") // "456-123"
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extract Gibt die erste Übereinstimmung des Musters zurück (muss eine Erfassungsgruppe haben).

Signaturen:
regex.extract(target, pat) -> optional(string)

Beispiele:
regex.extract("a123b", r"(\d+)") // optional("123")
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)
regex.extractAll Gibt alle Übereinstimmungen des Musters zurück (muss eine Erfassungsgruppe haben).

Signaturen:
regex.extractAll(target, pat) -> list(string)

Beispiele:
regex.extractAll("a1b2", r"(\d+)") // ["1", "2"]
(v0.25.1) (v0.13.0) (v0.10.1) (v0.1.1)

Aktivierung

Zwei-Variablen-Zusammenfassungen

Macro Beschreibung Ok C++ Java Python C
all Logisches UND über Schlüssel/Index und Wert abkürzen.

Signaturen:
list.all(i, v, pred) -> bool
map.all(k, v, pred) -> bool

Beispiele:
[1, 2].all(i, v, v > 0) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
exists Logisches ODER über Schlüssel/Index und Wert abkürzen.

Signaturen:
list.exists(i, v, pred) -> bool
map.exists(k, v, pred) -> bool

Beispiele:
[1, 2].exists(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
existsOne Prüft, ob genau ein Paar das Prädikat erfüllt.

Signaturen:
list.existsOne(i, v, pred) -> bool
map.existsOne(k, v, pred) -> bool

Beispiele:
[1, 2].existsOne(i, v, v == 2) // true
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformList Wandelt eine Liste/Karte in eine Liste um oder filtert sie.

Signaturen:
list.transformList(i, v, [filter], transform) -> list
map.transformList(k, v, [filter], transform) -> list

Beispiele:
[1, 2].transformList(i, v, v * 2) // [2, 4]
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMap Transformiert Werte einer Liste/Zuordnung in eine Zuordnung (Schlüssel bleiben unverändert).

Signaturen:
list.transformMap(i, v, [filter], transform) -> map
map.transformMap(k, v, [filter], transform) -> map

Beispiele:
[1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)
transformMapEntry Wird in eine Karte umgewandelt.

Signaturen:
list.transformMapEntry(i, v, [filter], transform_entry) -> map
map.transformMapEntry(k, v, [filter], transform_entry) -> map

Beispiele:
[1, 2].transformMapEntry(i, v, {string(v): v * 2}) // {"1": 2, "2": 4}
(v0.22.0) (v0.14.0) (v0.11.0) (v0.1.1)

Aktivierung

Bibliothek für native Typen

Funktion Beschreibung Ok C++ Java Python C
Native Structs Registrieren und Instanziieren von nativen Hosttypen (Go-Structs / Java-POJOs) in CEL.

Beispiele:
Account{id: 123} (Java-POJO, das in CEL instanziiert wird)
(v0.13.0) (v0.13.0)

Aktivierung

Netzwerkbibliothek

Die Netzwerkbibliothek bietet Funktionen zum Parsen, Validieren und Bearbeiten von IP-Adressen und CIDR-Blöcken.

Funktion Beschreibung Ok C++ Java Python C
ip Parst einen String in eine IP-Adresse oder extrahiert die IP-Adresse aus einem CIDR.

Signaturen
ip(string) -> IP
CIDR.ip() -> IP

Beispiele
ip("192.168.0.1")
cidr("192.168.0.0/24").ip()
(v0.29.0)
isIP Prüft, ob ein String eine gültige IP-Adresse ist.

Signaturen:
isIP(string) -> bool

Beispiele:
isIP("192.168.0.1") // true
(v0.29.0)
ip.isCanonical Prüft, ob ein IP-Adressstring im kanonischen Format vorliegt.

Signaturen:
ip.isCanonical(string) -> bool

Beispiele:
ip.isCanonical("192.168.0.1") // true
(v0.29.0)
cidr Parst einen String in einen CIDR-Block.

Signaturen:
cidr(string) -> CIDR

Beispiele:
cidr("192.168.0.0/24")
(v0.29.0)
isCIDR Prüft, ob ein String ein gültiger CIDR-Block ist.

Signaturen:
isCIDR(string) -> bool

Beispiele:
isCIDR("192.168.0.0/24") // true
(v0.29.0)
containsIP Prüft, ob ein CIDR-Block eine IP-Adresse enthält.

Signaturen:
CIDR.containsIP(IP) -> bool
CIDR.containsIP(string) -> bool

Beispiele:
cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true
(v0.29.0)
containsCIDR Prüft, ob ein CIDR-Block einen anderen CIDR-Block enthält.

Signaturen:
CIDR.containsCIDR(CIDR) -> bool
CIDR.containsCIDR(string) -> bool

Beispiele:
cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true
(v0.29.0)
family Gibt die IP-Familie zurück (4 für IPv4, 6 für IPv6).

Signaturen:
IP.family() -> int

Beispiele:
ip("192.168.0.1").family() // 4
(v0.29.0)
isGlobalUnicast Prüft, ob die IP-Adresse eine globale Unicast-Adresse ist.

Signaturen:
IP.isGlobalUnicast() -> bool

Beispiele:
ip("192.168.0.1").isGlobalUnicast() // true
(v0.29.0)
isLinkLocalMulticast Prüft, ob die IP-Adresse eine Link-Local-Multicast-Adresse ist.

Signaturen:
IP.isLinkLocalMulticast() -> bool

Beispiele:
ip("224.0.0.1").isLinkLocalMulticast() // true
(v0.29.0)
isLinkLocalUnicast Prüft, ob die IP-Adresse eine link-lokale Unicast-Adresse ist.

Signaturen:
IP.isLinkLocalUnicast() -> bool

Beispiele:
ip("169.254.0.1").isLinkLocalUnicast() // true
(v0.29.0)
isLoopback Prüft, ob die IP-Adresse eine Loopback-Adresse ist.

Signaturen:
IP.isLoopback() -> bool

Beispiele:
ip("127.0.0.1").isLoopback() // true
(v0.29.0)
isMask Prüft, ob die CIDR eine gültige Subnetzmaske ist.

Signaturen:
CIDR.isMask() -> bool

Beispiele:
cidr("255.255.255.0/24").isMask() // true
(v0.29.0)
isUnspecified Prüft, ob die IP-Adresse eine nicht angegebene Adresse ist (z.B. 0.0.0.0).

Signaturen:
IP.isUnspecified() -> bool

Beispiele:
ip("0.0.0.0").isUnspecified() // true
(v0.29.0)
masked Gibt den maskierten CIDR-Block zurück.

Signaturen:
CIDR.masked() -> CIDR

Beispiele:
cidr("192.168.0.1/24").masked() // 192.168.0.0/24
(v0.29.0)
prefixLength Gibt die Präfixlänge des CIDR-Blocks zurück.

Signaturen:
CIDR.prefixLength() -> int

Beispiele:
cidr("192.168.0.0/24").prefixLength() // 24
(v0.29.0)
string Konvertiert IP-Adressen oder CIDR-Blöcke in Strings.

Signaturen:
string(IP) -> string
string(CIDR) -> string

Beispiele:
string(ip("192.168.0.1")) // "192.168.0.1"
(v0.29.0)

Aktivierung

  • Go:Leite den Pass ext.Network() an cel.NewEnv() weiter.
  • C++:Nicht unterstützt.
  • Java:Nicht unterstützt.
  • Python:Nicht unterstützt.

JWT-Bibliothek

Die JWT-Bibliothek bietet Datentypen und Hilfsfunktionen zum Parsen von JSON-Webtokens (JWT) und zum Untersuchen von Standard- und benutzerdefinierten Ansprüchen.

Funktion Beschreibung Ok C++ Java Python C
jwt.parse Parst eine unformatierte Token-Zeichenkette in eine strukturierte jwt.Token-Zeichenkette, die in ein optionales

Signaturen:
jwt.parse(string) -> optional(jwt.Token)

Beispiele:
jwt.parse(token_string).hasValue()
(v0.32.0)
claim Fragt einen benutzerdefinierten Anspruchswert anhand des Schlüsselnamens aus der Token-Nutzlast ab.

Signaturen:
jwt.Token.claim(string) -> optional(dyn)
optional(jwt.Token).claim(string) -> optional(dyn)

Beispiele:
jwt.parse(token).claim("tenant").orValue("")
(v0.32.0)
presentedBy Prüft, ob Aussteller und Zielgruppe des Tokens mit den erwarteten Werten übereinstimmen.

Signaturen
jwt.Token.presentedBy(string, string) -> bool
optional(jwt.Token).presentedBy(string, string) -> bool

Beispiele
jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com")
(v0.32.0)

Aktivierung

  • Go:Importieren Sie cel.dev/cel-go/ext/security/jwt und übergeben Sie jwt.Library() an cel.NewEnv().
  • C++:Nicht unterstützt.
  • Java:Nicht unterstützt.
  • Python:Nicht unterstützt.

HMAC-Bibliothek

Die HMAC-Bibliothek bietet kryptografische Funktionen zum Berechnen und Überprüfen von Hash-basierten Message Authentication Codes (HMAC) für Strings und Bytefolgen.

Funktion Beschreibung Ok C++ Java Python C
hmac.compute Berechnet die Roh-HMAC-Signaturbytes mit dem angegebenen Algorithmus und dem geheimen Schlüssel.

Signaturen
hmac.compute(string, string|bytes, string|bytes) -> bytes

Beispiele
hmac.compute(hmac.SHA256, "secret", "message")
(v0.32.0)
hmac.verify Überprüft, ob eine HMAC-Signatur mit dem erwarteten Digest übereinstimmt.

Signaturen:
hmac.verify(string, string|bytes, string|bytes, string|bytes) -> bool

Beispiele:
hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true
(v0.32.0)

Aktivierung

  • Go:Importieren Sie cel.dev/cel-go/ext/security/hmac und übergeben Sie hmac.Library() an cel.NewEnv().
  • C++:Nicht unterstützt.
  • Java:Nicht unterstützt.
  • Python:Nicht unterstützt.

5. Erweiterte Funktionen

Zusammenfassung der erweiterten Funktionen

Funktion Beschreibung Ok C++ Java Python C
Teilweise Auswertung Auswertung mit fehlenden Eingaben; gibt Unbekannte oder einen vereinfachten Ausdruck zurück. ³
Asynchrone Bewertung Nicht blockierende gleichzeitige Ausführung von Erweiterungsfunktionen.
AST-Validatoren Bei der statischen Analyse wird der geprüfte AST nach der Typüberprüfung untersucht.
AST-Optimierungstools AST-Rewrites (Constant Folding, Inlining, CSE), um die Leistung zu verbessern.
CEL Policy Compiler Kompiliert YAML-basierte Richtlinienstrukturen in standardisierte CEL-ASTs.
Formale Überprüfung Beweist Sicherheitsinvarianten, Erfüllbarkeit, Gültigkeit und AST-Äquivalenz. (v0.14.0)

³ Go unterstützt das Generieren eines Residual AST (gekürzter AST). ⁴ C++ und Java unterstützen die Rückgabe von UnknownSet / CelUnknownSet zur Laufzeit, stellen aber keine öffentlichen APIs für die Generierung von Residual-ASTs bereit. ⁵ Go verwendet AsyncBinding / AsyncOp, um Channels zurückzugeben. ⁶ Java verwendet CelAsyncRuntime und gibt ListenableFuture zurück.

Teilweise Auswertung (Unbekannte)

Bei der partiellen Auswertung wird ein Ausdruck ausgewertet, wenn nur eine Teilmenge der Eingabevariablen (Argumente) bekannt ist. Stattdessen wird ein Ergebnis zurückgegeben, das angibt, was fehlt, oder ein vereinfachter Ausdruck.

  • Go: Volle Unterstützung. Ermöglicht die Definition eines PartialActivation mit Mustern unbekannter Attribute. Die Auswertung gibt einen types.Unknown-Wert zurück. Go unterstützt die Generierung eines Residual AST (Env.ResidualAst), eines reduzierten, vereinfachten AST, der nur die Teile des Ausdrucks enthält, die nicht ausgewertet werden konnten.
  • C++:Unterstützt Unknown-Werte. Unbekannte Attributmuster werden über Activation::set_unknown_attribute_patterns konfiguriert. Die Auswertung gibt eine UnknownSet zurück. Die öffentliche API bietet derzeit keine Möglichkeit, den verbleibenden AST zu generieren.
  • Java:Unterstützt die partielle Auswertung über PartialVars, die an Program.eval() übergeben wird. Die Auswertung gibt ein CelUnknownSet zurück. Die öffentliche API bietet derzeit keine Möglichkeit, Residual-ASTs zu generieren.
  • Python / C:Keine native Unterstützung.

Asynchrone Auswertung

Bei der asynchronen Auswertung können CEL-Ausdrücke Funktionen aufrufen, die asynchron ausgeführt werden (z.B. RPCs oder Datenbankabfragen), und die Auswertung blockieren, bis die Ergebnisse verfügbar sind, ohne den Hauptausführungs-Thread zu blockieren.

  • Go:Unterstützt asynchrone Funktionsüberladungen über AsyncBinding und AsyncOp. Asynchrone Funktionen geben einen Go-Channel (<-chan ref.Val) zurück. Der Interpreter verwaltet die gleichzeitige Ausführung und Synchronisierung.
  • Java:Unterstützt die asynchrone Auswertung über CelAsyncRuntime und AsyncProgram. Dabei wird ListenableFuture verwendet, um ausstehende Werte darzustellen. Die Auswertung wird automatisch abgeschlossen, wenn Futures aufgelöst werden.
  • C++ / Python / C:Keine integrierte Unterstützung.

AST-Validatoren

Validatoren führen nach der Typüberprüfung eine statische Analyse des geprüften AST durch, um domänenspezifische Einschränkungen zu erzwingen, bevor das Programm ausgeführt wird.

  • Go:Unterstützt die ASTValidator-Schnittstelle. Zu den kanonischen Validatoren gehören cel.validator.duration, cel.validator.timestamp, cel.validator.matches (regulärer Ausdruck), cel.validator.homogeneous_literals und cel.validator.comprehension_nesting_limit.
  • C++:Unterstützt cel::Validator. Die kanonischen Validierungen umfassen AstDepthValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, MatchesValidator und TimestampLiteralValidator.
  • Java:Unterstützt CelValidator und CelAstValidator. Zu den Canonical-Validatoren gehören AstDepthLimitValidator, ComprehensionNestingLimitValidator, DurationLiteralValidator, HomogeneousLiteralValidator, RegexLiteralValidator und TimestampLiteralValidator.
  • Python / C:Keine direkte Unterstützung.

AST-Optimierungstools

Optimierer schreiben den AST neu, um die Ausführungsleistung zu verbessern. Optimierer lassen sich in zwei Kategorien einteilen: statische Optimierer und Laufzeitoptimierer. C++, Java und Go unterstützen die Laufzeitoptimierung. CEL Java und Go unterstützen auch statische Optimierer.

Typische Optimierungen sind das Zusammenfassen von Konstanten (die Vorab-Auswertung von Teilausdrücken mit konstanten Eingaben) und die Eliminierung gemeinsamer Teilausdrücke (Common Subexpression Elimination, CSE).

  • Go:Unterstützt das Zusammenfassen von AST während der Kompilierung/Planung.
  • C++:Unterstützt die konstante Faltung über die cel::extensions::EnableConstantFolding-Erweiterung zur Planungszeit.
  • Java: Unterstützt die CelOptimizer Schnittstelle. Zu den kanonischen Optimierern gehören ConstantFoldingOptimizer (der die Pre-Order-Traversierung, das Falten von Protobuf-Nachrichtenkonstanten und das Aggregieren oder optionale Entfernen unterstützt), InliningOptimizer und SubexpressionOptimizer (CSE).
  • Python / C: Keine direkte Unterstützung.

CEL-Richtliniencompiler

CEL Policy ist ein YAML-basiertes Format zum Zusammensetzen mehrerer CEL-Ausdrücke mit Variablen, Übereinstimmungsblöcken, bedingten Ausgaben und verschachtelten Regeln. Es ist für komplexe Richtlinien-Engines (wie Kubernetes Admission Control) konzipiert, bei denen einzelne CEL-Ausdrücke unlesbar würden.

Für die formale Sprachdefinition, Syntax und Konformitätssuite verweisen wir auf die CEL Policy Specification.

Der Policy Compiler kompiliert diese YAML-Richtlinien in einen einzelnen standardmäßigen CEL-AST. Das bedeutet, dass sie vollständig mit standardmäßigen CEL-Laufzeiten kompatibel sind und alle Leistungs- und Sicherheitsgarantien übernehmen.

  • Go:Wird über die Go-Richtlinie unterstützt (einschließlich der Semantik für die Auswertung von Aggregatregeln).
  • C++:Wird über die C++-Richtlinie unterstützt.
  • Java:Unterstützt über die Java-Richtlinie (einschließlich der Semantik für die Auswertung von Aggregatregeln und der Kurzform-Typspezifizierer in Richtlinienkonfigurationen).
  • Python / C: Wird nicht direkt unterstützt.

Framework für die formale Überprüfung

Mit dem Framework für die formale Überprüfung können Nutzer Sicherheitsinvarianten, logische Äquivalenz, Erfüllbarkeit und Gültigkeit von CEL-Ausdrücken und strukturierten CEL-Richtlinien mathematisch beweisen.

  • Java:Wird über den CEL Java Verifier (dev.cel:verifier und dev.cel:verifier-cli) unterstützt. Zu den Funktionen gehören die Erfüllbarkeit (isSatisfiable) mit der Generierung von Zeugen-Eingaben, die Gültigkeit (isAlwaysTrue) mit der Generierung von Gegenbeispielen, die eingeschränkte Modellprüfung (Bounded Model Checking, BMC) für Comprehensions, logische Äquivalenznachweise für ASTs und die benutzerdefinierte Überprüfung von assume-/assert-Richtlinieninvarianten.
  • Go / C++ / Python / C: Werden indirekt über die Java-Befehlszeilen-Toolchain unterstützt.

Eine Einführung und Beispiele aus der Praxis finden Sie im Google Open Source-Blogpost Securing the agentic era: Introducing formal verification for CEL.