Priority and deny resolution
When multiple rules could apply to one request, Sentinel needs deterministic tie-breaking. Two mechanisms control that: numeric priority and deny-before-allow at equal priority.
Sort order
Before first-match evaluation, candidates are sorted:
- Descending
priority(higher number = checked first) - At the same priority,
denyrules beforeallowrules
Default priority is 0 if omitted.
Deny wins at equal priority
deny()
.anyRole()
.actions("project:delete")
.on("project")
.build(),
allow()
.roles("owner")
.actions("project:delete")
.on("project")
.build(), // priority 0 — same as denyFor an owner, both rules are candidates. At priority 0, deny sorts first and matches — owner cannot delete unless you raise the allow rule's priority.
Override pattern
Give the exception higher priority than the broad deny:
deny()
.anyRole()
.actions("project:delete", "project:archive")
.on("project")
.priority(0)
.build(),
allow()
.roles("owner")
.actions("project:delete", "project:archive")
.on("project")
.priority(10)
.build(),Now the owner's allow rule is sorted first and wins.
First match wins
After sorting, the engine walks the list and stops at the first fully matching rule (including conditions). Later rules are never considered.
Design policies as a ordered decision list, not as independent booleans combined at the end.