> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/agentgateway/agentgateway/llms.txt
> Use this file to discover all available pages before exploring further.

# CEL reference overview

> Common Expression Language (CEL) in Agentgateway: where it is used, what context is available, and how to write expressions.

# CEL reference overview

[Common Expression Language (CEL)](https://cel.dev/) is a fast, safe expression language used throughout Agentgateway to evaluate user-defined expressions against live request data. CEL expressions are evaluated at request time against a rich context of variables describing the request, response, authentication state, and more.

CEL is not as general-purpose as Lua or WASM, but it is significantly faster and sufficient for the majority of gateway policy use cases.

## Where CEL is used

Agentgateway uses CEL in several places across the request processing pipeline:

* **Authorization rules** — define which requests are allowed or denied
* **Rate limiting conditions** — select the attribute to rate limit on (for example, per user or per API key)
* **Logs and traces** — define which request attributes to include as structured fields
* **Header and body transformations** — compute new header or body values
* **MCP authorization** — control which MCP tools, prompts, and resources a caller can access

## Expression syntax

CEL expressions are single-line expressions that evaluate to a value. They support:

| Syntax          | Description                      | Example                                          |
| --------------- | -------------------------------- | ------------------------------------------------ |
| Field access    | Dot notation                     | `request.method`                                 |
| Map lookup      | Bracket notation                 | `request.headers["x-api-key"]`                   |
| Comparison      | `==`, `!=`, `<`, `<=`, `>`, `>=` | `response.code >= 500`                           |
| Logical         | `&&`, `\|\|`, `!`                | `jwt.role == "admin" && request.method == "GET"` |
| Membership      | `in`                             | `mcp.tool.name in ["read_file", "list_files"]`   |
| String methods  | Built-in string functions        | `request.path.startsWith("/api")`                |
| Ternary         | `condition ? a : b`              | `has(jwt.sub) ? jwt.sub : "anonymous"`           |
| Field existence | `has()`                          | `has(jwt.sub)`                                   |

## Available context objects

Agentgateway exposes the following top-level objects to CEL expressions. Not all objects are available in all contexts — for example, `response` is not available during a request-phase transformation, and `mcp` is only present for MCP requests.

| Object       | Description                                                                     |
| ------------ | ------------------------------------------------------------------------------- |
| `request`    | Attributes of the incoming HTTP request (method, path, headers, body, timing)   |
| `response`   | Attributes of the HTTP response (status code, headers, body)                    |
| `source`     | Attributes of the downstream connection (IP, port, mTLS identity)               |
| `env`        | Selected Kubernetes environment attributes (pod name, namespace, gateway)       |
| `jwt`        | Claims from a verified JWT token (present only when JWT auth is enabled)        |
| `apiKey`     | Claims from a verified API key (present only when API key auth is enabled)      |
| `basicAuth`  | Basic authentication credentials (present only when basic auth is enabled)      |
| `mcp`        | MCP-specific context: the tool, prompt, or resource being accessed              |
| `llm`        | LLM-specific context: model, token counts, prompt, completion, parameters       |
| `llmRequest` | Raw LLM request before processing (available only during LLM policy evaluation) |
| `backend`    | Information about the selected backend (name, type, protocol)                   |
| `extauthz`   | Dynamic metadata from external authorization filters                            |
| `extproc`    | Dynamic metadata from external processing filters                               |
| `metadata`   | Values set by transformation metadata expressions                               |

<Note>
  Agentgateway uses static analysis at configuration load time to determine which context fields your expressions reference. Fields that are not referenced are not collected, so you only pay for what you use. This is especially important for `request.body` and `response.body`, which require buffering.
</Note>

## Practical examples

<CodeGroup>
  ```cel Method check theme={null}
  request.method == "GET"
  ```

  ```cel JWT claim check theme={null}
  jwt.sub == "admin"
  ```

  ```cel MCP tool check theme={null}
  mcp.tool.name == "read_file"
  ```

  ```cel Health check on response theme={null}
  response.code >= 500
  ```

  ```cel Combine JWT and MCP context theme={null}
  jwt.sub == "test-user" && mcp.tool.name == "add"
  ```

  ```cel Restrict by source IP range theme={null}
  cidr("10.0.0.0/8").containsIP(source.address)
  ```

  ```cel Allow based on nested JWT claim theme={null}
  mcp.tool.name == "printEnv" && jwt.nested.key == "value"
  ```

  ```cel Log the user agent header theme={null}
  request.headers["user-agent"]
  ```
</CodeGroup>

## Custom CEL functions

Agentgateway extends CEL with custom functions beyond the standard library.

<AccordionGroup>
  <Accordion title="JSON and encoding">
    | Function        | Description                          | Example                             |
    | --------------- | ------------------------------------ | ----------------------------------- |
    | `json`          | Parse a string or bytes as JSON      | `json(request.body).some_field`     |
    | `toJson`        | Convert a CEL value to a JSON string | `toJson({"hello": "world"})`        |
    | `base64.encode` | Encode a string to base64            | `base64.encode("hello")`            |
    | `base64.decode` | Decode a base64 string to bytes      | `string(base64.decode("aGVsbG8K"))` |
  </Accordion>

  <Accordion title="JWT and authentication">
    | Function                | Description                                         | Example                                                                  |
    | ----------------------- | --------------------------------------------------- | ------------------------------------------------------------------------ |
    | `unvalidatedJwtPayload` | Parse a JWT payload without verifying the signature | `unvalidatedJwtPayload(request.headers.authorization.split(" ")[1]).sub` |
  </Accordion>

  <Accordion title="Control flow and variables">
    | Function    | Description                                                          | Example                                                                |
    | ----------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
    | `with`      | Bind an expression result to a variable (CEL has no native bindings) | `json(request.body).with(b, b.field_a + b.field_b)`                    |
    | `variables` | Expose all context variables as a single value                       | `variables`                                                            |
    | `default`   | Return a fallback if the expression fails to resolve                 | `default(request.headers["missing-header"], "fallback")`               |
    | `coalesce`  | Return the first non-null, non-error expression                      | `coalesce(request.headers["x-id"], json(request.body).id, "fallback")` |
    | `fail`      | Unconditionally fail an expression                                   | `fail`                                                                 |
  </Accordion>

  <Accordion title="Map and collection utilities">
    | Function           | Description                                                        | Example                                 |
    | ------------------ | ------------------------------------------------------------------ | --------------------------------------- |
    | `mapValues`        | Apply a function to all values in a map                            | —                                       |
    | `filterKeys`       | Return a new map keeping only keys matching a predicate            | `{"a":1,"b":2}.filterKeys(k, k == "a")` |
    | `merge`            | Join two maps (right-hand values win on key conflict)              | `{"a":2,"k":"v"}.merge({"a":3})`        |
    | `flatten`          | Flatten a list or struct into many fields (logging/tracing only)   | `flatten(request.headers)`              |
    | `flattenRecursive` | Like `flatten` but flattens multiple levels (logging/tracing only) | —                                       |
  </Accordion>

  <Accordion title="String and regex">
    | Function       | Description                                      | Example                                                    |
    | -------------- | ------------------------------------------------ | ---------------------------------------------------------- |
    | `regexReplace` | Replace substrings matching a regular expression | `"/id/1234/data".regexReplace("/id/[0-9]*/", "/id/{id}/")` |
    | `random`       | Generate a random float from 0.0 to 1.0          | `random() < 0.1`                                           |
    | `uuid`         | Generate a random UUIDv4                         | `uuid()`                                                   |
  </Accordion>

  <Accordion title="Standard library highlights">
    All standard CEL functions are available, including collections (`contains`, `size`, `has`, `map`, `filter`, `all`, `exists`), type conversion (`string`, `bytes`, `double`, `int`, `uint`), strings (`startsWith`, `endsWith`, `matches`, `trim`, `replace`, `split`, `substring`), time functions (`duration`, `timestamp`, `getFullYear`, `getMonth`), and IP/CIDR helpers (`isIP`, `ip`, `cidr`).
  </Accordion>
</AccordionGroup>

## Header views

The `request.headers` and `response.headers` objects expose chainable methods for common header access patterns:

| Method          | Description                                               | Example                                     |
| --------------- | --------------------------------------------------------- | ------------------------------------------- |
| Direct access   | Returns a string for single values, list for multiple     | `request.headers["content-type"]`           |
| `.redacted()`   | Replace sensitive values with `"<redacted>"`              | `request.headers.redacted().authorization`  |
| `.join()`       | Join all entries for a header with `,`                    | `request.headers.join()["x-forwarded-for"]` |
| `.raw()`        | Return raw entries as a list                              | `request.headers.raw()["set-cookie"]`       |
| `.split()`      | Split entries on `,` and return as a list                 | `request.headers.split()["accept"]`         |
| `.cookie(name)` | Parse the `Cookie` header and return a named cookie value | `request.headers.cookie("session")`         |

## Query string access

`request.pathAndQuery` and `request.uri` expose query-aware methods:

| Method                   | Description                                       | Example                                        |
| ------------------------ | ------------------------------------------------- | ---------------------------------------------- |
| `.query(name)`           | Return all values for a query parameter as a list | `request.pathAndQuery.query("foo") == ["bar"]` |
| `.addQuery(name, value)` | Return a new string with the parameter appended   | `request.pathAndQuery.addQuery("foo", "qux")`  |
| `.setQuery(name, value)` | Return a new string with the parameter replaced   | `request.uri.setQuery("foo", "qux")`           |

## Reference pages

<CardGroup cols={3}>
  <Card title="Request context" icon="arrow-right-to-bracket" href="/reference/cel/request-context">
    Full reference for `request`, `response`, `source`, `env`, `jwt`, `apiKey`, `basicAuth`, `backend`, and metadata objects.
  </Card>

  <Card title="MCP context" icon="plug" href="/reference/cel/mcp-context">
    Full reference for the `mcp` object: tools, prompts, and resources.
  </Card>

  <Card title="LLM context" icon="microchip" href="/reference/cel/llm-context">
    Full reference for the `llm` object: model, token counts, prompt, completion, and parameters.
  </Card>
</CardGroup>
