Skip to content

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 / BLOCKED

Step 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
json
{
  "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.

json
{
  "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:

json
{
  "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:

CheckWhat It DoesPossible Outcome
Action type checkDoes the action match a blocked action pattern?BLOCKED
Environment restrictionIs the action targeting a blocked environment?BLOCKED
Confidence floorIs any confidence dimension below the floor?HELD
Rate limitHas the agent exceeded its allowed rate?HELD
Time windowIs the action outside an allowed change window?HELD or BLOCKED
Content checkDoes the action payload contain prohibited content (PII, secrets)?BLOCKED
Amount thresholdDoes a financial parameter exceed the review threshold?HELD
Custom ruleDoes the action violate a custom-defined rule?Configurable

Each policy evaluation produces a result:

json
{
  "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.

json
{
  "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

TypeDescriptionDefault Verdict
action_blockBlocks specific action types entirelyBLOCKED
environment_restrictionBlocks actions in specific environmentsBLOCKED
confidence_checkChecks confidence scores against thresholdsHELD
rate_limitEnforces action frequency limitsHELD
time_windowRestricts actions to specific time windowsHELD or BLOCKED
content_checkScans action payload for prohibited contentBLOCKED
amount_thresholdFlags financial actions above a thresholdHELD
customUser-defined rule with configurable verdictConfigurable

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.

PolicyTriggered?Verdict
No PII in external comms (tenant)Yes -- phone number detectedBLOCKED
Email rate limit (agent)No -- under limit--
Business hours only (tenant)Yes -- outside 8AM-6PMHELD
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:

  1. Name -- A descriptive name for the policy
  2. Scope -- Tenant-wide or agent-scoped
  3. Type -- Select from the policy types above
  4. Conditions -- Define the trigger conditions
  5. Verdict on trigger -- HELD or BLOCKED
  6. Status -- Active or Draft

Via API

bash
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

  1. Start broad, refine narrow -- Begin with tenant-wide policies for your core rules, then add agent-scoped policies for specific constraints.
  2. 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.
  3. Review your fire lists -- If a policy fires frequently but you always release the escrow, consider adjusting the policy.
  4. Test with AUDIT_ONLY -- Before enforcing a new policy, run it in AUDIT_ONLY mode to understand its impact.
  5. Document your policies -- Use the description field to explain why the policy exists. Future reviewers will thank you.

Next Steps

AI Governance for Every Organization