RBAC vs ABAC vs ReBAC vs PBAC
IAM · practitioner · 9 min read · last reviewed 2026-07-07
The four authorization models compared: RBAC (role), ABAC (attributes), ReBAC (relationship), PBAC (policy). What each is, where each breaks, and a decision table for choosing.
TL;DR
- RBAC decides access by role, ABAC by attributes, ReBAC by relationship, and PBAC by an externalized policy that can evaluate all three.
- RBAC breaks on role explosion; ABAC breaks on auditability; ReBAC adds operational weight; PBAC is delivery, not a rule model.
- ReBAC is the Google Zanzibar model (SpiceDB, OpenFGA) and is the right choice for per-object, user-driven sharing.
- PBAC (OPA/Rego, AWS Cedar) is policy-as-code that in practice subsumes RBAC, ABAC, and ReBAC.
- Start with RBAC and layer the others where specific pain appears; the models compose rather than replace each other.
Every authorization model answers one question: what does an access decision depend on? RBAC depends on a role, ABAC on attributes, ReBAC on a relationship, and PBAC on a policy evaluated at runtime. They are not rivals so much as points on a complexity curve. Pick the simplest one that expresses the rules you actually have, and add the others only where that model starts to hurt.
The one question that separates all four
An access check is a function that returns allow or deny. What you feed that function is the whole distinction.
- RBAC feeds it a role: is this user an editor?
- ABAC feeds it attributes of the user, resource, action, and environment: is this user in the same department as the document, during business hours?
- ReBAC feeds it a relationship: is this user an editor of this specific document, or a member of a group that is?
- PBAC feeds it a policy: a piece of externalized code that can read roles, attributes, and relationships and return a decision plus an obligation.
Read that list again and you will notice the models compose. PBAC can evaluate attributes, which makes it a superset of ABAC in practice. ReBAC is really ABAC where the only attribute that matters is a graph edge. RBAC is ABAC where the only attribute is a role name. The differences that matter are operational: how the rules are stored, who can audit them, and how they behave when your object count and user count both explode.
RBAC: roles hold permissions, users hold roles
RBAC grants access by assigning users to roles, and roles to permissions. A user inherits every permission of every role they hold. That indirection is the entire point: you manage a handful of roles instead of thousands of individual grants, and onboarding becomes "give them the editor role" instead of a checklist.
The canonical model is NIST RBAC (https://csrc.nist.gov/projects/role-based-access-control), which formalized core RBAC plus role hierarchies and separation-of-duty constraints in the early 2000s. It is the default in nearly every system for a reason: it is simple to reason about, trivial to audit ("who has the admin role?"), and maps cleanly to how organizations already think about job functions.
Where it breaks is role explosion. The moment access depends on anything beyond job function, region, tenant, project, seniority, ownership, you encode each combination as its own role. editor, editor-emea, editor-emea-contractor, editor-emea-contractor-projectX. Roles multiply faster than users. I have seen enterprises with more roles than employees, at which point the model has stopped simplifying anything and become a worse version of per-user permissions. That is the signal to reach for a different model, not to define role number 4,001.
ABAC: policies over attributes
ABAC decides access by evaluating rules against attributes of four things: the user (department, clearance, employment type), the resource (owner, classification, project), the action (read, delete, approve), and the environment (time, IP, device posture). No roles required. A single rule like "allow read if user.department == resource.department and env.time is business hours" replaces a whole family of roles.
This is enormously expressive. Anything you can express as an attribute comparison, ABAC handles without minting new roles, which is exactly what kills RBAC. NIST published ABAC guidance in SP 800-162, and it is the right reach when access genuinely depends on context rather than fixed job function.
Where ABAC breaks is auditability and reasoning. Ask RBAC "who can delete this?" and you list role members. Ask ABAC the same question and the honest answer is "run every user against the policy engine and see." Access is computed, not stored, so it is hard to enumerate, hard to test exhaustively, and easy to get subtly wrong when three rules interact. Debugging a denied request means tracing which attribute on which of four objects failed. The power that solves role explosion is the same power that makes the system opaque.
ReBAC: relationship-graph traversal
ReBAC grants access based on relationships between subjects and objects, evaluated by traversing a graph. Instead of "user has role editor," you store the edge "user is an editor of document:123," and a check walks the graph to answer questions like "is this user a member of a group that is a viewer of a folder that contains this document?"
The reference design is Google's Zanzibar (https://research.google/pubs/pub48190/, the 2019 paper), which powers Drive, Docs, YouTube, and Calendar sharing. Its open descendants include SpiceDB, Ora, and OpenFGA. ReBAC is what you want the instant access becomes per-object and user-driven: "share this doc with Ana," "invite Bob to this repo," nested groups, ownership, folder inheritance. RBAC cannot express per-object sharing without a role per object, and ABAC can express it only by treating the entire relationship graph as one giant attribute, which is what Zanzibar actually is under the hood.
Where ReBAC breaks is operational weight and rules that are not about relationships. You are running a consistent, low-latency, planet-scale graph database for permission checks, and Zanzibar's "zookie" consistency tokens exist precisely because "did the revoke propagate yet?" is a genuinely hard problem. And a condition like "only during business hours" is not a relationship at all, so pure ReBAC has to bolt on attribute conditions (OpenFGA calls them contextual tuples) to cover what ABAC does natively.
PBAC: externalized policy-as-code
PBAC moves the authorization decision into an external policy engine, expressed as code, that your application calls at runtime. The application stops hardcoding if user.role == admin and instead asks a decision point: "here is the user, resource, action, and context, allow or deny?" The policy lives in version control, gets tested and reviewed like any other code, and is deployed independently of the app.
The two engines to know are the Open Policy Agent (https://www.openpolicyagent.org/), whose Rego language is a CNCF-graduated standard, and AWS Cedar (https://www.cedarpolicy.com/), which powers Amazon Verified Permissions and is designed to be analyzable. Both let a central team own policy across many services instead of scattering authorization logic through every codebase.
Here is the honest relationship to ABAC, because vendors muddy it: PBAC is the architectural pattern (externalized policy-as-code), and ABAC is one model you can express inside it. A Rego or Cedar policy that compares attributes is ABAC. But the same policy can also read roles (RBAC) and relationships (ReBAC), so PBAC in practice subsumes all three. When someone asks "ABAC or PBAC," they are comparing a rule model to a delivery mechanism. The useful reframing: PBAC is how you deliver and govern authorization; RBAC, ABAC, and ReBAC are what the rules are made of.
How to choose based on your authorization complexity
Choose the simplest model that expresses your real rules, then externalize when authorization logic outgrows your application code. The decision table below maps each model to its sweet spot and its failure mode.
| Model | Best fit | Where it breaks |
|---|---|---|
| RBAC | Fixed job functions, coarse-grained access, strong audit needs | Role explosion once access depends on context or per-object ownership |
| ABAC | Context-dependent access (department, clearance, time, device) | Auditability: access is computed, not enumerable; hard to test |
| ReBAC | Per-object, user-driven sharing; nested groups; ownership graphs | Operational weight; non-relationship conditions need bolt-ons |
| PBAC | Central governance of authorization across many services | Overkill for one small app; adds a policy engine to run and secure |
Use it in reverse too. If you cannot answer "who can access this?" without running code, you are in ABAC or ReBAC territory and need the tooling that comes with it. If you are minting roles faster than hiring, RBAC has already failed you.
Here is the same set as a quick comparison.
| Dimension | RBAC | ABAC | ReBAC | PBAC |
|---|---|---|---|---|
| Decision depends on | Role | Attributes | Relationship | Policy (any of the above) |
| Granularity | Coarse | Fine | Per-object | Whatever the policy says |
| Audit "who can X?" | Easy | Hard | Medium (graph query) | Depends on policy |
| Reference | NIST RBAC | NIST SP 800-162 | Google Zanzibar | OPA, AWS Cedar |
Migration paths as you scale
Start with RBAC and add the other models where specific pain appears; they compose rather than replace. Almost every system should begin with roles, because most early access really is coarse job function, and RBAC is the cheapest thing to build and audit.
A realistic progression:
- RBAC first. Roles and permissions cover the initial product. Do not over-engineer.
- Add ABAC conditions when context creeps in: tenant isolation, business-hours limits, device posture. Keep the roles; layer attribute checks on top. Many systems live happily here forever as "RBAC plus a few attribute rules."
- Add ReBAC the day you ship user-driven sharing (invite, share-with, nested teams, folder inheritance). This is a data-model change, not a tweak, so isolate it in a dedicated permissions service (OpenFGA, SpiceDB) rather than contorting your role table.
- Adopt PBAC when authorization logic is duplicated across enough services that you want one governed, testable, versioned source of truth. OPA or Cedar becomes the decision point; roles, attributes, and relationships all feed into it.
The mistake is skipping to the end. A three-service startup does not need Zanzibar and a Rego mesh; it needs roles and a clear head. Provisioning users into these systems is a separate concern handled by SCIM, and the login that establishes who the user is comes from OIDC; authorization only starts once identity is settled. For the wider security context, see Application Security 101, for the enterprise login layer that usually precedes all of this see Add SSO to Your B2B SaaS, and to evaluate platforms that implement these models see Top IAM solutions.
Key takeaways
- Pick the simplest model that expresses your actual rules; complexity you do not need is a permanent tax.
- If you are minting roles faster than you hire people, RBAC has already failed and you need attributes or relationships.
- The moment you ship user-driven sharing, you need ReBAC; do not fake it with a role per object.
- ABAC and ReBAC trade enumerable, auditable access for expressiveness; budget for the debugging and testing cost.
- PBAC answers how you deliver and govern authorization, not what the rules are made of; do not compare it to ABAC as an equal.
- Do not skip to Zanzibar plus a policy mesh on day one; a small app needs roles and a clear head.
Frequently asked questions
- RBAC or ABAC?
- Use RBAC when access follows fixed job functions and you need easy audits. Switch to or add ABAC when access depends on context like department, time, or device, and roles start multiplying.
- What is ReBAC?
- Relationship-Based Access Control decides access by traversing a graph of relationships between users and objects. It is the model behind Google Zanzibar and tools like SpiceDB and OpenFGA, built for per-object sharing.
- Is PBAC the same as ABAC?
- No. PBAC is the pattern of externalizing authorization as policy-as-code in an engine like OPA or Cedar. ABAC is one rule model you can express inside PBAC, alongside roles and relationships, so PBAC usually subsumes ABAC.
- When should I move off RBAC?
- When you are creating roles faster than you add users, or when access depends on context or per-object ownership that a role cannot express. That is the point to layer in ABAC conditions or a ReBAC service.
- Do these models compose?
- Yes. Most mature systems run RBAC with ABAC conditions on top, add ReBAC for sharing, and eventually feed all three into a PBAC engine as a single governed decision point.
Related
Research pillars
Vendor comparisons
Sibling guides