What Is ReBAC? Relationship-Based Access Control vs RBAC

Guilliano Molaire Guilliano Molaire 10 min read

ReBAC (relationship-based access control) is an authorization model in which a user can do something to an object because of how the two are related: the user is the owner of the document, a member of the team that owns the folder, or the person the ticket is assigned to. A ReBAC system decides by looking for a path of relationships from the user to the object that grants the permission, where an RBAC system looks up the roles the user holds. For most applications with a small set of job functions, plain RBAC is enough, and ReBAC starts to pay off when access depends on individual objects, such as sharing one document with one customer.

How does ReBAC decide access?

Subjects (users, teams, services) and objects (documents, projects, tenants) are connected by relationships, and a permission is computed by walking those relationships. If Anna is a member of the “Finance” team, and the “Finance” team is a viewer of the “Q3” folder, then Anna can view the “Q3” folder and, if folders pass access down to their contents, every document inside it. Nobody had to grant Anna access to each document, and removing her from the team removes all of it in one step.

Where does ReBAC come from?

ReBAC was described in academic work in the late 2000s (for example Fong’s “Relationship-Based Access Control: Protection Model and Policy Language”, presented at ACM CODASPY in 2011), and Zanzibar is the system that brought it into mainstream engineering practice. Google described it in “Zanzibar: Google’s Consistent, Global Authorization System” (Pang et al., USENIX Annual Technical Conference, 2019), which describes the system Google uses to answer authorization checks for products such as Drive, where access to a file depends on sharing with individuals, groups, and parent folders. Zanzibar stores access as relationship tuples and answers checks by evaluating those tuples together with rules for how relations combine.

Several open implementations follow that design. OpenFGA (a Cloud Native Computing Foundation project that started at Auth0) and SpiceDB (from Authzed) are two widely used open-source implementations, and both are documented as Zanzibar-inspired. You write a model that declares the types and relations in your domain, you write tuples as your application’s data changes, and you call a check API at request time.

What does a ReBAC model look like?

The example below is written in the OpenFGA modeling language (schema 1.1). It describes users, organizations, folders, and documents, where members of an organization can view the folders that organization owns, and a document inherits the viewers of the folder that contains it.

model
  schema 1.1

type user

type organization
  relations
    define member: [user]
    define admin: [user]

type folder
  relations
    define owner_org: [organization]
    define viewer: [user, organization#member] or member from owner_org

type document
  relations
    define parent_folder: [folder]
    define owner: [user]
    define viewer: [user] or owner or viewer from parent_folder

The data is a set of tuples, each saying that one user, or one object, has a relation to another object. Tuples are written here as user, relation, object, which is the order OpenFGA’s API uses for the fields (the Zanzibar paper writes object, relation, user).

user:anna          member         organization:acme
organization:acme  owner_org      folder:finance
folder:finance     parent_folder  document:q3-report
user:ben           owner          document:q3-report

In words, Anna is a member of Acme, Acme owns the Finance folder, the Q3 report sits in the Finance folder, and Ben owns the Q3 report. A check for “can user:anna be a viewer of document:q3-report?” returns true. The document’s viewer relation includes viewer from parent_folder, so the check moves to folder:finance. The folder’s viewer relation includes member from owner_org, so it moves to organization:acme, where Anna holds the member relation. A check for Ben also returns true, through the direct owner tuple, since owner is part of the document’s viewer definition. Neither answer required a role such as “finance-reader” to exist.

Three parts of the model are not exercised by these tuples. The admin relation on organization is defined but no rule uses it, so an admin who is not also a member gets no folder access here; adding or admin from owner_org to the folder’s viewer would extend it. The [user, organization#member] list on the folder allows direct grants, such as a tuple giving the members of one organization viewer access to a folder that organization does not own, or giving a single user access to it. The direct [user] on the document’s viewer allows sharing one document with one person. If you want to try the syntax yourself, the OpenFGA documentation has a playground and a section on parent-child modeling that works through this same folder and document pattern.

ReBAC vs RBAC vs ABAC: what is the difference?

The three models differ in what the authorization decision is based on, which is easiest to see by stating the rule each one follows.

Model The rule in one line Decision is based on Typical example
RBAC You can do what your role allows The user’s role “Editors can publish articles”
ABAC You can do it if the attributes satisfy the policy Attributes of user, resource, and context “Doctors can read records from their own department during their shift”
ReBAC You can do it if a relationship path grants it Relationships between user and object “Members of the team that owns the project can edit it”

RBAC answers “what kind of user is this?”, and we cover it in understanding RBAC and on the RBAC feature page. ABAC answers “do the facts about this request satisfy a policy?”, which we describe in attribute-based access control. ReBAC answers “how is this user connected to this object?”. The models overlap in practice, since a relationship can be treated as an attribute and a role can be modeled as a relationship to a tenant, and many real systems combine them.

When should you use ReBAC?

ReBAC pays off when the thing you are authorizing is a specific object rather than a type of action. The usual signals are the following.

  • Per-object sharing. Users share individual documents, boards, or projects with chosen people, as in Drive or Notion. With roles alone you would need a role per object.
  • Multi-tenant B2B products. Each customer organization has its own members and admins, and the same user may be an admin in one tenant and a viewer in another. The relationship “admin of tenant X” carries that naturally.
  • Hierarchies. Organizations contain teams, teams own projects, and projects contain resources, and access should flow down the hierarchy and be revocable at any level.
  • Delegation. Someone grants a colleague, a contractor, or a service temporary access to something that belongs to them.

When is RBAC plus a few attributes enough?

If your application has a handful of job functions, such as admin, editor, and viewer, and access depends on the type of user rather than on which individual object they touch, roles are simpler to build, easier to audit, and supported by mainstream identity providers. Adding a couple of attributes covers most of the remaining cases: a tenant_id claim to keep customers apart, a department claim for a team-scoped view, or an OAuth scope for a limited API grant (see OAuth scopes explained). A separate relationship store is another system to run, populate, and keep consistent, so it is worth adding only when you can name the object-level requirement that roles cannot express.

How does ReBAC apply to AI agents?

AI agents make the object-level question more common, because an agent usually acts for one user on one task and should hold only the access that task needs. In a relationship model an agent can be a principal of its own, with relationships that are scoped to a task, that can expire (through conditional tuples in OpenFGA, or relationship expiration in SpiceDB), and that can be revoked without touching the user it works for. OpenFGA’s documentation includes an AI agent authorization guide that describes agents as first-class principals with delegated, not copied, access, so permissions are granted to the agent explicitly rather than inherited wholesale from the user.

Auth0’s article, “AI Agents Are Not Users“, argues that AI agents are distinct identities from both human users and classic machine identities. For the identity side of the same problem, see our post on non-human identity and AI agents in Keycloak.

What does the architecture look like?

The common pattern splits the work between two systems. The identity provider authenticates the user and issues a token containing who they are (the subject identifier, sub), which tenant they belong to, and coarse roles. A relationship store such as OpenFGA or SpiceDB then answers the fine-grained question at request time: the application sends a check of the form “user, relation, object” and receives allow or deny.

The token is a good place for facts that change rarely and apply to the whole session, and the relationship store is the right place for facts that change per object and per moment, such as “Ben just shared this board with Anna”. Putting per-object grants in a token would make it large and stale, and putting identity in the relationship store would duplicate the user directory.

How does ReBAC fit with Keycloak?

Keycloak is an identity provider, and it is not a Zanzibar-style relationship store. It gives you several useful coarse and mid-grained tools: realm and client roles, groups (including nested groups), and Authorization Services, where you define resources, scopes, policies, and permissions and can evaluate them for a token. Our post on fine-grained authorization in Keycloak explains what that covers. Authorization Services supports per-resource permissions, including UMA-based sharing where a resource owner grants another user access, and an entitlement request can return everything a user is permitted. What it does not do is model arbitrary-depth object-to-object graphs or efficiently answer “list every document Anna can view” across millions of objects, which Zanzibar-style engines are built for. For a side-by-side comparison of Auth0 FGA and Keycloak Authorization Services, see Auth0 FGA permissions index versus Keycloak Authorization.

A practical split is to use Keycloak groups and roles for access to the application and the tenant, keep Authorization Services for the resource types where its policies are enough, and run OpenFGA or SpiceDB for the objects that need relationship-based sharing. The sub claim in the Keycloak token becomes the user identifier in the relationship store (for example user:<sub>), so both systems refer to the same person.

Skycloak is identity management as a service built on Keycloak, so it supplies the identity layer (users, organizations, roles, and tokens) that a relationship-based engine keys off. Skycloak does not ship a ReBAC engine, and the relationship store stays your own component.

What are the common pitfalls?

  • Keeping the two systems in sync. When a user is deleted or leaves an organization in the identity provider, their tuples in the relationship store must be removed too, or you retain access for an identity that no longer exists. Drive this from identity events or from your application’s own lifecycle code, and run a periodic reconciliation.
  • Check latency. Every protected request now includes a call to the authorization service, so put it close to the application, reuse connections, and use batch checks where the API offers them. Deep hierarchies make checks more expensive.
  • Consistency. The Zanzibar paper addresses the “new enemy problem”, where a check ignores the order of an access change and a later content change, for example showing new content to a user who was removed just before it was added. It does so with tokens it calls zookies, which let a caller ask for data at least as fresh as a previous write. SpiceDB exposes this as ZedTokens and per-request consistency levels (minimize_latency is the default for reads such as checks, and at_least_as_fresh and fully_consistent are stricter). OpenFGA offers MINIMIZE_LATENCY and HIGHER_CONSISTENCY on its query APIs, and it has no zookie or ZedToken equivalent. Its cache is off by default, so all queries are strongly consistent until you enable caching, and the consistency mode matters once you do, because the stricter option bypasses the cache at a performance cost. Choose the stricter level for operations where a just-revoked permission must take effect immediately.
  • Model design. Changing a relationship model later means migrating tuples, so start from your real sharing scenarios and keep the model small.

Choosing a model

Start by listing the access rules your product really has, and mark each as depending on the user’s job function, on facts about the request, or on how the user is connected to a specific object. If nearly all of them fall in the first group, roles with a few token claims will serve you well. If a meaningful share fall in the third group, especially sharing, hierarchies, and per-tenant administration, a relationship engine alongside your identity provider is likely to cost less than approximating those rules with ever more roles.

Frequently asked questions

What is ReBAC vs RBAC?

RBAC grants access based on the role a user holds, so everyone with the “editor” role gets the same permissions. ReBAC grants access based on the relationship between a user and a specific object, so two users with the same job title can have different access to the same document. The two work well together, with roles handling coarse access and relationships handling per-object access.

Is ReBAC the same as Zanzibar?

Zanzibar is Google’s implementation, described in a 2019 paper. ReBAC is the general model, described in academic work earlier, and Zanzibar brought it into mainstream engineering practice. OpenFGA and SpiceDB are open implementations inspired by Zanzibar.

Is ReBAC better than ABAC?

Neither is better in general. ABAC suits rules written over attributes such as department, time, or device, while ReBAC suits access that follows ownership, membership, and hierarchy. Many teams use both, and a relationship can be passed into an ABAC policy as an attribute.

Can Keycloak do ReBAC?

Not as a native relationship store. Keycloak Authorization Services covers per-resource permissions and sharing, but not arbitrary-depth object graphs, as described in the Keycloak section above. For graph-style sharing it is common to pair Keycloak with OpenFGA or SpiceDB, keyed on the token’s sub claim.

Do I need a separate service for ReBAC?

You can model simple relationships in your own database tables, and many applications start that way. A dedicated engine is worth considering when you need inherited access, “list everything this user can see” queries, and consistent behavior across several services.

Should AI agents have their own relationships?

Giving an agent its own identity and task-scoped, expiring grants limits what a mistaken or manipulated agent can do, and makes its access revocable without affecting the user. Whether you express those grants as relationships, scopes, or policies depends on how fine-grained they need to be.

Identity management as a service, on open source

Skycloak does what Auth0 and Okta do, SSO, MFA, SCIM, audit logs and enterprise federation, on an open source core. Unlimited users and applications on every plan, no charge per monthly active user, and you can export and self-host whenever you want.

Guilliano Molaire
Written by
Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Start Free Trial Talk to Sales
© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman