Questo documento funge da riferimento unificato per la documentazione dell'API per il Common Expression Language (CEL). Elenca tutte le macro, gli operatori e le funzioni standard, indicando le firme, i comportamenti e lo stato di supporto negli stack CEL ufficiali.
Per ulteriori dettagli sul comportamento e sulle specifiche della lingua, consulta la definizione del linguaggio CEL.
Versioni dello stack
Questo documento di riferimento si basa sulle seguenti versioni degli stack CEL:
- CEL Go:
v0.32.0(e versioni successive) - CEL C++:
v0.16.1 - CEL Java:
v0.14.0 - CEL Python:
v0.1.3 - CEL C: snapshot di sviluppo (non rilasciato)
Mirror di GitHub
Le implementazioni ufficiali di CEL sono sottoposte a mirroring su GitHub nell'organizzazione cel-expr:
1. Macro principali
Si tratta di macro integrate che vengono espanse in tempo di compilazione.
| Macro | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
has(container.field) |
Verifica se un campo è presente in un messaggio o una chiave in una mappa. Firme: has(container.field) -> boolEsempi: has(request.auth.claims.email) |
✓ | ✓ | ✓ | ✓ | ✓ |
list.all(var, predicate) |
Verifica se tutti gli elementi di un elenco soddisfano un predicato. Firme: list.all(var, predicate) -> boolEsempi: [1, 2, 3].all(x, x > 0) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists(var, predicate) |
Verifica se almeno un elemento di un elenco soddisfa un predicato. Firme: list.exists(var, predicate) -> boolEsempi: [1, 2, 3].exists(x, x > 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.exists_one(var, predicate) |
Verifica se esattamente un elemento in un elenco soddisfa un predicato. Firme: list.exists_one(var, predicate) -> boolEsempi: [1, 2, 3].exists_one(x, x == 2) // true |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.filter(var, predicate) |
Filtra gli elementi di un elenco in base a un predicato. Firme: list.filter(var, predicate) -> listEsempi: [1, 2, 3].filter(x, x > 1) // [2, 3] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, transform) |
Trasforma ogni elemento di un elenco utilizzando un'espressione. Firme: list.map(var, transform) -> listEsempi: [1, 2, 3].map(x, x * 2) // [2, 4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
list.map(var, filter, transform) |
Trasforma gli elementi di un elenco che soddisfano un predicato di filtro. Firme: list.map(var, filter, transform) -> listEsempi: [1, 2, 3].map(x, x > 1, x * 2) // [4, 6] |
✓ | ✓ | ✓ | ✓ | ✓¹ |
¹ Supportato in C runtime perché le macro vengono espanse in comprensioni durante la compilazione da parte del compilatore host.
2. Operatori principali
| Operatore | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
Aritmetica (+, -, *, /, %) |
Operazioni aritmetiche standard. Negazione (-x) e identità (+x). La concatenazione di elenchi (list + list) è supportata in Go, C++, Java e Python.Firme: T + T -> TT - T -> TT * T -> TT / T -> TT % T -> T-T -> T+T -> Tlist + list -> listEsempi: 1 + 2 * 3 // 7[1] + [2] // [1, 2] |
✓ | ✓ | ✓ | ✓ | ✓² |
Confronto (==, !=, <, <=, >, >=) |
Confronto standard. I confronti numerici sono eterogenei (ad es. 1 == 1.0).Firme: T == T -> boolT != T -> boolT < T -> boolT <= T -> boolT > T -> boolT >= T -> boolEsempi: x < 42.01 == 1.0 // true |
✓ | ✓ | ✓ | ✓ | ✓ |
Logico (!, &&, ||, ? :) |
NOT, AND, OR logici e condizionale ternario. AND/OR utilizza la valutazione short-circuit. Firme: !bool -> boolbool && bool -> boolbool || bool -> boolbool ? T : T -> TEsempi: x > 0 ? "positive" : "non-positive" |
✓ | ✓ | ✓ | ✓ | ✓ |
Indicizzazione ([]) |
Accedi all'elemento di un elenco per indice o alla chiave di ricerca in una mappa. Firme: list[int] -> Tmap[K] -> VEsempi: tags[0]users['john'] |
✓ | ✓ | ✓ | ✓ | ✓ |
Abbonamento (in) |
Controlla se l'elemento si trova in un elenco o se la chiave si trova in una mappa. Firme: T in list -> boolK in map -> boolEsempi: 'admin' in roles |
✓ | ✓ | ✓ | ✓ | ✓ |
² La concatenazione di elenchi (list + list) non è supportata nel runtime C,
anche se sono supportati altri operatori aritmetici.
3. Funzioni principali
Funzioni generali e di stringa
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
size |
Restituisce le dimensioni di una stringa (caratteri), di byte, di un elenco o di una mappa. Firme: size(T) -> int (dove T è string, bytes, list o map)Esempi: size("hello") // 5 |
✓ | ✓ | ✓ | ✓ | ✓ |
contains |
Restituisce un valore che indica se la stringa contiene una sottostringa. Firme: string.contains(string) -> boolEsempi: "hello".contains("ell") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
startsWith |
Restituisce un valore che indica se la stringa inizia con il prefisso. Firme: string.startsWith(string) -> boolEsempi: "hello".startsWith("he") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
endsWith |
Restituisce un valore che indica se la stringa termina con il suffisso. Firme: string.endsWith(string) -> boolEsempi: "hello".endsWith("lo") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
matches |
Restituisce un valore che indica se la stringa corrisponde all'espressione regolare RE2. Firme: string.matches(string) -> boolEsempi: "123".matches(r"^\d+$") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
Funzioni di selezione di data e ora
Queste funzioni estraggono componenti da google.protobuf.Timestamp o
google.protobuf.Duration.
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
getFullYear |
Restituisce l'anno a 4 cifre. Firme: timestamp.getFullYear([tz]) -> intEsempi: timestamp("2026-07-23T00:00:00Z").getFullYear() // 2026 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMonth |
Restituisce il mese (0-11). Firme: timestamp.getMonth([tz]) -> intEsempi: timestamp("2026-07-23T00:00:00Z").getMonth() // 6 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfMonth |
Restituisce il giorno del mese (1-31). Firme: timestamp.getDayOfMonth([tz]) -> intEsempi: timestamp("2026-07-23T00:00:00Z").getDayOfMonth() // 23 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfWeek |
Restituisce il giorno della settimana (0 = domenica). Firme: timestamp.getDayOfWeek([tz]) -> intEsempi: timestamp("2026-07-23T00:00:00Z").getDayOfWeek() // 4 |
✓ | ✓ | ✓ | ✓ | ✗ |
getDayOfYear |
Restituisce il giorno dell'anno (0-365). Firme: timestamp.getDayOfYear([tz]) -> intEsempi: timestamp("2026-07-23T00:00:00Z").getDayOfYear() // 203 |
✓ | ✓ | ✓ | ✓ | ✗ |
getHours |
Restituisce le ore (0-23). Firme: timestamp.getHours([tz]) -> intduration.getHours() -> intEsempi: duration("1h30m").getHours() // 1 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMinutes |
Restituisce i minuti (0-59). Firme: timestamp.getMinutes([tz]) -> intduration.getMinutes() -> intEsempi: duration("1h30m").getMinutes() // 30 |
✓ | ✓ | ✓ | ✓ | ✗ |
getSeconds |
Restituisce i secondi (0-59). Firme: timestamp.getSeconds([tz]) -> intduration.getSeconds() -> intEsempi: duration("1h30m45s").getSeconds() // 45 |
✓ | ✓ | ✓ | ✓ | ✗ |
getMilliseconds |
Restituisce i millisecondi (0-999). Firme: timestamp.getMilliseconds([tz]) -> intduration.getMilliseconds() -> intEsempi: duration("1.5s").getMilliseconds() // 500 |
✓ | ✓ | ✓ | ✓ | ✗ |
Conversioni dei tipi
| Tipo di target | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
bool |
Viene convertito in booleano. Firme: bool(bool) -> boolbool(string) -> boolEsempi: bool("true") // true |
✓ | ✓ | ✓ | ✓ | ✓ |
bytes |
Viene convertito in byte. Firme: bytes(bytes) -> bytesbytes(string) -> bytesEsempi: bytes("hello") // b"hello" |
✓ | ✓ | ✓ | ✓ | ✓ |
double |
Esegue la conversione in virgola mobile a precisione doppia. Firme: double(double) -> doubledouble(int) -> doubledouble(uint) -> doubledouble(string) -> doubleEsempi: double(1) // 1.0 |
✓ | ✓ | ✓ | ✓ | ✓ |
duration |
Converte in durata. Firme: duration(duration) -> durationduration(string) -> durationEsempi: duration("1.5s") // 1.5s duration |
✓ | ✓ | ✓ | ✓ | ✓ |
int |
Converte in un numero intero con segno a 64 bit. Firme: int(int) -> intint(uint) -> intint(double) -> int (arrotonda a zero)int(string) -> intint(timestamp) -> int (secondi dall'epoca)Esempi: int(1.5) // 1 |
✓ | ✓ | ✓ | ✓ | ✓ |
string |
Esegue la conversione in stringa. Firme: string(T) -> string (supporta bool, int, uint, double, bytes, timestamp, duration)Esempi: string(1.5) // "1.5" |
✓ | ✓ | ✓ | ✓ | ✓ |
timestamp |
Esegue la conversione in timestamp. Firme: timestamp(timestamp) -> timestamptimestamp(string) -> timestamp (RFC3339)Esempi: timestamp("2026-07-23T00:00:00Z") |
✓ | ✓ | ✓ | ✓ | ✓ |
uint |
Converte in un numero intero senza segno a 64 bit. Firme: uint(uint) -> uintuint(int) -> uintuint(double) -> uintuint(string) -> uintEsempi: uint(1) // 1u |
✓ | ✓ | ✓ | ✓ | ✓ |
dyn |
Esegue il cast del valore al tipo dinamico per il controllo del tipo. Firme: dyn(T) -> dynEsempi: dyn([1, "two"]) |
✓ | ✓ | ✓ | ✓ | ✗ |
type |
Restituisce il tipo di valore. Firme: type(T) -> typeEsempi: type(1) // int |
✓ | ✓ | ✓ | ✓ | ✗ |
4. Estensioni (librerie)
Libreria di associazioni
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
cel.bind |
Associa una variabile locale per evitare la valutazione duplicata. Firme: cel.bind(varName, initExpr, resultExpr) -> TEsempi: cel.bind(x, a + b, x * x) |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Bindings()acel.NewEnv(). - C++: aggiungi
BindingsCompilerLibrary()aCompilerBuilder. Il runtime viene gestito automaticamente. - Java: aggiungi
CelExtensions.bindings()aCelCompilere ai builderCelRuntime. - Python: importa
cel_expr_python.ext.ext_bindingse utilizzaExtBindings()incel.NewEnv(extensions=[...]).
Libreria di codificatori
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
base64.encode |
Codifica i byte in una stringa base64. Firme: base64.encode(bytes) -> stringEsempi: base64.encode(b"hello") // "aGVsbG8=" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
base64.decode |
Decodifica la stringa Base64 in byte. Genera un errore in caso di input non valido. Firme: base64.decode(string) -> bytesEsempi: base64.decode("aGVsbG8=") // b"hello" |
✓ (v0.6.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
json.encode |
Serializza un valore CEL in una stringa JSON. Firme: json.encode(dyn) -> stringEsempi: json.encode([1, 2]) // "[1,2]" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Come attivare
- Vai: passa
ext.Encoders()acel.NewEnv(). - C++:
- Redattore: aggiungi
EncodersCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterEncodersFunctions()il giornoFunctionRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.encoders()aCelCompilere ai builderCelRuntime. - Python: importa
cel_expr_python.ext.ext_encoderse utilizzaExtEncoders()incel.NewEnv(extensions=[...]).
Libreria matematica
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
math.greatest |
Restituisce il maggiore degli argomenti numerici (o dell'elenco di numeri). Firme: math.greatest(arg, ...) -> TEsempi: math.greatest(1, 3, 2) // 3 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.least |
Restituisce il minimo degli argomenti numerici (o dell'elenco di numeri). Firme: math.least(arg, ...) -> TEsempi: math.least([1, 3, 2]) // 1 |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
math.abs |
Valore assoluto. Firme: math.abs(T) -> T (supporta int, uint, double)Esempi: math.abs(-1) // 1 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sqrt |
Radice quadrata. Firme: math.sqrt(T) -> double (supporta int, uint, double)Esempi: math.sqrt(9) // 3.0 |
✓ (v0.25.1) | ✓ (v0.12.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
math.bitAnd |
AND bit a bit. Firme: math.bitAnd(T, T) -> T (supporta int, uint)Esempi: math.bitAnd(5, 3) // 1 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitOr |
OR bit a bit. Firme: math.bitOr(T, T) -> T (supporta int, uint)Esempi: math.bitOr(5, 3) // 7 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitXor |
XOR bit a bit. Firme: math.bitXor(T, T) -> T (supporta int, uint)Esempi: math.bitXor(5, 3) // 6 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitNot |
NOT bit a bit. Firme: math.bitNot(T) -> T (supporta int, uint)Esempi: math.bitNot(1) // -2 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftLeft |
Spostamento bit a bit a sinistra. Firme: math.bitShiftLeft(T, int) -> T (supporta int, uint)Esempi: math.bitShiftLeft(1, 2) // 4 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.bitShiftRight |
Spostamento bit a destra. Firme: math.bitShiftRight(T, int) -> T (supporta int, uint)Esempi: math.bitShiftRight(4, 2) // 1 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.ceil |
Arrotondamento per eccesso. Firme: math.ceil(double) -> doubleEsempi: math.ceil(1.2) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.floor |
Arrotondamento per difetto. Firme: math.floor(double) -> doubleEsempi: math.floor(1.8) // 1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.round |
Arrotondamento al numero intero più vicino. Firme: math.round(double) -> doubleEsempi: math.round(1.5) // 2.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.trunc |
Troncamento (arrotondamento verso zero). Firme: math.trunc(double) -> doubleEsempi: math.trunc(-1.8) // -1.0 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isInf |
Verifica se il valore double è infinito positivo o negativo. Firme: math.isInf(double) -> boolEsempi: math.isInf(1.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isNaN |
Controlla se double è NaN. Firme: math.isNaN(double) -> boolEsempi: math.isNaN(0.0/0.0) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.isFinite |
Controlla se il valore double è finito. Firme: math.isFinite(double) -> boolEsempi: math.isFinite(1.2) // true |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
math.sign |
Restituisce il segno del valore (-1, 0 o 1). Firme: math.sign(T) -> T (supporta int, uint, double)Esempi: math.sign(-42) // -1 |
✓ (v0.21.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Math()acel.NewEnv(). - C++:
- Redattore: aggiungi
MathCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterMathExtensionFunctions()il giornoFunctionRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.math()aCelCompilereCelRuntime. - Python: importa
cel_expr_python.ext.ext_mathe utilizzaExtMath()incel.NewEnv(extensions=[...]).
Libreria di proto
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
proto.getExt |
Recupera il campo di estensione proto2 o il valore predefinito se non impostato. Firme: proto.getExt(msg, extName) -> TEsempi: proto.getExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
proto.hasExt |
Controlla se il campo di estensione proto2 è impostato. Firme: proto.hasExt(msg, extName) -> boolEsempi: proto.hasExt(msg, google.api.expr.test.int32_ext) |
✓ (v0.13.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Protos()acel.NewEnv(). - C++:aggiungi
ProtoExtCompilerLibrary()aCompilerBuilder. Il runtime viene gestito automaticamente. - Java: aggiungi
CelExtensions.protos()aCelCompilereCelRuntime. - Python: importa
cel_expr_python.ext.ext_protoe utilizzaExtProto()incel.NewEnv(extensions=[...]).
Raccolta di elenchi
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
distinct |
Restituisce elementi distinti. Firme: list.distinct() -> listEsempi: [1, 2, 2].distinct() // [1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
flatten |
Appiattisce gli elenchi nidificati. Firme: list.flatten([depth]) -> listEsempi: [[1], [2, 3]].flatten() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.7.1) | ✓ (v0.1.1) | ✗ |
lists.range |
Restituisce l'elenco di numeri interi [0, ..., n-1].Firme: lists.range(int) -> list(int)Esempi: lists.range(3) // [0, 1, 2] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
reverse |
Inverte l'elenco. Firme: list.reverse() -> listEsempi: [1, 2].reverse() // [2, 1] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
slice |
Elenco secondario dei resi (inizio incluso, fine escluso). Firme: list.slice(start, end) -> listEsempi: [1, 2, 3].slice(1, 3) // [2, 3] |
✓ (v0.17.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sort |
Ordina l'elenco degli elementi comparabili. Firme: list.sort() -> listEsempi: [3, 1, 2].sort() // [1, 2, 3] |
✓ (v0.22.0) | ✓ (v0.11.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
sortBy |
Ordina l'elenco in base alla chiave valutata dall'espressione. Firme: list.sortBy(var, expr) -> listEsempi: [{"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 |
Restituisce il primo elemento come facoltativo. Richiede l'estensione Opzionale. Firme: list.first() -> optionalEsempi: [1, 2].first() // optional(1) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
last |
Restituisce l'ultimo elemento come facoltativo. Richiede l'estensione Opzionale. Firme: list.last() -> optionalEsempi: [1, 2].last() // optional(2) |
✓ (v0.23.0) | ✓ (v0.15.0) | ✓ (v0.11.0) | ✓ (v0.1.2) | ✗ |
Come attivare
- Vai: passa
ext.Lists()acel.NewEnv(). - C++:
- Redattore: aggiungi
ListsCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterListsFunctions()il giornoFunctionRegistryeRegisterListsMacros()il giornoMacroRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.lists()aCelCompilereCelRuntime. - Python: attiva tramite
cel.EnvConfigaggiungendolistsall'elencoextensions.
Libreria di set
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
sets.contains |
Verifica se list1 contiene tutti gli elementi di list2. Firme: sets.contains(list1, list2) -> boolEsempi: sets.contains([1, 2], [1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.equivalent |
Verifica se gli elenchi sono equivalenti (contengono gli stessi elementi univoci). Firme: sets.equivalent(list1, list2) -> boolEsempi: sets.equivalent([1, 2], [2, 1, 1]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
sets.intersects |
Verifica se gli elenchi condividono almeno un elemento. Firme: sets.intersects(list1, list2) -> boolEsempi: sets.intersects([1, 2], [2, 3]) // true |
✓ (v0.15.0) | ✓ (v0.10.0) | ✓ (v0.6.0) | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Sets()acel.NewEnv(). - C++:
- Redattore: aggiungi
SetsCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterSetsFunctions()il giornoFunctionRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.sets()aCelCompilereCelRuntime. - Python: attiva tramite
cel.EnvConfigaggiungendosetsall'elencoextensions.
Libreria di stringhe
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
charAt |
Restituisce il carattere all'indice. Firme: string.charAt(int) -> stringEsempi: "hello".charAt(1) // "e" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
indexOf |
Restituisce l'indice della prima occorrenza della sottostringa o -1. Firme: string.indexOf(substr, [start]) -> intEsempi: "hello".indexOf("l") // 2 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
lastIndexOf |
Restituisce l'indice dell'ultima occorrenza della sottostringa o -1. Firme: string.lastIndexOf(substr, [end]) -> intEsempi: "hello".lastIndexOf("l") // 3 |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
join |
Concatena le stringhe. Firme: list(string).join([separator]) -> stringEsempi: ["a", "b"].join("-") // "a-b" |
✓ (v0.10.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
split |
Divide la stringa in base al separatore. Firme: string.split(separator, [limit]) -> list(string)Esempi: "a-b".split("-") // ["a", "b"] |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
substring |
Restituisce la sottostringa (inizio incluso, fine esclusa). Firme: string.substring(start, [end]) -> stringEsempi: "hello".substring(1, 3) // "el" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
trim |
Taglia lo spazio vuoto Unicode. Firme: string.trim() -> stringEsempi: " hello ".trim() // "hello" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
replace |
Sostituisce le occorrenze di old con new. Firme: string.replace(old, new, [limit]) -> stringEsempi: "hello".replace("l", "w") // "hewwo" |
✓ (v0.4.0) | ✓ (v0.10.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
reverse |
Inverte i punti di codice Unicode. Firme: string.reverse() -> stringEsempi: "abc".reverse() // "cba" |
✓ (v0.18.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
lowerAscii |
Converte i caratteri ASCII in minuscolo. Firme: string.lowerAscii() -> stringEsempi: "Hello".lowerAscii() // "hello" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
upperAscii |
Converte i caratteri ASCII in maiuscolo. Firme: string.upperAscii() -> stringEsempi: "Hello".upperAscii() // "HELLO" |
✓ (v0.6.0) | ✓ (v0.11.0) | ✓ (v0.2.0) | ✓ (v0.1.1) | ✗ |
quote |
Esegue l'escape della stringa per una stampa sicura. Firme: strings.quote(string) -> stringEsempi: strings.quote("a\tb") // "\"a\\tb\"" |
✓ (v0.14.0) | ✓ (v0.14.0) | ✓ (v0.13.0) | ✓ (v0.1.1) | ✗ |
format |
Formatta la stringa utilizzando i segnaposto in stile printf. Firme: string.format(list) -> stringEsempi: "str: %s, int: %d".format(["a", 1]) // "str: a, int: 1" |
✓ (v0.14.0) | ✓ (v0.11.0) | ✗ | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Strings()acel.NewEnv(). - C++:
- Redattore: aggiungi
StringsCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterStringsFunctions()il giornoFunctionRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.strings()aCelCompilereCelRuntime. - Python: importa
cel_expr_python.ext.ext_stringse utilizzaExtStrings()incel.NewEnv(extensions=[...]).
Libreria di espressioni regolari
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
regex.replace |
Sostituisce le corrispondenze con la stringa sostitutiva (supporta i riferimenti inversi). Firme: regex.replace(target, pat, repl, [limit]) -> stringEsempi: 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 |
Restituisce la prima corrispondenza del pattern (deve avere un gruppo Capture). Firme: regex.extract(target, pat) -> optional(string)Esempi: regex.extract("a123b", r"(\d+)") // optional("123") |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
regex.extractAll |
Restituisce tutte le corrispondenze del pattern (deve avere un gruppo Capture). Firme: regex.extractAll(target, pat) -> list(string)Esempi: regex.extractAll("a1b2", r"(\d+)") // ["1", "2"] |
✓ (v0.25.1) | ✓ (v0.13.0) | ✓ (v0.10.1) | ✓ (v0.1.1) | ✗ |
Come attivare
- Vai: passa
ext.Regex()acel.NewEnv(). - C++:
- Redattore: aggiungi
RegexExtCompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterRegexExtensionFunctions()il giornoFunctionRegistry.
- Redattore: aggiungi
- Java: aggiungi
CelExtensions.regex()aCelCompilereCelRuntime. - Python: attiva tramite
cel.EnvConfigaggiungendoregexeoptionalall'elencoextensions.
Comprensioni a due variabili
| Macro | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
all |
Valutazione di cortocircuito dell'operatore logico AND su chiave/indice e valore. Firme: list.all(i, v, pred) -> boolmap.all(k, v, pred) -> boolEsempi: [1, 2].all(i, v, v > 0) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
exists |
Valore OR logico di cortocircuito su chiave/indice e valore. Firme: list.exists(i, v, pred) -> boolmap.exists(k, v, pred) -> boolEsempi: [1, 2].exists(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
existsOne |
Verifica se esattamente una coppia soddisfa il predicato. Firme: list.existsOne(i, v, pred) -> boolmap.existsOne(k, v, pred) -> boolEsempi: [1, 2].existsOne(i, v, v == 2) // true |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformList |
Trasforma/filtra l'elenco/la mappa in un elenco. Firme: list.transformList(i, v, [filter], transform) -> listmap.transformList(k, v, [filter], transform) -> listEsempi: [1, 2].transformList(i, v, v * 2) // [2, 4] |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMap |
Trasforma i valori di un elenco/mappa in una mappa (le chiavi rimangono fisse). Firme: list.transformMap(i, v, [filter], transform) -> mapmap.transformMap(k, v, [filter], transform) -> mapEsempi: [1, 2].transformMap(i, v, v * 2) // {0: 2, 1: 4} |
✓ (v0.22.0) | ✓ (v0.14.0) | ✓ (v0.11.0) | ✓ (v0.1.1) | ✗ |
transformMapEntry |
Si trasforma in una mappa. Firme: list.transformMapEntry(i, v, [filter], transform_entry) -> mapmap.transformMapEntry(k, v, [filter], transform_entry) -> mapEsempi: [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) | ✗ |
Come attivare
- Vai: passa
ext.TwoVarComprehensions()acel.NewEnv(). - C++:
- Redattore: aggiungi
ComprehensionsV2CompilerLibrary()aCompilerBuilder. - Runtime: chiama
RegisterComprehensionsV2Functions()suFunctionRegistryeRegisterComprehensionsV2Macros()suMacroRegistry.
- Redattore: aggiungi
- Java:aggiungi
CelExtensions.comprehensions()ai builderCelCompilereCelRuntime. - Python:attiva tramite
cel.EnvConfigaggiungendotwo-var-comprehensionsall'elencoextensions.
Libreria dei tipi nativi
| Funzionalità | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| Struct nativi | Registrazione e creazione di istanze di tipi nativi host (struct Go / POJO Java) in CEL. Esempi: Account{id: 123} (istanza POJO Java in CEL) |
✓ (v0.13.0) | ✗ | ✓ (v0.13.0) | ✗ | ✗ |
Come attivare
- Vai:passa
cel.NativeTypes(...)oext.NativeTypes(...)(fornendo i tipi di riflessione) acel.NewEnv(). - C++: non supportato.
- Java: aggiungi
CelExtensions.nativeTypes()(che fornisce classi Java) ai generatoriCelCompilereCelRuntime. - Python:non supportato.
Network Library
La libreria Network fornisce funzioni per l'analisi, la convalida e la manipolazione di indirizzi IP e blocchi CIDR.
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
ip |
Analizza una stringa in un indirizzo IP o estrae l'IP da un CIDR. Firme: ip(string) -> IPCIDR.ip() -> IPEsempi: ip("192.168.0.1")cidr("192.168.0.0/24").ip() |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isIP |
Controlla se una stringa è un indirizzo IP valido. Firme: isIP(string) -> boolEsempi: isIP("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
ip.isCanonical |
Verifica se una stringa di indirizzo IP è nel formato canonico. Firme: ip.isCanonical(string) -> boolEsempi: ip.isCanonical("192.168.0.1") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
cidr |
Analizza una stringa in un blocco CIDR. Firme: cidr(string) -> CIDREsempi: cidr("192.168.0.0/24") |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isCIDR |
Controlla se una stringa è un blocco CIDR valido. Firme: isCIDR(string) -> boolEsempi: isCIDR("192.168.0.0/24") // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsIP |
Verifica se un blocco CIDR contiene un indirizzo IP. Firme: CIDR.containsIP(IP) -> boolCIDR.containsIP(string) -> boolEsempi: cidr("192.168.0.0/24").containsIP(ip("192.168.0.1")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
containsCIDR |
Verifica se un blocco CIDR contiene un altro blocco CIDR. Firme: CIDR.containsCIDR(CIDR) -> boolCIDR.containsCIDR(string) -> boolEsempi: cidr("192.168.0.0/16").containsCIDR(cidr("192.168.1.0/24")) // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
family |
Restituisce la famiglia IP (4 per IPv4, 6 per IPv6). Firme: IP.family() -> intEsempi: ip("192.168.0.1").family() // 4 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isGlobalUnicast |
Verifica se l'IP è un indirizzo unicast globale. Firme: IP.isGlobalUnicast() -> boolEsempi: ip("192.168.0.1").isGlobalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalMulticast |
Verifica se l'IP è un indirizzo multicast locale rispetto al collegamento. Firme: IP.isLinkLocalMulticast() -> boolEsempi: ip("224.0.0.1").isLinkLocalMulticast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLinkLocalUnicast |
Verifica se l'IP è un indirizzo unicast locale al collegamento. Firme: IP.isLinkLocalUnicast() -> boolEsempi: ip("169.254.0.1").isLinkLocalUnicast() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isLoopback |
Verifica se l'IP è un indirizzo di loopback. Firme: IP.isLoopback() -> boolEsempi: ip("127.0.0.1").isLoopback() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isMask |
Controlla se il CIDR è una subnet mask valida. Firme: CIDR.isMask() -> boolEsempi: cidr("255.255.255.0/24").isMask() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
isUnspecified |
Verifica se l'IP è un indirizzo non specificato (ad es. 0.0.0.0).Firme: IP.isUnspecified() -> boolEsempi: ip("0.0.0.0").isUnspecified() // true |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
masked |
Restituisce il blocco CIDR mascherato. Firme: CIDR.masked() -> CIDREsempi: cidr("192.168.0.1/24").masked() // 192.168.0.0/24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
prefixLength |
Restituisce la lunghezza del prefisso del blocco CIDR. Firme: CIDR.prefixLength() -> intEsempi: cidr("192.168.0.0/24").prefixLength() // 24 |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
string |
Converte l'indirizzo IP o il blocco CIDR in una stringa. Firme: string(IP) -> stringstring(CIDR) -> stringEsempi: string(ip("192.168.0.1")) // "192.168.0.1" |
✓ (v0.29.0) | ✗ | ✗ | ✗ | ✗ |
Come attivare
- Vai: passa
ext.Network()acel.NewEnv(). - C++: non supportato.
- Java:non supportato.
- Python:non supportato.
Libreria JWT
La libreria JWT fornisce tipi di dati e funzioni di assistenza per l'analisi dei token JWT (JSON Web Token) e l'ispezione di rivendicazioni standard e personalizzate.
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
jwt.parse |
Analizza una stringa di token non elaborata in un jwt.Token strutturato racchiuso in un valore facoltativo.Firme: jwt.parse(string) -> optional(jwt.Token)Esempi: jwt.parse(token_string).hasValue() |
✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
claim |
Esegue una query su un valore di rivendicazione personalizzata in base al nome della chiave dal payload del token. Firme: jwt.Token.claim(string) -> optional(dyn)optional(jwt.Token).claim(string) -> optional(dyn)Esempi: jwt.parse(token).claim("tenant").orValue("") |
✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
presentedBy |
Verifica che l'emittente e il pubblico del token corrispondano ai valori previsti. Firme: jwt.Token.presentedBy(string, string) -> booloptional(jwt.Token).presentedBy(string, string) -> boolEsempi: jwt.parse(token).presentedBy("https://auth.example.com", "https://api.example.com") |
✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Come attivare
- Vai a: importa
cel.dev/cel-go/ext/security/jwte passajwt.Library()acel.NewEnv(). - C++: non supportato.
- Java:non supportato.
- Python:non supportato.
Libreria HMAC
La libreria HMAC fornisce funzioni crittografiche per calcolare e verificare i codici HMAC (Hash-based Message Authentication Code) su stringhe e sequenze di byte.
| Funzione | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
hmac.compute |
Calcola i byte della firma HMAC non elaborata utilizzando l'algoritmo e la chiave segreta specificati. Firme: hmac.compute(string, string|bytes, string|bytes) -> bytesEsempi: hmac.compute(hmac.SHA256, "secret", "message") |
✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
hmac.verify |
Verifica se una firma HMAC corrisponde al digest previsto. Firme: hmac.verify(string, string|bytes, string|bytes, string|bytes) -> boolEsempi: hmac.verify(hmac.SHA256, secret, msg, expected_sig) // true |
✓ (v0.32.0) | ✗ | ✗ | ✗ | ✗ |
Come attivare
- Vai a: importa
cel.dev/cel-go/ext/security/hmace passahmac.Library()acel.NewEnv(). - C++: non supportato.
- Java:non supportato.
- Python:non supportato.
5. Funzionalità avanzate
Riepilogo delle funzionalità avanzate
| Funzionalità | Descrizione | Go | C++ | Java | Python | C |
|---|---|---|---|---|---|---|
| Valutazione parziale | Valuta con input mancanti; restituisce valori sconosciuti o un'espressione semplificata. | ✓³ | ✓⁴ | ✓⁴ | ✗ | ✗ |
| Valutazione asincrona | Esecuzione simultanea non bloccante delle funzioni di estensione. | ✓⁵ | ✗ | ✓⁶ | ✗ | ✗ |
| Strumenti di convalida AST | Controlli di analisi statica sull'AST controllato dopo il controllo dei tipi. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Ottimizzatori AST | Riscritture AST (constant folding, inlining, CSE) per migliorare il rendimento. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Compilatore di criteri CEL | Compila le strutture delle policy basate su YAML in AST CEL standard. | ✓ | ✓ | ✓ | ✗ | ✗ |
| Formal Verification | Dimostra invarianti di sicurezza, soddisfacibilità, validità ed equivalenza AST. | ✗ | ✗ | ✓ (v0.14.0) | ✗ | ✗ |
³ Go supporta la generazione di un AST residuo (AST potata). ⁴ C++ e Java supportano
la restituzione di UnknownSet / CelUnknownSet in fase di runtime, ma non espongono API pubbliche
per la generazione di AST residui. ⁵ Go utilizza AsyncBinding / AsyncOp per restituire
i canali. ⁶ Java utilizza CelAsyncRuntime restituendo ListenableFuture.
Valutazione parziale (sconosciuti)
La valutazione parziale consente di valutare un'espressione quando è noto solo un sottoinsieme delle variabili di input (argomenti). Anziché non riuscire, la valutazione produce un risultato che indica cosa manca o un'espressione semplificata.
- Vai:supporto completo. Consente di definire un
PartialActivationcon pattern di attributi sconosciuti. La valutazione restituisce un valoretypes.Unknown. Go supporta la generazione di un AST residuo (Env.ResidualAst), ovvero un AST semplificato che contiene solo le parti dell'espressione che non è stato possibile valutare. - C++:supporta i valori
Unknown. I pattern degli attributi sconosciuti vengono configurati tramiteActivation::set_unknown_attribute_patterns. Valutazione restituisce unUnknownSet. L'API pubblica al momento non espone la generazione di AST residui. - Java:supporta la valutazione parziale tramite
PartialVarspassato aProgram.eval(). La valutazione restituisce unCelUnknownSet. L'API pubblica non espone attualmente la generazione di AST residui. - Python / C: nessun supporto nativo.
Valutazione asincrona
La valutazione asincrona consente alle espressioni CEL di chiamare funzioni che vengono eseguite in modo asincrono (ad es. effettuando RPC o query di database) e di bloccare la valutazione finché i risultati non sono disponibili, senza bloccare il thread di esecuzione principale.
- Go: supporta gli overload di funzioni asincrone tramite
AsyncBindingeAsyncOp. Le funzioni asincrone restituiscono un canale Go (<-chan ref.Val) e l'interprete gestisce l'esecuzione e la sincronizzazione simultanee. - Java:supporta la valutazione asincrona tramite
CelAsyncRuntimeeAsyncProgram. UtilizzaListenableFutureper rappresentare i valori in attesa e completa automaticamente la valutazione man mano che i futures vengono risolti. - C++ / Python / C: nessun supporto integrato.
Strumenti di convalida AST
I validatori eseguono l'analisi statica sull'AST controllato dopo il controllo del tipo per applicare vincoli specifici del dominio prima dell'esecuzione del programma.
- Go: supporta l'interfaccia
ASTValidator. I validatori canonici includonocel.validator.duration,cel.validator.timestamp,cel.validator.matches(regex),cel.validator.homogeneous_literalsecel.validator.comprehension_nesting_limit. - C++:supporta
cel::Validator. Le convalide canoniche includonoAstDepthValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,MatchesValidatoreTimestampLiteralValidator. - Java: supporta
CelValidatoreCelAstValidator. I validatori canonici includonoAstDepthLimitValidator,ComprehensionNestingLimitValidator,DurationLiteralValidator,HomogeneousLiteralValidator,RegexLiteralValidatoreTimestampLiteralValidator. - Python / C: nessun supporto diretto.
Ottimizzatori AST
Gli ottimizzatori riscrivono l'AST per migliorare le prestazioni di esecuzione. Gli ottimizzatori rientrano in una delle due categorie: statici e di runtime. C++, Java e Go supportano l'ottimizzazione del runtime. CEL Java e Go supportano anche gli ottimizzatori statici.
Le ottimizzazioni tipiche includono la costante di folding (pre-valutazione delle sottoespressioni con input costanti) e l'eliminazione delle sottoespressioni comuni (CSE).
- Go: supporta il folding AST durante la compilazione/pianificazione.
- C++:supporta la riduzione delle costanti tramite l'estensione
cel::extensions::EnableConstantFoldingin fase di pianificazione. - Java:supporta l'interfaccia
CelOptimizer. Gli ottimizzatori canonici includonoConstantFoldingOptimizer(che supporta l'attraversamento pre-ordine, il ripiegamento costante dei messaggi Protobuf e l'eliminazione di aggregati o facoltativi),InliningOptimizereSubexpressionOptimizer(CSE). - Python / C: nessun supporto diretto.
Compilatore di policy CEL
CEL Policy è un formato basato su YAML per comporre più espressioni CEL insieme a variabili, blocchi di corrispondenza, output condizionali e regole nidificate. È progettato per motori di criteri complessi (come Kubernetes Admission Control) in cui le singole espressioni CEL diventerebbero illeggibili.
Per la definizione formale del linguaggio, la sintassi e la suite di conformità, consulta la specifica dei criteri CEL.
Il compilatore di policy compila queste policy YAML in un unico AST CEL standard, il che significa che sono completamente compatibili con i runtime CEL standard ed ereditano tutte le garanzie di prestazioni e sicurezza.
- Go: supportato tramite la policy Go (incluse le semantiche di valutazione delle regole aggregate).
- C++:supportato tramite le norme C++.
- Java:supportato tramite norme Java (inclusi semantica di valutazione delle regole aggregate e identificatori di tipo abbreviati nelle configurazioni delle norme).
- Python / C:non supportato direttamente.
Framework di verifica formale
Il framework di verifica formale consente agli utenti di dimostrare matematicamente l'invarianza della sicurezza, l'equivalenza logica, la soddisfacibilità e la validità tra le espressioni CEL e le policy CEL strutturate.
- Java:supportato tramite CEL Java Verifier
(
dev.cel:verifieredev.cel:verifier-cli). Le funzionalità includono la soddisfacibilità (isSatisfiable) con la generazione di input di testimonianza, la validità (isAlwaysTrue) con la generazione di controesempi, il controllo del modello vincolato (BMC) per le comprensioni, le prove di equivalenza logica tra gli AST e la verifica invariante delle norme personalizzateassume/assert. - Go / C++ / Python / C: sono supportati indirettamente tramite la toolchain da riga di comando Java.
Per un'introduzione ed esempi reali, consulta il post del blog di Google Open Source: Securing the era agentica: Introducing formal verification for CEL.