Enforcement Chain Guide
This guide explains how the Policy Engine’s enforcement chain operates. It covers how packs are ordered in a chain, how combining algorithms determine the final action when multiple rules match, how to filter the chain view by group membership, and how to simulate requests before deploying changes.
For a conceptual overview of policy packs, rules, actions, and user-visible outcomes, see Policy Engine — User Guide. For step-by-step admin configuration (creating packs, rules, and chains), see Policy Engine admin guide.
What a policy chain is
Section titled “What a policy chain is”An org’s policy chain is the ordered sequence of policy packs evaluated for every AI request. When a request comes in, the Policy Engine evaluates each pack in chain order, applying the combining algorithm to determine the final enforcement action.
Your org has exactly one chain. The chain is configured in Settings → Policies → Policy Chain.
The chain holds references to packs — not copies of rules. If you modify a pack’s rules, those changes apply immediately to the chain the next time the chain is evaluated.
How chain evaluation works
Section titled “How chain evaluation works”For every AI request, the Policy Engine:
- Identifies the applicable chain (your org’s chain)
- Iterates packs in sequence order (position 1 first, then 2, then 3, …)
- Within each pack, evaluates rules in ascending sequence number order
- Applies the combining algorithm to determine when to stop and what action to return
The result is a single enforcement action: ALLOW, BLOCK, CANCEL, REDACT, ROUTE_TO, PROMPT, or ALLOW_WITH_OVERRIDE.
If no rule matches in any pack, the default action is ALLOW.
Pack ordering
Section titled “Pack ordering”Packs appear in the chain in the order shown in the Policy Chain editor. Position 1 is evaluated first. Order matters significantly with the first_applicable combining algorithm (see below).
Reordering packs
Section titled “Reordering packs”In the Policy Chain editor:
- Drag a pack card up or down to change its position
- Use the up (↑) and down (↓) buttons on each card to move it one position at a time
- Click Save chain to persist the new order
Changes take effect immediately after saving. There is no separate publish step.
Adding packs to the chain
Section titled “Adding packs to the chain”- Navigate to Settings → Policies → Policy Chain.
- Click Add Pack.
- Select from the list of packs not yet in the chain. Packs already in the chain do not appear in the picker.
- The selected pack is appended to the end of the chain.
- Reorder it as needed, then click Save chain.
Removing packs from the chain
Section titled “Removing packs from the chain”Click the remove button (×) on a pack card. The pack is removed from the chain but not deleted — its rules remain intact and you can re-add it later.
Combining algorithms
Section titled “Combining algorithms”The combining algorithm controls how the chain resolves situations where multiple rules across multiple packs could apply to a single request.
Set the combining algorithm using the Combining algorithm dropdown in the Policy Chain editor, then click Save chain.
first_applicable (default)
Section titled “first_applicable (default)”The engine evaluates rules in pack/sequence order and stops at the first terminal rule that matches. All subsequent rules and packs are skipped.
Terminal actions: ALLOW, BLOCK, CANCEL, ROUTE_TO, PROMPT, ALLOW_WITH_OVERRIDE.
Non-terminal: REDACT. A matching REDACT rule applies its redaction and evaluation continues to the next rule.
Example chain:
Pack 1 — "Engineering exceptions" Rule 1 (seq 1): user_groups=["engineering"] → ALLOW
Pack 2 — "PCI-DSS Bundle" Rule 1 (seq 1): entity_types=["CREDIT_CARD"] → REDACT Rule 2 (seq 2): entity_types=["SSN"] → BLOCK
Pack 3 — "Default deny" Rule 1 (seq 1): (unconditional) → BLOCKRequest from engineering user with no PII detected:
- Pack 1, Rule 1 matches (user is in engineering) → ALLOW → evaluation stops
- Pack 2 and Pack 3 are never reached
Request from non-engineering user with credit card number detected:
- Pack 1, Rule 1 does not match (user not in engineering) → continue
- Pack 2, Rule 1 matches (CREDIT_CARD detected) → REDACT applied, evaluation continues (REDACT is non-terminal)
- Pack 2, Rule 2 does not match (no SSN) → continue
- Pack 3, Rule 1 matches (unconditional) → BLOCK → evaluation stops
- Both REDACT and BLOCK are combined: content is redacted AND the request is blocked
This is the standard firewall model. Use it when rule priority should be determined by pack/rule position.
deny_overrides (XACML-style)
Section titled “deny_overrides (XACML-style)”All rules across all packs are evaluated regardless of matches. Any BLOCK or CANCEL action takes precedence over any ALLOW. A single matching deny in any pack blocks the request.
Behavior in deny_overrides mode:
| Rule matches | What happens |
|---|---|
| BLOCK or CANCEL | Immediately terminal — evaluation stops; request is denied |
| ALLOW | Collected but does not stop evaluation |
| ROUTE_TO | Collected but does not stop evaluation |
| REDACT | Accumulated as in first_applicable |
| PROMPT / ALLOW_WITH_OVERRIDE | Collected but overridden by any BLOCK/CANCEL |
If no BLOCK or CANCEL fires, the most severe collected terminal action is returned (e.g., ROUTE_TO over ALLOW).
When to use deny_overrides: When your compliance or security policy requires that any explicit deny rule — regardless of position — overrides all permissive rules. For example, a compliance bundle’s BLOCK rule must win even if an engineering exception pack’s ALLOW rule would otherwise have matched first.
When to use first_applicable: When rule priority is positional — packs earlier in the chain should take precedence over later packs. This is appropriate for most deployments.
Group-filtered chain view
Section titled “Group-filtered chain view”The Policy Chain editor includes a group filter that highlights which packs have rules that apply to a specific group.
Using the group filter
Section titled “Using the group filter”- In the Policy Chain editor, locate the Filter by group field.
- Enter a group name (e.g.,
engineering,finance). - The editor asynchronously checks each pack’s rules for
user_groupsconditions referencing this group. - Packs that contain at least one rule with a condition matching the specified group are marked (highlighted).
- Packs with no group-specific rules are dimmed — their rules apply to all users regardless of group.
The group filter is display-only. It does not change the chain configuration or evaluation behavior. It is a diagnostic tool for understanding which packs are relevant to a specific user population.
The group filter value is persisted per browser session. When you open the Policy Simulator, the stored group value is pre-populated as the user groups context. You can clear it by removing the text in the filter field.
What the filter shows
Section titled “What the filter shows”| Pack appearance | Meaning |
|---|---|
| Highlighted | Pack has at least one rule with a user_groups condition that includes the filtered group |
| Dimmed | Pack has no user_groups conditions matching this group — rules in this pack apply to all users or use other condition types |
| Normal (no filter set) | No group filter active — all packs shown at equal prominence |
Dimmed packs still apply to users in the filtered group. “Dimmed” means no group-specific rules — not that the pack is skipped.
Policy simulation
Section titled “Policy simulation”Before saving changes to the chain or publishing new rules, use the Policy Simulator to verify how a specific request would be evaluated under the current configuration.
Running a simulation
Section titled “Running a simulation”- Navigate to Settings → Policies → Simulator.
- Configure the evaluation context:
- Prompt: the text of the request to simulate
- Provider: the AI provider (anthropic, openai, google, ollama, mistral, cohere, bedrock, azure_openai, groq)
- Model: the specific model name (e.g.,
claude-3-5-sonnet-20241022) - User groups: one or more group names representing the user’s group memberships (comma or Enter to add each group)
- If a group filter is active in the chain editor, click Use chain filter to pre-populate the user groups field from the stored filter value.
- Click Simulate.
The simulator posts to POST /api/admin/policy-chains/simulate with the evaluation context and returns the result.
Reading simulation results
Section titled “Reading simulation results”The result panel shows:
| Field | Description |
|---|---|
| Matched | Whether any rule matched |
| Action | The final enforcement action |
| Matched pack | The pack containing the matching rule |
| Matched rule | The specific rule that determined the final action |
| Match reason | Why the rule matched (condition types that fired) |
| Evaluation trace | Full ordered list of packs and rules evaluated, with match/skip status |
Action results are color-coded in the result panel:
| Action | Color |
|---|---|
| ALLOW | Green |
| BLOCK | Red |
| CANCEL | Gray |
| REDACT | Orange |
| ROUTE_TO | Purple |
Evaluation trace rows where the match reason involves a group condition (user_group) are tagged with a group match badge. This makes it easy to identify which rules fired because of the simulated user’s group membership.
What the simulator evaluates
Section titled “What the simulator evaluates”The simulator evaluates against the currently saved chain configuration, including any unsaved changes you have made in the editor (the editor uses optimistic state — changes visible in the UI are reflected in the simulation even before you click Save chain). Always run a simulation after editing the chain, and save if the results are as expected.
The simulator evaluates input direction only. It does not simulate output evaluation (model response evaluation). To test output rules, use the Policy Engine testing advanced testing workflow.
Worked examples
Section titled “Worked examples”Example 1: Engineering bypass before compliance block
Section titled “Example 1: Engineering bypass before compliance block”Goal: Engineers can send requests that would otherwise be blocked by the PCI-DSS bundle.
Chain (first_applicable):
Position 1 — Custom: "Engineering exceptions" Rule 1: user_groups=["engineering"] → ALLOW
Position 2 — Bundle: "PCI-DSS Bundle" (managed rules including CREDIT_CARD BLOCK)Result: Engineering users match Pack 1 Rule 1 → ALLOW. The PCI-DSS bundle is never evaluated for them. All other users fall through to the PCI-DSS bundle.
Simulate this: Set user groups to engineering, enter a prompt containing a credit card number. Result should be ALLOW with Pack 1 trace showing match.
Example 2: Mandatory deny regardless of exceptions
Section titled “Example 2: Mandatory deny regardless of exceptions”Goal: A specific entity type must always be blocked, even for privileged groups.
Chain (deny_overrides):
Position 1 — Custom: "Engineering exceptions" Rule 1: user_groups=["engineering"] → ALLOW
Position 2 — Custom: "Hard blocks" Rule 1: entity_types=["PATIENT_RECORD"] → BLOCKResult: In deny_overrides mode, both packs are evaluated. If Pack 2 Rule 1 fires (PATIENT_RECORD detected), the BLOCK overrides the ALLOW from Pack 1 regardless of order.
Example 3: Identifying group-specific packs with the group filter
Section titled “Example 3: Identifying group-specific packs with the group filter”Goal: Understand which packs affect the finance group before changing their exception rules.
- Set the group filter to
finance. - Review which packs are highlighted — these have
user_groups=["finance"]conditions. - Dimmed packs apply to all users including finance users, but do not have finance-specific targeting.
- Open the simulator, click Use chain filter to pre-populate
financein the user groups field, and run test prompts.
See also
Section titled “See also”- Policy Engine — User Guide — packs, rules, actions, and what users see
- Policy Engine admin guide — creating packs, rules, and configuring the chain in the UI
- Policy configuration guide — combining algorithms reference and ROUTE_TO configuration
- Policy Engine testing — advanced testing including output-direction rules
- Group policy visualization — reading the enforcement posture for a specific group
- Groups & RBAC — group creation and membership management