Workflow: Policy Evaluation
CHAM (Contextual Hierarchical Action Model) policies are the rules that define what AI agents can and cannot do. This page explains how policies are loaded, evaluated, and combined during governance.
Overview
Every /govern request triggers a policy evaluation. TheWARDN loads all applicable policies, passes them to Sentinel, and Sentinel evaluates each one against the proposed action. The outcome determines the verdict.
Evaluation Flow
POST /govern arrives
|
v
+---------------------------+
| 1. Load Tenant-Wide |
| Active Policies |
+---------------------------+
|
v
+---------------------------+
| 2. Load Agent-Scoped |
| Active Policies |
| (additive) |
+---------------------------+
|
v
+---------------------------+
| 3. Inject Confidence |
| Floor as Synthetic |
| Policy |
+---------------------------+
|
v
+---------------------------+
| 4. Pass All Policies |
| to Sentinel |
+---------------------------+
|
v
+---------------------------+
| 5. Sentinel Evaluates |
| Each Policy vs Action |
+---------------------------+
|
v
+---------------------------+
| 6. Aggregate Results |
| - Fire list recorded |
| - Worst tier wins |
+---------------------------+
|
v
Verdict
CLEARED / HELD / BLOCKEDStep 1: Load Tenant-Wide Policies
Tenant-wide policies apply to every agent in the tenant. These are your organization's baseline governance rules.
Examples of tenant-wide policies:
- No PII in outbound communications
- No code execution on production systems outside maintenance windows
- All financial transactions above $10,000 require human approval
{
"policy_id": "pol_no_pii_external",
"name": "No PII in External Communications",
"scope": "tenant",
"status": "active",
"type": "action_block",
"conditions": {
"action_pattern": "send_*",
"content_check": "pii_detected",
"direction": "external"
},
"verdict_on_trigger": "BLOCKED"
}Only policies with status: "active" are loaded. Inactive or draft policies are ignored during evaluation.
Step 2: Load Agent-Scoped Policies
Agent-scoped policies apply only to a specific agent. They are additive -- they do not replace tenant-wide policies.
An agent must satisfy both tenant-wide AND agent-scoped policies to receive a CLEARED verdict.
{
"policy_id": "pol_email_rate_limit",
"name": "Email Send Rate Limit",
"scope": "agent",
"agent_id": "agent_abc123",
"status": "active",
"type": "rate_limit",
"conditions": {
"action": "send_email",
"max_per_hour": 50
},
"verdict_on_trigger": "HELD"
}TIP
Agent-scoped policies are useful for applying specific constraints to individual agents without affecting other agents in your tenant.
Step 3: Inject Confidence Floor
If the agent has a confidence floor set (e.g., 0.70), TheWARDN injects a synthetic policy that checks all confidence dimensions:
{
"policy_id": "synthetic_confidence_floor_agent_abc123",
"name": "Confidence Floor (0.70)",
"scope": "agent",
"type": "confidence_check",
"conditions": {
"min_overall": 0.70,
"min_per_dimension": 0.70
},
"verdict_on_trigger": "HELD"
}This synthetic policy is evaluated identically to any other policy. If any confidence dimension falls below the floor, the action is HELD.
Step 4: Pass to Sentinel
All loaded policies -- tenant-wide, agent-scoped, and synthetic -- are passed to Sentinel as a single evaluation set. Sentinel does not distinguish between policy sources during evaluation.
Step 5: Sentinel Evaluates Each Policy
Sentinel evaluates each policy against the action independently:
| Check | What It Does | Possible Outcome |
|---|---|---|
| Action type check | Does the action match a blocked action pattern? | BLOCKED |
| Environment restriction | Is the action targeting a blocked environment? | BLOCKED |
| Confidence floor | Is any confidence dimension below the floor? | HELD |
| Rate limit | Has the agent exceeded its allowed rate? | HELD |
| Time window | Is the action outside an allowed change window? | HELD or BLOCKED |
| Content check | Does the action payload contain prohibited content (PII, secrets)? | BLOCKED |
| Amount threshold | Does a financial parameter exceed the review threshold? | HELD |
| Custom rule | Does the action violate a custom-defined rule? | Configurable |
Each policy evaluation produces a result:
{
"policy_id": "pol_no_pii_external",
"triggered": true,
"reason": "PII detected in email body: social security number pattern",
"verdict_on_trigger": "BLOCKED"
}Step 6: Aggregate Results
After all policies are evaluated, Sentinel aggregates the results:
Fire List
Every triggered policy is added to the fire list. The fire list is recorded in the audit trail regardless of the final verdict.
{
"fired_policies": [
{
"policy_id": "pol_no_pii_external",
"reason": "PII detected in email body",
"verdict_on_trigger": "BLOCKED"
},
{
"policy_id": "pol_email_rate_limit",
"reason": "Agent has sent 52 emails this hour (limit: 50)",
"verdict_on_trigger": "HELD"
}
]
}Worst Tier Wins
The final verdict is determined by the most restrictive triggered policy:
BLOCKED > HELD > CLEARED- If any policy triggers BLOCKED, the final verdict is BLOCKED
- If no BLOCKED but any policy triggers HELD, the final verdict is HELD
- If no policies trigger, the final verdict is CLEARED
In the example above, the final verdict is BLOCKED because pol_no_pii_external triggers a BLOCK, even though pol_email_rate_limit would only trigger a HOLD.
WARNING
There is no way to override a BLOCKED verdict programmatically. If a policy says BLOCK, the action is blocked. To change this behavior, you must modify or deactivate the policy.
Policy Types Reference
| Type | Description | Default Verdict |
|---|---|---|
action_block | Blocks specific action types entirely | BLOCKED |
environment_restriction | Blocks actions in specific environments | BLOCKED |
confidence_check | Checks confidence scores against thresholds | HELD |
rate_limit | Enforces action frequency limits | HELD |
time_window | Restricts actions to specific time windows | HELD or BLOCKED |
content_check | Scans action payload for prohibited content | BLOCKED |
amount_threshold | Flags financial actions above a threshold | HELD |
custom | User-defined rule with configurable verdict | Configurable |
How Multiple Policies Combine
Here is a concrete example of how multiple policies interact:
Scenario: An email assistant agent tries to send an email at 2:00 AM containing a customer's phone number.
| Policy | Triggered? | Verdict |
|---|---|---|
| No PII in external comms (tenant) | Yes -- phone number detected | BLOCKED |
| Email rate limit (agent) | No -- under limit | -- |
| Business hours only (tenant) | Yes -- outside 8AM-6PM | HELD |
| Confidence floor 0.70 (agent) | No -- confidence is 0.85 | -- |
Final verdict: BLOCKED (worst tier wins)
Fire list: [pol_no_pii_external, pol_business_hours]
Even though the business hours policy would only HOLD the action, the PII policy triggers a BLOCK, so the action is blocked outright.
Creating Policies
Via Console
Navigate to Policies in the console sidebar. Click Create Policy and fill in:
- Name -- A descriptive name for the policy
- Scope -- Tenant-wide or agent-scoped
- Type -- Select from the policy types above
- Conditions -- Define the trigger conditions
- Verdict on trigger -- HELD or BLOCKED
- Status -- Active or Draft
Via API
curl -X POST https://api.thewardn.ai/policies \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "No Production Deploys After Hours",
"scope": "tenant",
"type": "time_window",
"conditions": {
"action_pattern": "deploy_*",
"environment": "production",
"blocked_hours": { "after": "18:00", "before": "08:00" },
"blocked_days": ["Saturday", "Sunday"]
},
"verdict_on_trigger": "BLOCKED",
"status": "active"
}'TIP
Create policies in draft status first, then switch to active after testing. In AUDIT_ONLY mode, you can see which policies would fire without affecting production.
Best Practices
- Start broad, refine narrow -- Begin with tenant-wide policies for your core rules, then add agent-scoped policies for specific constraints.
- Use HELD before BLOCKED -- When in doubt, use HELD. It lets you review the action before deciding. BLOCKED is for actions that should never execute under any circumstances.
- Review your fire lists -- If a policy fires frequently but you always release the escrow, consider adjusting the policy.
- Test with AUDIT_ONLY -- Before enforcing a new policy, run it in AUDIT_ONLY mode to understand its impact.
- Document your policies -- Use the description field to explain why the policy exists. Future reviewers will thank you.
Next Steps
- Govern an Action -- See how policies fit into the full governance flow
- Escrow Lifecycle -- What happens when a HELD verdict is issued
- Incident Response -- Handling violations from BLOCKED verdicts