For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Conditional policies
Run different variants of a policy on the same route based on a CEL expression evaluated against the request.
Conditional policies
A policy normally applies the same configuration to every request on the route it attaches to. Conditional execution lets you nest a list of policy variants under a conditional field. Each variant has a CELCEL (Common Expression Language)A simple expression language used throughout agentgateway to enable flexible configuration. CEL expressions can access request context, JWT claims, and other variables to make dynamic decisions. expression that determines whether it applies. For each request, agentgateway evaluates the entries in order and runs the first variant whose expression returns true.
A common use case is choosing between two external authorization servers based on the request. For example, you might send admin paths to a stricter authorization server and route everything else to a standard one.
The following policies support conditional execution:
- External authorization (
extAuth) - External processing (
extProc) - Rate limiting (
rateLimit) - Transformations (
transformation) - Direct response (
directResponse)
For details on how to write the CEL expressions that go in each condition field, see the CEL expressions reference.
How conditional execution works
- First match wins. Agentgateway evaluates each
conditionalentry in the order you list them and runs the first variant whoseconditionevaluates totrue. Subsequent entries are not evaluated. - Optional fallback. An entry without a
conditionis the unconditional fallback. It must be the last entry in the list, and you can have at most one. If no condition matches and there is no fallback, the policy does not run for that request. - Mutually exclusive with the inline form. For a given policy, set either the top-level fields or the
conditionallist, not both. - Limits. A
conditionallist can have between 1 and 64 entries.
Examples
Review the following examples to see how conditional policies work. Conditional execution works the same way for every supported policy. The following examples show one configuration per policy type.
Multiple ext auth servers
Route to one of two external authorization servers based on the request path. Requests to a path that starts with /admin go to a stricter authorization server. The fallback entry handles every other request.
# yaml-language-server: $schema=https://agentgateway.dev/schema/config
binds:
- port: 3000
listeners:
- routes:
- backends:
- host: localhost:8000
policies:
extAuthz:
conditional:
# Admin paths go to the stricter authorization server.
- condition: request.path.startsWith("/admin")
host: localhost:9000
protocol:
grpc: {}
failureMode: deny
# Fallback for every other request. No condition, must be last.
- host: localhost:9001
protocol:
grpc: {}
failureMode: denyDifferent rate limits
Apply a stricter rate limit to write requests and a looser limit to all other traffic.
binds:
- port: 3000
listeners:
- routes:
- backends:
- host: localhost:8000
policies:
localRateLimit:
conditional:
- condition: request.method == "POST" || request.method == "PUT" || request.method == "DELETE"
maxTokens: 10
tokensPerFill: 10
fillInterval: 1m
type: requests
- maxTokens: 100
tokensPerFill: 100
fillInterval: 1m
type: requestsTransform internal traffic
Add a tracing header when the request includes an x-internal: true header. With no fallback entry, agentgateway skips the transformation on every other request.
binds:
- port: 3000
listeners:
- routes:
- backends:
- host: localhost:8000
policies:
transformations:
conditional:
- condition: request.headers["x-internal"] == "true"
request:
add:
x-trace-source: '"internal"'Filter LLM chats with extproc
Send requests on a path that starts with /v1/chat through an external processor. Every other request bypasses the processor.
binds:
- port: 3000
listeners:
- routes:
- backends:
- host: localhost:8000
policies:
extProc:
conditional:
- condition: request.path.startsWith("/v1/chat")
host: localhost:9100
failureMode: failClosedShort-circuit deprecated paths with a direct response
Return a 410 Gone response for any path that starts with /v0/. Every other request proceeds to the backend.
binds:
- port: 3000
listeners:
- routes:
- backends:
- host: localhost:8000
policies:
directResponse:
conditional:
- condition: request.path.startsWith("/v0/")
status: 410
body: "This API version is no longer available. Use /v1/."