For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
HTTP authorization
Attaches to:
HTTP authorizationAuthorization (AuthZ)The process of determining what actions an authenticated user or service is allowed to perform. Agentgateway supports HTTP authorization, MCP authorization, and external authorization services. allows defining rules to allow or deny requests based on their properties, using CEL expressions.
Policies can define allow, deny, and require rules. Rules are evaluated in this order of precedence:
- If there are no rules, the request is allowed.
- If any
denyrule matches, the request is denied. - If any
requirerule does not match, the request is denied. Allrequirerules must match for the request to proceed. - If any
allowrule matches, the request is allowed. - If no rule matched the request, the outcome depends on whether any
allowrules are configured:- If no
allowrules are configured, the request is allowed (denylist semantics:denyandrequirerules act as a gate, and anything not blocked is permitted). - If
allowrules are configured, the request is denied (allowlist semantics: only explicitly allowed requests are permitted).
- If no
A CEL expression that cannot be evaluated is treated as false. For example, if the expression refers to jwt.aud, but the request has no JWT. The effect depends on the rule type:
- A
requireexpression that isfalse(or errors) denies the request (fail-closed). - A
denyexpression that errors does not match, so it does not deny the request (fail-open). - An
allowexpression that errors does not match, so it does not allow the request.
authorization:
rules:
- allow: 'request.path == "/authz/public"'
- deny: 'request.path == "/authz/deny"'
- require: 'jwt.aud == "my-service"'
# legacy format; same as `allow: ...`
- 'request.headers["x-allow"] == "true"'Require rules
The require rule type expresses mandatory conditions more clearly than double-negative deny rules, and it fails closed. For example:
authorization:
rules:
- require: 'jwt.aud == "my-service"'You might be tempted to express the same intent with a deny rule:
# NOT equivalent when jwt.aud is missing
authorization:
rules:
- deny: 'jwt.aud != "my-service"'These behave the same when a JWT with an audience claim is present, but they differ when the claim is missing. With no JWT, jwt.aud is undefined and both expressions error:
- A failed
requireexpression denies the request (fail-closed). - A failed
denyexpression does not match and therefore does not deny the request (fail-open). The request might be allowed by other rules.
For mandatory conditions such as “all requests must have a valid audience claim,” prefer require, which fails closed.
Unlike allow rules (where any one match permits the request), all require rules must match for the request to proceed.