BookbagBookbag
Guardrails

Policy enforcement at runtime. Rule authoring without DSL drama.

Block destructive tool calls. Hold high-risk operations for human approval. Redact PII before it leaves your walls. A rule builder anyone on the team can use — plain-English preview, preset chips, test against real calls before you ship.

Four decisions. One runtime.

Every intercepted call maps to one of these four. Severity decides which wins when rules conflict.

allow

Call proceeds. Logged for observability + compliance.

block

Call refused. Reason returned to the agent. Never executes.

hold

Call paused awaiting human approval. Long-poll returns the verdict.

redact

Arguments or output scrubbed before the call proceeds. PII never touches downstream.

A rule builder that explains itself

Plain-English preview updates as you type. Preset chips for common patterns. Advanced JSON escape hatch when you need it.

Preset chips

Block destructive shell. Approval on large refunds. Flag PII detector. Block prompt injection. One click prefills the form.

Plain-English preview

'When a tool call happens, if tool equals shell and args.cmd matches /rm -rf/, block the call.' Updates as you edit.

Test against last 100

Run the drafted rule against the last 100 real calls. See matches, false positives, and what would have happened. Ship with confidence.

Activity → Policy → Activity

Every uncovered row in the Activity Log has a 'Create policy' button. Author the rule inline. The next matching call enforces it.

agent.py
# Your agent code stays unchanged. The SDK intercepts the call.

result = client.agent.tool_call(
    run_uid=run_uid,
    tool="shell",
    arguments={"cmd": "rm -rf /tmp/important"},
)

if result["decision"] == "block":
    raise GuardrailBlocked(result["reason"])

if result["decision"] == "hold":
    # Long-poll while a reviewer approves/denies.
    final = client.agent.await_decision(
        audit_id=result["audit_id"], timeout_ms=30000
    )
    if final["decision"] != "allow":
        raise GuardrailHeld(final["reason"])

# Only now does the actual shell call run.
subprocess.run(result["tool"] + " " + result["arguments"]["cmd"])
session · conv_8f3a2c
streaming
14:32:01
query_databaseallowcompleted
query: "all customer records"
no policy configured
14:32:03
send_emailblockcompleted
to: "reports@external.example"
domain policy · external recipient
14:33:18
issue_refundholdpending
amount: $500.00 · order: FF-4210
awaiting human approval
14:35:44
issue_refundallowcompleted
amount: $49.99 · order: FF-1042
refund policy · amount ≤ $60
14:38:12
update_crmallowcompleted
contact: "acme-corp"
no policy configured
14:42:07
fetch_piiblockcompleted
ssn + dob requested
pii detector · high severity

Detectors, pre-flight

Four built-in detectors run on every call. Their flags are available to every rule as detector_flags.

PII

Names · emails · SSNs · phone · addresses

Secret

API keys · passwords · tokens · PEMs

Prompt injection

System-override and jailbreak patterns

Jailbreak

Known bypass corpora + heuristics

Guardrails FAQs

Frequently Asked Questions

Stop your agent from doing the wrong thing. Before it does it.

Join the teams shipping safer AI with real-time evaluation, audit trails, and continuous improvement.