Relationship-Based Access Control

Understanding ReBAC

Descope supports full Relationship-Based Access Control (ReBAC) to manage access permissions in your application based on relationships between entities. Create a schema, define relationships, and add checks to your application using our APIs and SDKs.

Practical Scenario for ReBAC instead of RBAC

An E-commerce platform

With RBAC, access is granted based on roles like Seller, Buyer, or Admin. A seller with a generic seller role would have the same access rights as any other seller, which might include managing listings, processing orders, and handling customer queries.

However, RBAC could have limitations in this scenario:

  • One-Size-Fits-All: All sellers have identical access privileges regardless of their specific relationship with the buyer or the product. For example, sellers cannot offer personalized deals or discounts to repeat customers or manage after-sale services uniquely for each customer.
  • Static Permissions: The RBAC system cannot easily accommodate temporary or conditional permissions, such as allowing a buyer to track the progress of a custom-made item directly through the seller's interface.

ReBAC, on the other hand, can provide access controls that adapt to the relationships between users:

  • Seller-Customer Relationships: Sellers might give specific customers special access to pre-orders or exclusive products based on their purchase history or membership status.
  • Collaborative Features: For custom-made items, the relationship between a buyer and seller could allow for a direct communication channel within the platform, enabling the buyer to provide input or get updates on their order's progress.
  • Dynamic Permissions: Access permissions can evolve in real-time. For instance, a buyer might have temporary access to a seller's design tool to customize a product, which expires after the order is finalized. In the e-commerce platform scenario, ReBAC allows for a more nuanced and customer-centric approach. It enables dynamic access control based on the evolving relationships between sellers, buyers, and products. In contrast, RBAC's static roles might not effectively handle the varied and personalized interactions that modern e-commerce platforms often facilitate.

Key Concepts

Before implementing ReBAC in Descope, it's important to understand the below key terms & concepts that we will refer to in the rest of the guide.

Schema

A combination of one or more types. This is used to define a permission model of a system. Here's an example of part of a schema:

model AuthZ 1.0
 
type user
 
type group
  relation member: user
  relation super_admin: user
 
type folder
  relation parent: folder
  relation owner: user | group#member
  relation editor: user | group#member
  relation viewer: user | group#member
 
  permission can_create: owner | parent.owner | parent.can_create
  permission can_edit: editor | parent.editor | can_create
  permission can_view: viewer|parent.viewer|can_edit
 
type doc
  relation parent: folder
  relation owner: user | group#member
  relation editor: user | group#member
  relation viewer: user | group#member
 
  permission can_create: owner|parent.owner
  permission can_edit: editor | parent.editor & can_create
  permission can_view: (viewer | parent.viewer) - can_edit

The schema, together with Relations, allows determination of whether a relationship exists between a user and a resource. The schema can be loaded programmatically via SDK/API or modified in the Descope console.

Type

Defines a class of objects with similar characteristics and holds Relation Definitions. Examples include:

  • Document
  • Folder
  • User
  • Organization

Relation Definitions

Defines all the possible relations a user or other object can have to a Namespace. An example looks like:

relation parent: folder
relation owner: user | group#member
relation editor: user | group#member
relation viewer: user | group#member

Resource

Represents an entity in the system. It is simply an identifier, not necessarily tied to a Namespace:

  • fb83c013-3060-41f4-9590-d3233a67938f
  • descope/java-sdk
  • org_ajUc9kJ
  • new-roadmap

Targets, Relation Definitions, and Resources are the building blocks for Relations.

Target or Target Set

A Target is a unique identifier, not necessarily tied to a Namespace. A Target Set is a group or set of users/entities related by a unique identifier, a Namespace, and a Relation Definition.

Like a Resource, a Target looks as follows:

  • any identifier: e.g. lisa or 4179af14-f0c0-135-88fd-5570c7bf6f59
  • any object: e.g. fb83c013-3060-41f4-9590-d3233a67938f, descope/java-sdk or ajUc9kJ

The Target Set:

  • a group or a set of users (also called a userset): e.g. organization#members, which represents the set of users related to the object as member

Relation

An tuple consisting of a Target or Target Set, Relation Definition, and Resource stored in Descope&aposs FGA service.

A Relation consists of a:

  • Target or Target Set, e.g. anne, 3f7768e0-4fa7-4e93-8417-4da68ce1846c, descope
  • Target Type, eg. user, group#member, folder#editor
  • Relation, e.g. editor, member or parent_workspace
  • Resource, e.g note-1, descope.com or marketing
  • Resource Type, eg. note, site, org

An authorization Schema together with Relations, allow the determination of whether a relationship exists between a Target and a Resource.

Throughout the documentation, you will encounter Relations represented as:

Relation("n1", "note, "can_view", "u1", "user")

Direct and Implied Relations

A direct relationship between user X and object Y means the Relation (target=X, relation definition=R, resource=Y) exists, and the Descope FGA authorization model for that relation allows this direct relationship.

An implied (or computed) relationship exists between target X and resource Y if target X is related to a resource Z that is in a direct or implied relationship with resource Y, and the Descope FGA authorization model allows it.

Implementing ReBAC in Descope

The general process of setting up ReBAC in Descope is as follows:

  1. Defining a schema: Establish the types of entities (e.g., user, document) and the possible relationships (e.g., owner, editor) that exist within your application.
  2. Saving a schema: Store the schema in a way that it can be efficiently queried and managed, ensuring it can be updated as the relationships evolve.
  3. Creating relations: Build out the actual linkages between specific entities based on your defined schema, which will serve as the foundation for making access decisions.
  4. Adding relations checks: Integrate checks into your application to consult the defined relationships and confirm if a user's action is authorized.

A full code example

After you've completed the aforementioned steps, you'll have employed code looking something like the below, with everything from implementing a schema to creating and checking relations. The schema is loaded from a YAML file (as shown in the define schema example section), and the relations are created and checked using the Descope SDK.

const schema = {
  dsl: `
  model AuthZ 1.0
  type user
 
  type group
    relation member: user
    relation owner: user
 
  type note
    relation owner: user | group#member | group#owner | group
    relation editor: group | group#member | group#owner | user
    relation viewer: group | group#member | group#owner | user
 
    permission can_edit: editor | owner
    permission can_view: viewer | can_edit
`
}
await descopeClient.management.fga.saveSchema(schema)
 
await descopeClient.management.fga.createRelations([
  {
    resource: 'some-doc',
    resourceType: 'doc',
    relation: 'owner',
    target: 'u1',
    targetType: 'user',
  },
]);
const relations = await descopeClient.management.fga.check([
  {
    resource: 'some-doc',
    resourceType: 'doc',
    relation: 'can_view',
    target: 'u1',
    targetType: 'user',
  },
]);
 
const target: string = 'u1';
const relations = await descopeClient.management.authz.whatCanTargetAccess(target);
 

Next Steps

Now that you have a high-level vision of the ReBAC implementation process, let's move on to defining a schema.

Was this helpful?

On this page