Policies & guardrails
A guardrail is a policy rule that constrains what agents may do during a run. Policies are how you give an autonomous system the freedom to act while keeping it inside lines you define. This guide covers the policy model and how to author one.
Why policies
Cendriix runs are autonomous, agents decide which tools to call without a human in the loop for every step. Policies make that safe. A policy can block a dangerous tool outright, require human approval before a sensitive action, cap spend, or restrict which environments an agent can write to. Every policy decision is recorded as an audit event, so you can always answer why a run was allowed or stopped.
The policy model
A policy is a named, versioned set of rules. Rules are evaluated synchronously before every tool call. Each rule has a matcher that decides whether it applies and an action that decides what happens when it does. Policies live under .cendriix/policies/ as YAML and are managed with the cendriix policy command group.
Writing rules
Here is a policy that blocks production data deletion, requires approval for any production deploy, and caps the spend of a single run:
# .cendriix/policies/production-safety.yaml
name: Production safety
description: Core guardrails for production environments.
rules:
- id: no-prod-delete
action: block
match:
tool: "aws.*.delete*"
env: production
- id: approve-prod-deploy
action: require_approval
approvers: { role: maintainer }
match:
tool: "aws.ecs.updateService"
env: production
- id: run-cost-ceiling
action: halt
match:
run_cost_usd: { gt: 25.00 }Rule actions
| Action | Description |
|---|---|
allow | Explicitly permit the matched action. Used to carve exceptions out of a broader block rule. |
block | Reject the tool call. The agent receives the rejection and must find another path or fail the step. |
require_approval | Pause the run and insert a dynamic approval gate. The run continues only if an approver allows it. |
halt | Stop the entire run immediately. Used for hard ceilings such as a run-level cost cap. |
Matchers
A matcher is an object of conditions; all conditions must hold for the rule to apply. Tool names support * wildcards, so aws.*.delete* matches every delete operation across every AWS service. Matchers can also test the target environment, the calling agent, the repository, and numeric run state such as accumulated cost.
run_cost_usd matcher is evaluated before the tool call that would push the run over the ceiling is committed. The expensive call never runs, the run halts at the gate instead of overshooting the budget.How policies compose
A run applies every policy bound to its workspace plus any bound to its workflow. When more than one rule matches the same action, the most restrictive applicable action wins: halt beats block, block beats require_approval, and an explicit allow only takes effect when no stricter rule matches. This means adding a policy can only ever tighten behaviour, never loosen it unexpectedly.
Testing a policy safely
Before enabling a new policy, replay a real past run against it. Time travel re-executes the run deterministically with the new policy active and side effects intercepted, so you see exactly which calls the policy would have blocked, without touching production.
# Dry-run a candidate policy against a real run
cendriix policy test \
--file .cendriix/policies/production-safety.yaml \
--run run_a1b2c3d4
# Once verified, publish and enable it
cendriix policy create --file .cendriix/policies/production-safety.yaml
cendriix policy enable --id pol_xyz