CEL expressions

CEL expressions

Agentgateway uses the CEL expression language throughout the project to enable flexibility. CEL allows writing simple expressions based on the request context that evaluate to some result.

Example expressions

Review the following examples of expressions for different uses cases.

Default function

You can use the default function to provide a fallback value if the expression cannot be resolved.

Request header fallback with example of an anonymous user:

default(request.headers["x-user-id"], "anonymous")

Nested object fallback with example of light theme:

default(json(request.body).user.preferences.theme, "light")

JWT claim fallback with example of default “user” role:

default(jwt.role, "user")

Logs, traces, and observability

# Include logs where there was no response or there was an error
filter: |
   !has(response) || response.code > 299
fields:
  add:
    user.agent: 'request.headers["user-agent"]'
    # A static string. Note the expression is a string, and it returns a string, hence the double quotes.
    span.name: '"openai.chat"'
    gen_ai.usage.prompt_tokens: 'llm.input_tokens'
    # Parse the JSON request body, and conditionally log...
    # * If `type` is sum, val1+val2
    # * Else, val3
    # Example JSON request: `{"type":"sum","val1":2,"val2":3,"val4":"hello"}`
    json.field: |
      json(request.body).with(b,
         b.type == "sum" ?
           b.val1 + b.val2 :
           b.val3
      )

Authorization

mcpAuthorization:
  rules:
  # Allow anyone to call 'echo'
  - 'mcp.tool.name == "echo"'
  # Only the test-user can call 'add'
  - 'jwt.sub == "test-user" && mcp.tool.name == "add"'
  # Any authenticated user with the claim `nested.key == value` can access 'printEnv'
  - 'mcp.tool.name == "printEnv" && jwt.nested.key == "value"'

Rate limiting

remoteRateLimit:
   descriptors:
   # Rate limit requests based on a header, whether the user is authenticated, and a static value (used to match a specific rate limit rule on the rate limit server)
   - entries:
      - key: some-static-value
        value: '"something"'
      - key: organization
        value: 'request.headers["x-organization"]'
      - key: authenticated
        value: 'has(jwt.sub)'

Context reference

As you write expressions, keep the following context in mind.

Functions and variables

When using CEL in agentgateway, you can use the following variables and functions.

Field Description
request request contains attributes about the incoming HTTP request
request.method The HTTP method of the request. For example, GET
request.uri The complete URI of the request. For example, http://example.com/path.
request.host
request.scheme
request.path The path of the request URI. For example, /path.
request.headers The headers of the request.
request.body The body of the request. Warning: accessing the body will cause the body to be buffered.
request.startTime The (pre-rendered) time the request started
request.endTime The (pre-rendered) time the request completed
response response contains attributes about the HTTP response
response.code The HTTP status code of the response.
response.body The body of the response. Warning: accessing the body will cause the body to be buffered.
jwt jwt contains the claims from a verified JWT token. This is only present if the JWT policy is enabled.
llm llm contains attributes about an LLM request or response. This is only present when using an ai backend.
llm.streaming Whether the LLM response is streamed.
llm.requestModel The model requested for the LLM request. This may differ from the actual model used.
llm.responseModel The model that actually served the LLM response.
llm.provider The provider of the LLM.
llm.inputTokens The number of tokens in the input/prompt.
llm.outputTokens The number of tokens in the output/completion.
llm.totalTokens The total number of tokens for the request.
llm.prompt The prompt sent to the LLM. Warning: accessing this has some performance impacts for large prompts.
llm.prompt[].role
llm.prompt[].content
llm.completion The completion from the LLM. Warning: accessing this has some performance impacts for large responses.
llm.params The parameters for the LLM request.
llm.params.temperature
llm.params.top_p
llm.params.frequency_penalty
llm.params.presence_penalty
llm.params.seed
llm.params.max_tokens
source source contains attributes about the source of the request.
source.address The IP address of the downstream connection.
source.port The port of the downstream connection.
source.identity The (Istio SPIFFE) identity of the downstream connection, if available.
source.identity.trustDomain The trust domain of the identity.
source.identity.namespace The namespace of the identity.
source.identity.serviceAccount The service account of the identity.
mcp mcp contains attributes about the MCP request.
mcp.(any)(1)tool
mcp.(any)(1)tool.target The target of the resource
mcp.(any)(1)tool.name The name of the resource
mcp.(any)(1)prompt
mcp.(any)(1)prompt.target The target of the resource
mcp.(any)(1)prompt.name The name of the resource
mcp.(any)(1)resource
mcp.(any)(1)resource.target The target of the resource
mcp.(any)(1)resource.name The name of the resource
backend backend contains information about the backend being used.
backend.name The name of the backend being used. For example, my-service or service/my-namespace/my-service:8080.
backend.type The type of backend. For example, ai, mcp, static, dynamic, or service.
backend.protocol The protocol of backend. For example, http, tcp, a2a, mcp, or llm.
extauthz extauthz contains dynamic metadata from ext_authz filters

Functions by policy type

Certain fields are populated only if they are referenced in a CEL expression. This way, agentgateway avoids expensive buffering of request bodies if no CEL expression depends on the body.

Depending on the policy, different fields are accessible based on when in the request processing they are applied.

Policy Available Variables
Transformation source, request, jwt
Remote Rate Limit source, request, jwt
HTTP Authorization source, request, jwt
MCP Authorization source, request, jwt, mcp
Logging source, request, jwt, mcp, response, llm
Tracing source, request, jwt, mcp, response, llm
Metrics source, request, jwt, mcp, response, llm

Functions for all policy types

The following functions can be used in all policy types.

Function Purpose
json Parse a string or bytes as JSON. Example: json(request.body).some_field.
with CEL does not allow variable bindings. with allows doing this. Example: json(request.body).with(b, b.field_a + b.field_b)
variables variables exposes all of the variables available as a value. CEL otherwise does not allow accessing all variables without knowing them ahead of time. Warning: this automatically enables all fields to be captured.
map_values map_values applies a function to all values in a map. map in CEL only applies to map keys.
flatten Usable only for logging and tracing. flatten will flatten a list or struct into many fields. For example, defining headers: 'flatten(request.headers)' would log many keys like headers.user-agent: "curl", etc.
flatten_recursive Usable only for logging and tracing. Like flatten but recursively flattens multiple levels.
base64_encode Encodes a string to a base64 string. Example: base64_encode("hello").
base64_decode Decodes a string in base64 format. Example: string(base64_decode("aGVsbG8K")). Warning: this returns bytes, not a String. Various parts of agentgateway will display bytes in base64 format, which may appear like the function does nothing if not converted to a string.
random Generates a number float from 0.0-1.0

Standard functions

Additionally, the following standard functions are available for all policy types, too.

  • contains, size, has, map, filter, all, max, startsWith, endsWith, string, bytes, double, exists, exists_one, int, uint, matches.
  • Duration/time functions: duration, timestamp, getFullYear, getMonth, getDayOfYear, getDayOfMonth, getDate, getDayOfWeek, getHours, getMinutes, getSeconds, getMilliseconds.
  • From the strings extension: charAt, indexOf, join, lastIndexOf, lowerAscii, upperAscii, trim, replace, split, substring.