Back to listing

RBAC vs ReBAC: a comparison of authorization models with examples

Noa Shavit avatar

Noa Shavit

Head of Marketing

Dec 6th, 2022

ReBAC  |  

RBAC

role-based access control vs relationship-based access control models

Every application requires access control to secure protected resources. The most simple form of access control is one in which sets of permissions are aggregated into roles (e.g. Admin, Editor, or Viewer) which are assigned to users. This popular authorization model is known as role-based access control (RBAC). RBAC allows organizations to answer questions like “Can Sally push to production?” and “Which users can push to production?”

As applications grow in complexity more granular controls are required. This is when relationship-based access control (ReBAC) comes into the picture. ReBAC adopts RBAC’s concept of aggregating a set of permissions, but instead of assigning them to users/groups, relationships between users and objects (e.g. projects, lists, folders, etc.), can be defined at any level of the resource hierarchy to determine access. The result is a fine-grained access control model that allows the organization to answer questions like “Can Ian edit the strategy doc for ACME projects” and “Who can edit the strategy document we created for ACME projects?”

In this post, we dive into the similarities and differences between role-based and relationship-based access control. We also provide a couple of example policies for RBAC, ReBAC, and a combination of the two.

Role-based access control (RBAC)

Role-based access control

RBAC is a popular authorization model, used by the likes of Slack, MailChimp, and Bill.com. It's simple and straightforward. Permissions are aggregated into roles and users are associated with groups that are assigned roles. Grouping permissions into roles and users into groups limits the number of rules that need to be defined to grant users the appropriate permissions.

In this model, when a subject (user/group) tries to access a resource, the authorization system expects the roles assigned to that subject to contain the required permissions to access the resource. If they do not, access is denied.

For example, view, edit, and delete permissions are grouped to form roles. A Viewer role would map to the view permission, an Editor would combine view and edit, and Admin would group all three. A Viewer cannot edit any resource, because that role does not have the edit permission. Both Admins and Editors can edit resources because the edit permission is associated with both roles.

The mapping between roles and permissions doesn’t change very often and can be defined statically in an authorization policy (for example, a data.json file in an Open Policy Agent policy). Here is an example of how you can define the Viewer, Editor, and Admin roles:


{
 "roles": {
   "viewer": {
     "perms": {
       "view": {
         "allowed": true
       }
     }
   },
   "editor": {
     "perms": {
       "view": {
         "allowed": true
       },
       "edit": {
         "allowed": true
       }
     }
   },
   "admin": {
     "perms": {
       "view": {
         "allowed": true
       },
       "edit": {
         "allowed": true
       },
       "delete": {
         "allowed": true
       }
     }
   }
 }
}

RBAC models are easy to reason about, modify and audit. We would recommend using the role-based access control model when you’re able to form a relatively static mapping between users, roles, and resources.

In some cases, however, role-based access control bears the risk of “role explosion,” where a large number of roles is required to cover every required scenario. In those situations, we would recommend using other authorization models (such as ReBAC) either instead of, or in tandem with, the role-based model.

RBAC resources

Here are a few resources to help you get started with role-based access control:

A developer’s guide to RBAC and ABAC

RBAC best practices

Building RBAC in Node

Building RBAC in Go

Building RBAC in Python

Relationship-based access control (ReBAC)

Relationship-based access control

ReBAC is an authorization model that assigns permissions based on relations between resources. Relations include data ownership, parent-child relationships, groups, and hierarchies. Google Zanzibar, the authorization system for Drive, YouTube, and other Google services, is most commonly associated with this authorization model.

ReBAC allows organizations to model their application’s resource hierarchy so that the authorization model matches it. Most B2B apps have tenants or organizations at the top of their resource hierarchy, followed by an internal hierarchy of resources, such as teams, projects, lists, folders, and even individual items. ReBAC allows organizations to restrict access at any level of the hierarchy and apply the principle of least privilege using fine-grained access control.

To build relationship-based access control developers need to describe a relationship graph between subjects (users/groups) and objects (teams, projects, lists, folders, individual items) in their system. Once done, the authorization policy will check whether a particular type of relationship exists for any user or resource and determine if access is granted or denied based on that information.

For example, a document-sharing application has a hierarchical structure between a set of folders and documents. It has set up its authorization policy in such a way that when a user is granted permission to perform actions on a “parent” folder, they are allowed to perform actions on any item that is contained within that folder. The can-view and can-edit permissions are associated with the Editor relationship and the can-view permission is associated with the Viewer relationship.

Here’s an example of how we can specify the can-edit permission in the policy:

package example.rebac.edit.__fileSystemResource 
fileSystemResource = ds.object({
 "key": input.resource.fileSystemResource,
 "type": "file-system-resource",
})
 
user = ds.object({
 "key": input.user.id,
 "type": "user",
})
 
allowed {
  ds.check_permission({
    "subject": { "id": user.id },
    "permission": "can-edit",
    "object": { "id": fileSystemResource.id }
  })
}

All in all, ReBAC offers organizations fine-grained access control at every level of their resource hierarchy, down to the individual item. It is a powerful and flexible model, but it can bring significant management complexity, especially as your scale. When every resource in your system needs to be present in both your database and your authorization system, you quickly run into consistency issues.

Thankfully, there are services out there, like Aserto, that allow organizations to combine ReBAC with other authorization models, like RBAC, to enjoy the benefits of each.

ReBAC resources

Resources to help you get up to speed with relationship-based access control:

RBAC, ABAC, and ReBAC example policies

Topaz open-source authorizer

Documentation


Combining RBAC and ReBAC

Both authorization models have their merits. RBAC might be good enough for one of your applications (e.g. an internal dashboard), or a specific service, but insufficient for your commercial offering. Thankfully, we aren’t limited to using only one authorization model at a time.

For example, we can write an access control policy that enforces the following rules:

  • If a user is an Admin, they may edit any file system resource
  • If a user has been explicitly granted the can-edit permission to a particular resource, they may do so regardless of any other condition

Here is what that policy would look like:

package example.rebac.edit.__fileSystemResource
 
user_attributes = input.user.properties.attributes

fileSystemResource = ds.object({
 "key": input.resource.fileSystemResource,
 "type": "file-system-resource",
})
 
user = ds.object({
 "key": input.user.id,
 "type": "user",
})
 
allowed {
  user_attributes.roles == "admin"
}
 
allowed {
  ds.check_permission({
   "subject": { "id": user.id },
   "permission": "can-edit",
   "object": { "id": fileSystemResource.id }
  })
}

Conclusions

Role-based access control is a straightforward authorization model, but it relies on static roles. Relationship-based access control adopts RBAC’s concept of roles (i.e. relations) as a mechanism to aggregate a set of permissions but provides the ability to create relations between subjects and objects at any level of the resource hierarchy, which results in much finer-grained access than traditional RBAC.

The good news is that you don’t have to commit to just one model. Aserto lets you scale from one authorization model to another and even combine RBAC, ReBAC, and ABAC as you see fit, for complete flexibility and control.

Authorization is hard, but we are here to help! Book a time to speak with an engineer about your specific challenges and needs today or sign-up for free to experience Aserto for yourself.