#Why one model is not enough
Role-based access control answers most questions well and has a mature model behind it . An editor may edit. An administrator may configure. Roles are easy to explain and easy to audit.
They stop being enough at the first requirement of the form "only during business hours", "only from the corporate network", or "only for records in their own region". Those are attributes of the request and the resource rather than properties of the subject, which is what attribute-based control exists for .
Then somebody asks for "anyone who can edit the parent folder can edit this document". That is neither a role nor an attribute. It is a relationship, resolved by walking a graph, which is the model Zanzibar formalised at scale .
#Most systems end up with all three
Usually accidentally. Roles in a table, attribute checks scattered through handlers as conditionals, and relationship logic embedded in queries. Three models with no shared vocabulary and no defined interaction.
The question that exposes it: a role grants access, an attribute policy denies it, and a relationship grants it. What happens? In most systems the answer is whichever check ran first, which means the answer depends on code order.
#Fixing precedence first
One rule, stated before anything else is designed: explicit deny beats allow beats default deny.
Explicit deny wins because a deny is usually a compliance or safety statement, and a rule that says contractors may never see payroll data should not be defeated by someone being added to a group. Default deny is the base case, which is fail-safe defaults doing exactly what it exists to do .
Once that is fixed, adding a model is additive. A new relationship type contributes allows and denies into a rule everyone already understands.
#Caching, and why it is hard
Authorisation is on the hot path of every request, so it gets cached, and that is where correctness goes.
Role changes invalidate obviously. Relationship changes do not: moving a document to a different folder changes the answer for every user whose access came through the old folder, and computing that set is itself a graph traversal.
What I settled on is per-tenant and per-subject invalidation with a short time to live, accepting a bounded window where a revoked permission still works. That window has to be short and it has to be stated, because a security property with an undocumented staleness window is not a property.
#Auditing the decision
An authorisation system needs to answer why, not only whether. When somebody asks why a user could see a record, "the check returned true" is not an answer.
Recording which rule granted access, and through which path for relationship checks, costs storage and is the difference between an access review that takes an afternoon and one that takes a week.
References
- [1]Ravi S. Sandhu, Edward J. Coyne, Hal L. Feinstein, Charles E. Youman, “Role-Based Access Control Models”, Computer, vol. 29, no. 2, pp. 38-47, 1996doi:10.1109/2.485845 ↗
- [2]Vincent C. Hu et al., “Guide to Attribute Based Access Control (ABAC) Definition and Considerations”, NIST Special Publication 800-162, 2014doi:10.6028/NIST.SP.800-162 ↗
- [3]Ruoming Pang et al., “Zanzibar: Google's Consistent, Global Authorization System”, USENIX Annual Technical Conference, 2019
- [4]Jerome H. Saltzer, Michael D. Schroeder, “The Protection of Information in Computer Systems”, Proceedings of the IEEE, vol. 63, no. 9, pp. 1278-1308, 1975doi:10.1109/PROC.1975.9939 ↗