← Back to policies
§ DOCUMENTATION
Policy Expressions (CEL)
Author enforcement rules in CEL — the Common Expression Language used by Kubernetes admission, GCP IAM, Envoy, and Istio. Deterministic, sandboxed, no I/O, no access to host globals.
§ 01
When to reach for an expression policy
Expression policies are the middle ground between a built-in policy type (which ships with Execlave) and a custom validator (which calls out to your own service). Use them when the rule is pure business logic over the request context and does not need state Execlave doesn't already hold.
- Spend caps conditioned on environment or agent.
- Tool-scope rules that depend on the identity of the caller.
- Metadata-driven allow / deny where the SDK attaches structured fields.
For anything that requires a database lookup or external API call, use a custom validator instead.
§ 02
Context variables
Every expression runs against the same structured context. Expressions must ultimately return a boolean.
// Context variables available to every expression{ input: string, // user / upstream prompt output: string, // model response (only at phase="post") agentId: string, agentName: string, environment: string, // e.g. "production", "staging" tools: list<string>, // tools declared on the request metadata: map, // free-form metadata from the SDK cost: double, // estimated / actual USD orgId: string, now: int, // Unix epoch seconds (server clock) phase: string // "pre" (pre-execution) | "post"}§ 03
Examples
# Block any production agent with estimated cost > $1.00cost > 1.0 && environment == "production" # Escalate when a sensitive tool is requestedtools.exists(t, t == "payments.transfer") # Only allow the finance-assistant to issue refundsagentName == "finance-assistant" || !tools.exists(t, t == "refunds.issue") # Metadata-driven gate (SDK attaches userId in metadata)metadata.userId == "u_banned"§ 04
Guarantees
- Deterministic and pure — no clock, network, file, or environment access beyond the declared context.
- Validated at write time — expressions are parsed during
POST /policiesandPATCH /policies/:id. Invalid syntax returns HTTP 400 with the parser message underfields["ruleDefinition.expression"]. - Size-capped — expressions are rejected above 4 KB.
- Compiled once, cached — a parse cache of up to 500 compiled expressions is kept per process.
- Safe-skip on runtime fault — if an expression throws at evaluation time or returns a non-boolean, the single policy is skipped and logged. Other policies on the same request are unaffected. This matches Execlave's general policy-engine posture: a misconfigured policy cannot take down the request path.
§ 05
Outcomes
| Expression returns | Effect |
|---|---|
true | Violation — policy action (block / warn / require_approval) is applied. |
false | No violation — enforcement continues with remaining policies. |
| non-boolean / parse error | Policy is skipped and logged. Does not affect other policies. |
§ 06
Creating an expression policy
curl -X POST https://api.execlave.com/api/policies \ -H "Authorization: Bearer $EXECLAVE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "cost-guardrail", "policyType": "expression", "severity": "high", "action": "block", "ruleDefinition": { "expression": "cost > 1.0 && environment == \"production\"", "message": "Estimated cost exceeds $1.00 in production" } }'