Skip to main content
When two rules could both match the same tool call, firewall rule priority decides which one wins. A firewall policy is an ordered list of rules — the engine walks them in priority order, stops at the first one that matches, and applies its verdict. Get the order right and a broad guard plus a narrow exception coexist cleanly; get it wrong and the broad rule swallows the exception you meant to carve out. This page is the focused reference for ordering. For the full rule grammar see Firewall Rules; for the verdicts a rule can produce see Verdicts.

1. The order: priority ascending, first match wins

Within a policy, rules are evaluated in priority ASC, id ASC order:
  1. Lower priority runs first. A rule with priority: 0 is checked before one with priority: 10. Think of it as a queue position, not a strength score — the smaller number gets first say.
  2. Ties break by rule id. Two rules at the same priority run 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.
  3. 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.
  4. No match → the default verdict. If nothing matches, the policy’s default_verdict applies — audit unless 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:
// Rule A — priority 10: trust this one exact tool.
{ "label": "allow safe shell", "priority": 10,
  "tool_name_glob": "shell.echo", "verdict": "allow" }

// Rule B — priority 20: block the rest of the shell family.
{ "label": "block shell family", "priority": 20,
  "tool_name_glob": "shell.*", "verdict": "deny" }
A call to 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.
Don’t depend on the id tie-break for this. If the allow and the deny share the same priority, the winner is whichever rule you created first — a fragile ordering that silently flips if you delete and re-create a rule. Give the specific rule a lower priority and the intent is explicit.

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:
1

Open the policy's Test tab

In the console, open the policy and switch to Test (Developer+).
2

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.
3

Read the matched rule

The result names the verdict, the matched rule (by label/id), and the reason. If a broad rule won where you expected a narrow one, lower the narrow rule’s priority and re-test.
See Test rules for the full sandbox, and Manage policies for editing rule order in place.

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 modeEffect on the winning verdict
allowNo change — the rule verdict stands.
quarantineEscalates anything short of deny to pending_approval; an existing deny is left as-is.
blockForces a deny regardless of the rule verdict.
So a 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.
Skill mode is not a rule, so it doesn’t have a priority and you can’t re-order it relative to your rules. It always evaluates after the winning verdict is chosen. If a governed skill’s mode is blocking calls you expected to allow, fix it on the skill, not by adding a higher-priority allow rule — the rule can’t override the mode.

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:
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.
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 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:
  1. Resolve the policy — the one attached to the calling key, or the workspace default. See scope.
  2. Walk rules in priority ASC, id ASC — first match wins; no match → default_verdict.
  3. Apply skill enforcement — a governed skill’s mode rides on top of the winning verdict (block forces deny, quarantine escalates).
  4. Apply shadow mode — if on, downgrade enforcing verdicts to audit.
  5. 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.
For the matching language behind a rule, see the full Firewall Rules reference; for how skills layer on top, see Firewall Skills and enforcement modes.