Access control rules: roles, exceptions and the banned-user slip
Access rules combine roles that grant, roles that grant conditionally, and a lock or ban that takes precedence. owner OR admin OR (editor AND NOT locked) is the pattern with four conditions, and the banned-user slip is the mistake it exists to prevent.
Owners and admins can always edit; editors can edit unless the document is locked. The bracket is the whole design: editor AND NOT locked keeps the lock attached to the editor role, so that the lock does not stop owners and admins, who are meant to be able to unlock. The checks on the page show the rule contingent with the witness editor = TRUE, locked = FALSE, the others FALSE, as one row that grants.
The banned-user slip is the entry rule's grouping mistake in a different costume. A global ban that must override every role is an AND NOT at the top level, (owner OR admin OR (editor AND NOT locked)) AND NOT banned; written as owner OR admin OR (editor AND NOT banned) it bans editors only, and the owners who were banned keep editing. The equivalence checker reports the rows where the two differ, and they are precisely the banned owners and banned admins.
Rules of this shape grow by adding roles to the OR and exceptions to the AND NOT, and the tests that keep them honest are the independence pairs: one pair per role shows that the role grants on its own, and one pair per exception shows that the exception revokes on its own. Four conditions give four pairs in about five scenarios, far fewer than the sixteen rows, and a counterexample from a past incident is worth keeping as a test for as long as the rule exists.
Example
can_edit := owner OR admin OR (editor AND NOT locked) · output
Exact checks
Truth table (16 rows)
| # | owner | admin | editor | locked | can_edit |
|---|---|---|---|---|---|
| 0 | FALSE | FALSE | FALSE | FALSE | FALSE |
| 1 | FALSE | FALSE | FALSE | TRUE | FALSE |
| 2 | FALSE | FALSE | TRUE | FALSE | TRUE |
| 3 | FALSE | FALSE | TRUE | TRUE | FALSE |
| 4 | FALSE | TRUE | FALSE | FALSE | TRUE |
| 5 | FALSE | TRUE | FALSE | TRUE | TRUE |
| 6 | FALSE | TRUE | TRUE | FALSE | TRUE |
| 7 | FALSE | TRUE | TRUE | TRUE | TRUE |
| 8 | TRUE | FALSE | FALSE | FALSE | TRUE |
| 9 | TRUE | FALSE | FALSE | TRUE | TRUE |
| 10 | TRUE | FALSE | TRUE | FALSE | TRUE |
| 11 | TRUE | FALSE | TRUE | TRUE | TRUE |
| 12 | TRUE | TRUE | FALSE | FALSE | TRUE |
| 13 | TRUE | TRUE | FALSE | TRUE | TRUE |
| 14 | TRUE | TRUE | TRUE | FALSE | TRUE |
| 15 | TRUE | TRUE | TRUE | TRUE | TRUE |
Plain-language reading
Beginnercan_edit is true exactly when at least one of the following holds (several may hold):
1. owner is true
2. admin is true
3. editor is true and locked is false
In every other case, can_edit is false.
About the operators:
- OR is inclusive: it is true when at least one part is true, including when several are.
- AND is true only when all of its parts are true.
- NOT reverses a value: true becomes false and false becomes true.
Intermediatecan_edit is true exactly when at least one of the following holds (several may hold):
1. owner is true
2. admin is true
3. editor is true and locked is false
In every other case, can_edit is false.
Advancedcan_edit is true exactly when at least one of the following holds (several may hold) [inclusive disjunction ∨]:
1. owner is true
2. admin is true
3. editor is true and locked is false [conjunction ∧]
In every other case, can_edit is false.
Formal notation: owner ∨ admin ∨ (editor ∧ ¬locked)
Logic diagram
The common slip
Attaching a global ban to one role. owner OR admin OR (editor AND NOT banned) lets a banned owner edit. A ban that overrides everything is (…) AND NOT banned around the whole rule, and the table shows the banned-owner row either way.
Questions
Should the lock override admins?
That is a policy question, and the formula records the answer. As written, it does not: locked is inside the editor bracket. To make it override everyone, move AND NOT locked outside, and the equivalence checker will list the rows that change.
How do I express “at least one of several roles”?
As an OR of the roles, which is inclusive: a user with two roles qualifies. If roles are exclusive by construction, say so as an assumption, and the checks will respect it.
Related
See also
- Access control rule: owner OR admin OR (editor AND NOT locked)
- Entry rule: (member OR invited) AND NOT banned, checked every way
- Entry rule slip: member OR (invited AND NOT banned) and the case that differs
- Eligibility rules: the pattern, the usual exceptions and the tests
- Feature flag logic: combining flags without surprises
- “Unless” in a rule: AND NOT, not OR
- “A or B and C”: the grouping ambiguity and how to resolve it
- Turning a counterexample into a regression test
Testing and rules
Generated from the Tangibool engine, semantics tangibool-semantics/1, engine 1.0.0, build . Every table, map, simplification and verdict on these pages was computed by the Tangibool engine when the site was built, and every claim was re-checked by the same exact checker the app uses. Limits are stated where they apply. © 2026 Foreranger LTD.