Skip to content
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 /policies and PATCH /policies/:id. Invalid syntax returns HTTP 400 with the parser message under fields["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 returnsEffect
trueViolation — policy action (block / warn / require_approval) is applied.
falseNo violation — enforcement continues with remaining policies.
non-boolean / parse errorPolicy 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"    }  }'