RBAC vs ReBAC: Two Authorization Models, Two Philosophies

Emmanuel Gautier Emmanuel Gautier ·
Authorization

Every application eventually hits the same wall. The permission system that worked at launch — a handful of roles, a simple check before every action — starts to crack under real-world complexity. New resource types appear. Users need granular control over what they share and with whom. Teams want to delegate access without involving an administrator. And suddenly the clean admin / member / viewer model is generating hundreds of bespoke roles that nobody can audit.

Two authorization models dominate the conversation at that inflection point: Role-Based Access Control (RBAC) and Relationship-Based Access Control (ReBAC), the model popularized by Google’s Zanzibar paper. This article explains how each one works, where each one fails, and how to choose between them — or combine them.


The question both models are trying to answer

Before comparing the approaches, it helps to state the problem precisely. At the core of any authorization system is a single question:

Given this user, this resource, and this action — is the access allowed?

The models differ in how they represent the answer and where the complexity lives.

To make the comparison concrete, we’ll use a single running example throughout this article: a B2B SaaS project management tool. Users belong to organizations. Organizations own workspaces. Workspaces contain projects. Projects contain documents. Users can share individual documents with collaborators — inside or outside their organization. It’s a deliberately ordinary product, and that’s the point: it’s the kind of system where authorization complexity sneaks up on you.


RBAC: the role-based model

How it works

RBAC is the most widely used authorization model in enterprise software, and for good reason — the mental model is immediately intuitive. Think of it like a job title. A user is assigned a role (admin, editor, viewer), and that role carries a set of permissions (create_project, edit_document, read_document).

The implementation is essentially two tables:

UserRole
aliceadmin
bobeditor
carolviewer
RolePermission
admincreate_project, delete_project, invite_member, edit_document, read_document
editoredit_document, read_document
viewerread_document

To answer the question “can Bob edit this document?”, the system looks up Bob’s role (editor), checks whether edit_document is in that role’s permission set, and returns yes or no. The check is O(1). The model is easy to explain to a compliance auditor. It maps naturally to how organizations already think about access — job titles and departments.

RBAC model: users mapped to roles mapped to permissions

Where RBAC works well

RBAC is the right model when your permission domain is flat, stable, and product-wide:

  • An internal admin dashboard with two or three user types
  • A SaaS product at MVP stage where “admin can do everything, member can do most things, viewer can only read” is genuinely true
  • Compliance-heavy contexts (SOC 2, HIPAA) where auditors want to see a clean mapping between roles and access rights
  • Products where permissions don’t need to vary per resource instance — every editor has the same rights on every document

Where RBAC breaks down

The trouble starts the moment permissions need to vary at the resource level.

In our project management example: Alice is an editor for Project X but only a viewer for Project Y. Bob owns Document 42 and wants to share it read-only with an external contractor, Carol, without giving Carol any other access to the workspace.

The naive RBAC response is to create more roles: editor-of-project-x, editor-of-project-y, viewer-of-doc-42. This is called role explosion — a combinatorial proliferation of roles that grows with every new project, document, or sharing arrangement, until the role list is unmanageable and the system no longer provides meaningful access boundaries.

The second failure mode is privilege creep. RBAC records what a user can do, but not why. When Alice moves from the engineering team to marketing, her editor-of-project-x role doesn’t automatically revoke. The original organizational relationship that justified the permission is gone; the permission persists. Over time, users accumulate roles that no longer reflect their actual position in the organization.

These aren’t edge cases. They are the natural trajectory of any product that allows resource-level sharing or organizational restructuring.


ReBAC: the relationship-based model

The key insight

Relationship-Based Access Control shifts the question from “what roles does this user have?” to “what is this user’s relationship to this resource?”

Instead of a global role table, the authorization state is a graph of relationships between entities: users, documents, folders, projects, organizations, teams. Permissions are derived by traversing that graph.

The mental model is closer to a social network than an org chart. Alice doesn’t have an editor role globally — she is an editor of Project X specifically. That relationship is a directed edge in the graph. When Project X contains Document 42, the graph contains a second edge: Document 42 is a child of Project X. To check whether Alice can edit Document 42, the engine traverses the path: Alice → editor of → Project X → parent of → Document 42. Access granted.

Google Zanzibar and the tuple model

ReBAC as a discipline predates Google, but the model as it’s implemented in modern systems was formalized by the Zanzibar paper, published at USENIX ATC in 2019. Zanzibar is the authorization system behind Google Drive, YouTube, Google Calendar, and virtually every other Google product. It handles trillions of objects across hundreds of millions of users.

The core data primitive in Zanzibar is the relation tuple, written as:

<object>#<relation>@<user>

A few examples from our project management product:

project:X#editor@alice
project:X#viewer@bob
document:42#parent@project:X
team:alpha#member@carol
project:X#viewer@team:alpha#member

That last line is where the power shows. It says: “anyone who is a member of team:alpha is a viewer of project:X.” When Carol is added to team:alpha, she immediately gets viewer access to project:X and all its documents — without any role reassignment.

The authorization check engine traverses these tuples as a graph, following edges until it can confirm or deny the access. Importantly, this traversal respects inheritance: if you have a rule that “editors of a folder are also editors of the documents inside it,” the engine follows that chain automatically.

ReBAC graph model: relationship tuples connecting users, teams, and resources

The open-source ecosystem

Zanzibar itself is not publicly available, but the paper sparked a generation of open implementations:

  • OpenFGA — originated at Auth0/Okta, now a CNCF Incubating project (v1.13 as of early 2026). The most widely adopted Zanzibar implementation.
  • Ory Keto — part of the Ory stack, cloud-native, headless, API-first. Well suited to teams already running Ory Kratos or Hydra.
  • SpiceDB (Authzed) — commercial Zanzibar implementation with a strong consistency model.
  • Permify — OSS Zanzibar with a growing adoption curve and a lightweight operational profile.

These systems all expose a similar API: write relationship tuples, define a schema (which relations exist, and which relations inherit from others), and ask permission check questions.

Where ReBAC shines — and where it doesn’t

ReBAC handles naturally the cases where RBAC role-explodes:

  • Per-resource permissions that differ between users
  • Deep resource hierarchies (organization → workspace → project → document → comment)
  • User-driven sharing (“share this document with carol@example.com as a viewer”)
  • Multi-tenant architectures where each organization manages its own permission topology

The trade-offs are real, though. Permission checks involve graph traversal, which is more computationally expensive than a table lookup — though production systems mitigate this with caching and query optimization. More significantly, auditability is harder: in RBAC, a compliance auditor can ask “list all permissions for this role” and get a table. In ReBAC, permissions are discovered at runtime through graph traversal, which makes static audit queries more complex. Tools like OpenFGA’s list-objects and list-users queries help, but the model requires more investment to make fully auditable.

ReBAC is also limited to relationships that can be expressed as graph edges. It cannot natively handle dynamic context: “allow access only during business hours,” or “allow delete only if the document status is draft.” For those conditions, you need attribute-based logic (ABAC) layered on top.


Head-to-head comparison

DimensionRBACReBAC (Zanzibar-style)
Mental modelJob title → permission setGraph of relationships between entities
Permission granularityProduct-wide (same role = same access everywhere)Per-resource (Alice can edit X but not Y)
Permission inheritanceManual (must reassign roles)Automatic (via graph traversal)
Scalability of the modelBreaks down past ~10 roles (role explosion)Scales to billions of objects
AuditabilityHigh — a role is a static, inspectable listModerate — permissions discovered at query time
Implementation complexityLowMedium to high
Runtime performanceO(1) table lookupGraph traversal (mitigated by caching)
User-driven sharingAwkwardNatural
Handles dynamic contextNoNo (needs ABAC for that)
Best starting pointYesAfter RBAC starts to crack

When to choose which

Choose RBAC when:

  • Your permission model fits in fewer than ~10 stable role categories
  • Permissions don’t vary per resource instance — every editor is an editor of everything
  • You need fast compliance audit trails (SOC 2 auditors appreciate a simple role matrix)
  • You’re at MVP stage and operational simplicity is the priority
  • Your team doesn’t yet have dedicated infrastructure for a separate authorization service

Choose ReBAC when:

  • Users need to control sharing at the level of individual resources
  • You have a deep resource hierarchy and permissions need to flow down through it
  • You’re building a collaborative product (document editors, project tools, file sharing)
  • You’re multi-tenant B2B SaaS and each organization needs to manage its own permission topology without your engineering team being involved
  • You’re already experiencing role explosion

The hybrid reality

Most mature SaaS products don’t choose one model exclusively — they run both in layers. RBAC handles the coarse-grained product policy: “admins can configure the workspace, members can create projects, viewers can only read.” ReBAC handles the fine-grained resource policy: “Alice is an editor of this specific project, Carol is a viewer of this specific document.”

The practical signal for when to add ReBAC: when your engineering team starts creating roles like editor-of-project-x to handle resource-specific permissions, that’s role explosion beginning. That’s the moment to introduce a relationship layer.


Connection to CIAM and identity infrastructure

One important architectural distinction: RBAC and ReBAC live in your authorization layer, not your authentication layer.

Your CIAM platform (Auth0, Ory Kratos, Cognito, Stytch, etc.) handles identity — who the user is, how they authenticated, which organization they belong to. Most CIAM platforms ship native support for RBAC: they store roles on user profiles and emit them in tokens at login time.

ReBAC requires a separate authorization service alongside your CIAM. OpenFGA, Ory Keto, and SpiceDB are all designed to run independently of the identity provider. Your CIAM authenticates the user; your ReBAC engine decides what that user can access.

User management tooling — including operational admin interfaces like AUMS — operates at the identity layer: it surfaces role assignments, organization membership, and team structure that feed into whichever authorization model the application uses downstream. Good user admin tooling makes it easy to inspect and modify these assignments without developer involvement, regardless of whether the downstream model is RBAC, ReBAC, or both.


Conclusion

The choice between RBAC and ReBAC is not about which model is technically superior. It’s about matching the model to the complexity of your permission domain.

RBAC is the right starting point for most products. It’s simple, auditable, and maps naturally to how organizations think about access. The moment you find yourself creating resource-specific roles to work around its limitations, that’s the signal to introduce a relationship layer.

ReBAC, in the Zanzibar tradition, handles the permission scenarios that RBAC role-explodes on. It requires more infrastructure and more schema design, but it’s the model that scales with a product as sharing, delegation, and resource hierarchies grow more complex.

Most teams end up running both: RBAC for product-level policy, ReBAC for resource-level decisions. Understanding the boundary between them — and recognizing the moment to cross it — is one of the more consequential architectural decisions in a growing SaaS product.