← Back to home
§ 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.
- Governed by failure mode — a non-boolean result or a write-time-validated misconfiguration is skipped and logged. A genuine runtime evaluation fault now defers to the policy's
failure_mode:fail_open(default) abstains so other policies on the request are unaffected, whilefail_closedtreats the fault as a violation and enforces it. A misconfigured policy still cannot take down the request path under the default.
§ 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. |
| runtime evaluation fault | Deferred to failure_mode — fail_open abstains (default), fail_closed enforces. |
§ 06
Creating an expression policy
curl -X POST https://api.execlave.com/api/v1/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" } }'