1. The order: priority ascending, first match wins
Within a policy, rules are evaluated inpriority ASC, id ASC order:
- Lower
priorityruns first. A rule withpriority: 0is checked before one withpriority: 10. Think of it as a queue position, not a strength score — the smaller number gets first say. - Ties break by rule id. Two rules at the same
priorityrun in creation order (ascending rule id), so the older rule wins the tie. Use distinct priorities when order actually matters rather than relying on the id tie-break. - First match wins. The engine stops at the first rule whose conditions all hold and applies its verdict. Rules further down the list are never consulted for that call.
- No match → the default verdict. If nothing matches, the policy’s
default_verdictapplies —auditunless you changed it.
A rule matches only when every declared condition holds at once: the
surface, the
tool-name glob, the optional skill glob,
the optional argument clauses,
and the egress scope (egress rules only). A partial match is no match, and
evaluation moves to the next rule.
2. One concrete example: specific before broad
The canonical ordering job is letting a narrow allow survive a broad deny. Put the specific rule at a lower priority so it is reached first:shell.echo hits Rule A first (priority 10), matches, and
is allowed — the engine never reaches Rule B. A call to shell.exec
falls through A (the glob doesn’t match), hits Rule B, and is denied.
Flip the priorities and the broad shell.* deny at priority 10 would
catch shell.echo first, and your allow at priority 20 would be dead
code. The rule of thumb: most specific first, broadest last.
3. Verify order before you depend on it
Reasoning about priority on paper is error-prone once a policy has more than a handful of rules. The Test sandbox runs the real engine against a sample tool call and tells you not just the verdict but which rule won — so you can confirm the rule you expected actually fired:Submit a sample call
Enter a tool name (and arguments, if your rules inspect them) and run
it. Nothing is dispatched and nothing is persisted — it’s a dry run.
4. Skill enforcement rides on top
Rule priority decides the winning rule’s verdict — but that isn’t always the final answer. If the tool call is owned by a governed skill, the skill’s enforcement mode is applied on top of the winning verdict, after first-match resolution:| Skill mode | Effect on the winning verdict |
|---|---|
allow | No change — the rule verdict stands. |
quarantine | Escalates anything short of deny to pending_approval; an existing deny is left as-is. |
block | Forces a deny regardless of the rule verdict. |
quarantine skill can turn a rule’s allow into a held call, and a
block skill denies a call even when no rule names its tools.
Quarantine only escalates — it never downgrades a deny to something softer.
This is why a skill auto-detected as risky stays quarantined until you
review it, no matter how permissive your rules are.
5. Things that don’t ride first-match
A few mechanisms sit outside the per-rule priority walk — know where they land so you don’t try to order them:cap_cost — resolved, not ranked
cap_cost — resolved, not ranked
A
cap_cost rule under its ceiling is
treated as non-matching, so evaluation continues to the next rule
rather than letting it win first-match as a grant. Over the ceiling it
resolves to a deny. It never short-circuits a lower-priority rule
just by being reached.Sequences — reactive, not inline
Sequences — reactive, not inline
A sequence rule matches a chain
of calls across a time window, so it’s enforced reactively by an
asynchronous matcher rather than on the single call that completes the
chain. It lights up the events feed but doesn’t win the first-match
walk for an individual call.
Shadow mode — applied after the verdict
Shadow mode — applied after the verdict
Shadow mode doesn’t change which rule
wins — it downgrades the winning enforcing verdict to
audit (reason
prefixed [shadow] would …) after first-match resolution, so you can
measure a policy’s impact before it changes traffic.6. Putting it together
For any tool call the full resolution is:- Resolve the policy — the one attached to the calling key, or the workspace default. See scope.
- Walk rules in
priority ASC, id ASC— first match wins; no match →default_verdict. - Apply skill enforcement — a governed skill’s mode rides on top of
the winning verdict (
blockforces deny,quarantineescalates). - Apply shadow mode — if on, downgrade enforcing verdicts to
audit. - Record the event — verdict, surface, tool, and matched rule land in the events feed.
Editing a rule’s priority takes effect on the next call for every key
attached to the policy — no redeploy, no agent-code change. Re-run the
Test sandbox after re-ordering to confirm
the new winner before live traffic depends on it.
Where to go next
Verdicts
What each winning verdict actually does.
Glob syntax
How tool-name matching decides whether a rule is even a candidate.
Test rules
Dry-run a policy and see which rule wins.
Tool allow-listing
The default-deny pattern that leans hardest on ordering.
