CEL condition reference
Every CEL variable, field, operator, and macro available in SecureAuth Agent Authority policy conditions, with a worked expression for each.
Policy conditions are written in CEL, Google's Common Expression Language. This page is the field-by-field reference — every variable, operator, and macro the condition editor accepts, plus one worked expression per variable.
Variables
Four variables are available in every condition, describing the request the gateway is currently evaluating:
| Variable | Represents |
|---|---|
agent | The connected agent instance making the call |
user | The signed-in user behind that agent instance |
mcp | The MCP server and tool being called |
request | The call being authorized: arguments and client IP |
agent
| Field | Type | Description |
|---|---|---|
agent.id | string | Agent instance ID |
agent.name | string | Agent display name |
agent.slug | string | Agent type slug (for example claude-code) — matches every instance of that agent |
agent.tags | list<string> | Tag names assigned to the agent's slug |
user
| Field | Type | Description |
|---|---|---|
user.id | string | User ID |
user.name | string | User display name |
user.email | string | User email address |
user.groups | list<string> | OIDC groups the user belongs to |
mcp
| Field | Type | Description |
|---|---|---|
mcp.id | string | MCP server ID |
mcp.name | string | MCP server display name |
mcp.slug | string | MCP server slug (for example github) |
mcp.tags | list<string> | Tag names assigned to the MCP server |
mcp.tool.name | string | Name of the tool being called |
mcp.tool.tags | list<string> | Tag names assigned to that tool |
request
| Field | Type | Description |
|---|---|---|
request.args.<field> | dyn | A field from the live tool-call arguments; its type is inferred from the matched tool's input schema |
request.ip | string | Client IP the gateway resolved for the call |
request.args is only populated for a tool-call request — see Argument-level conditions for how autocomplete and coverage chips help you reference these fields safely. request.ip is present on every call; see Network conditions.
Operators
Comparison and logic: == != in && || ! < <= > >= ?: has()
Arithmetic: + - * / % — usable inside a condition as long as the whole expression still returns a bool, for example size(user.groups) + 1 > 2.
Literals include true, false, and null.
String methods, available on any string field: .startsWith() .endsWith() .contains() .matches() .inCidr()
size() (callable as a function, size(x), or a method, x.size()) isn't string-only — it returns length for strings, lists, and maps alike, for example size(user.groups) > 0.
type(x) returns a value's type, which is useful against dyn-typed request.args fields, for example type(request.args.count) == int.
The full CEL standard library is enabled, so its conversion functions — int(), string(), double(), and the rest — are accepted too. That matters most for request.args, whose values arrive as dyn.
Network functions
inCidr(range) / inCidr([ranges])
A method on any string, returning bool. True when the subject address falls inside the range.
- A range without
/is an exact address match, so an allowlist can mix hosts and subnets. - An address the gateway could not determine, or that does not parse, matches nothing rather than erroring — so
!request.ip.inCidr(…)denies calls of unknown origin. - A malformed range literal, and an empty range list, are rejected when the rule is saved rather than at call time.
- An IPv4 range must be written in IPv4 form: an IPv4-mapped range (
::ffff:10.0.0.0/120) is rejected, because address matching is per-family and it would match nothing.
request.ip.inCidr("10.0.0.0/8")
request.ip.inCidr(["203.0.113.0/24", "192.0.2.45"])inCidr() is declared on any string, so it type-checks against other fields too — but request.ip is the only one the gateway resolves rather than reads out of the request payload. See Network conditions for what that does and does not guarantee.
List macros
Available on any list<string> field (user.groups, agent.tags, mcp.tags, mcp.tool.tags) and on list-typed request.args fields:
| Macro | Returns | Use it when |
|---|---|---|
.exists(x, <cond>) | bool | At least one element matches |
.all(x, <cond>) | bool | Every element matches |
.exists_one(x, <cond>) | bool | Exactly one element matches |
.filter(x, <cond>) | list | The subset of elements that match |
.map(x, <expr>) | list | Transform each element |
Worked expressions
One per variable, plus a network condition:
| Variable | Expression | Matches |
|---|---|---|
agent | agent.slug == "claude-code" && "prod" in agent.tags | Claude Code instances tagged prod |
user | user.groups.exists(g, g.startsWith("eng-")) | Users in any eng-* group |
mcp | mcp.slug == "github" && mcp.tool.name.startsWith("delete_") | Delete tools on the GitHub MCP server |
request | has(request.args.channel_id) && request.args.channel_id in ["C_GENERAL", "C_DEVREL"] | Slack calls scoped to two channels |
request | request.ip.inCidr(["203.0.113.0/24", "198.51.100.16/28"]) | Calls from either office range |
Limits
Expressions are capped at 1024 bytes.
Error semantics
A condition errors at runtime when it references a request.args field the live call's arguments don't include — even one the tool's schema defines as optional — or compares incompatible types. The gateway is fail-closed on that error, and which way it fails depends on the rule's effect: an allow rule with an erroring condition is skipped, so the next rule decides; a deny rule with an erroring condition still denies. Guard optional fields with has() before referencing them — see Conditions for the full evaluation model.
Next steps
- Policies — attach a condition to a rule and test it live.
- Argument-level conditions — autocomplete, coverage chips, and per-call authorization.
- Tags — the source of
agent.tags,mcp.tags, andmcp.tool.tags.
Reference
Lookup reference for SecureAuth Agent Authority — CEL policy-condition syntax and gateway MCP endpoint shapes for admins writing rules or connecting agents.
Gateway endpoints and authentication
The gateway's MCP endpoint shapes, agent authentication, and per-user upstream authentication — the lookup reference for connecting agents.