Policy & Governance
Waxell Observe provides a policy enforcement layer that checks whether an agent is allowed to execute before it runs. Policies are configured on the control plane and evaluated server-side, giving administrators centralized control over agent behavior without modifying agent code.
New to policies? Start with Policy Categories & Templates to see what's available, then use the Platform Assistant to create your first policy through chat.
How It Works
- Before an agent executes, the client sends a policy check request to the control plane
- The control plane evaluates all applicable policies (sorted by priority)
- The response contains an action that determines what happens next
Policies are defined across 26 categories -- from cost budgets and content scanning to data access boundaries, cognitive governance, and regulatory compliance. The platform also generates automated recommendations based on your agents' actual behavior.
Policy Actions
Every policy check returns one of these actions:
| Action | Meaning | Client Behavior |
|---|---|---|
allow | Execution is permitted | Agent runs normally |
warn | Execution is permitted with a warning | Agent runs; warning recorded in trace |
redact | Sensitive content masked | Content replaced with ##TYPE## placeholders |
throttle | Rate limited | PolicyViolationError raised |
block | Execution denied | PolicyViolationError raised |
skip | Execution skipped silently | Run not started, no error raised |
retry | Execution retried | Automatic retry with backoff |
The PolicyCheckResult object provides convenience properties:
result.action # "allow", "block", "warn", "throttle", "redact", "skip", "retry"
result.reason # Human-readable explanation
result.metadata # Additional data from the policy engine
result.allowed # True if action is "allow" or "warn"
result.blocked # True if action is "block", "throttle", or "skip"
Pre-Execution Checks
Enable policy enforcement with the enforce_policy parameter. Combined with init(), this is the recommended pattern:
import waxell_observe as waxell
from waxell_observe.errors import PolicyViolationError
waxell.init()
@waxell.observe(agent_name="support-bot", enforce_policy=True)
async def handle_query(query: str) -> str:
# Policies checked automatically before this runs
response = await call_llm(query)
return response
try:
result = await handle_query("test")
except PolicyViolationError as e:
print(f"Blocked: {e.policy_result.action}")
print(f"Reason: {e.policy_result.reason}")
print(f"Details: {e.policy_result.metadata}")
With the Context Manager (Advanced)
from waxell_observe import WaxellContext
from waxell_observe.errors import PolicyViolationError
try:
with WaxellContext(
agent_name="support-bot",
enforce_policy=True,
) as ctx:
result = process(query)
ctx.set_result({"output": result})
except PolicyViolationError as e:
print(f"Blocked: {e}")
With LangChain
from waxell_observe.integrations.langchain import WaxellLangChainHandler
from waxell_observe.errors import PolicyViolationError
handler = WaxellLangChainHandler(
agent_name="langchain-bot",
enforce_policy=True,
)
try:
result = chain.invoke(input, config={"callbacks": [handler]})
handler.flush_sync(result={"output": result})
except PolicyViolationError as e:
print(f"Blocked: {e}")
Mid-Execution Policy Checks
For long-running agents, check policies between steps to catch budget exhaustion or policy changes during execution:
import waxell_observe as waxell
waxell.init()
@waxell.observe(
agent_name="pipeline-agent",
enforce_policy=True,
mid_execution_governance=True, # Check on each step
)
async def run_pipeline(query: str) -> str:
# Step 1
data = await retrieve(query)
waxell.step("retrieve", output={"sources": len(data)})
# Step 2 -- mid-execution check happens automatically
summary = await summarize(data)
waxell.step("summarize", output={"length": len(summary)})
return summary
You can also check manually for more control:
with WaxellContext(agent_name="pipeline-agent") as ctx:
await step_one()
ctx.record_step("step_one")
# Manual mid-execution check
policy = await ctx.check_policy()
if policy.blocked:
ctx.set_result({"stopped_at": "step_one", "reason": policy.reason})
return
await step_two()
ctx.record_step("step_two")
Approval Workflows
When a policy blocks execution, you can handle it with human approval instead of failing. Pass on_policy_block to define what happens:
@waxell.observe(
agent_name="data-manager",
workflow_name="delete",
enforce_policy=True,
on_policy_block=waxell.prompt_approval, # terminal Y/N prompt
)
async def delete_records(table: str) -> dict:
return {"deleted": 500, "table": table}
If the human approves, the function executes normally. If denied or timed out, PolicyViolationError propagates to the caller.
Built-in handlers: prompt_approval (terminal), auto_approve (testing), auto_deny (testing). You can also write custom handlers for Slack, webhooks, or any approval channel.
See Approval Workflows for the full guide — custom handlers, ApprovalDecision, and what gets traced.
Disabling Policy Checks
Skip enforcement in development or testing:
# Decorator
@waxell.observe(agent_name="my-agent", enforce_policy=False)
async def my_function():
...
# Or disable all observability
# export WAXELL_OBSERVE=false
Configuring Policies
Policies are configured on the Waxell control plane, not in agent code. This separation means:
- Administrators define what agents are allowed to do
- Developers write agents that respect those policies automatically
- Policy changes take effect immediately without redeploying agents
Three ways to configure policies:
- Dashboard -- Governance > Policies in the UI
- API --
POST /waxell/v1/policies/(see API Reference) - Platform Assistant -- Ask the AI to create policies through chat (see Platform Assistant)
See Policy Categories & Templates for the full list of available policy types and pre-built templates.
Next Steps
- Approval Workflows -- Handle policy blocks with human approval
- Human-in-the-Loop -- Capture any interactive human input as observable spans
- Policy Categories & Templates -- All 26 categories and pre-built templates
- Recommendations -- Automated policy suggestions from runtime data
- Platform Assistant -- Create and manage policies via chat
- REST API Reference -- Direct API usage