Skip to main content

Create a ReBAC Policy

Build a relationship-based access control (ReBAC) policy in the Permit.io dashboard, then test it with a permission check. This walkthrough is for developers who have built a role-based access control (RBAC) policy and need permissions that follow relationships between objects. You model dashboards that contain widgets, so a role on a dashboard gives a role on every widget in it.

Prerequisites

Define the policy schema

The example is a dashboarding system with two resource types. Dashboard is the parent. Widget is the child. Each resource has its own roles: Owner, Viewer, and Analyst on dashboards, and Owner, Viewer, and Editor on widgets. A role on a dashboard gives a matching role on every widget in that dashboard.

Diagram of the Dashboard and Widget resources: Dashboard is parent of Widget, each has three resource roles, and Dashboard Owner and Viewer derive Widget Editor and Viewer

The schema has four parts: resources with their roles, the relation between the resources, role derivations, and permissions.

1. Create the resources and their roles

In the Permit dashboard, open Policy, select the Resources tab, and click Add Resource.

Empty Resources tab in the Permit Policy screen with the Add Resource button
1

Create the Dashboard resource

Enter these details, then click Save:

FieldValue
NameDashboard
Actionsview, remove-widget, add-widget, edit, delete, create
Roles on this resourceOwner, Viewer, Analyst
2

Create the Widget resource

Click Add Resource again, enter these details, then click Save:

FieldValue
NameWidget
Actionsview, edit, delete, create
Roles on this resourceOwner, Viewer, Editor
3

Check the resources list

The Resources tab lists both resources, with their keys and instance roles, such as Dashboard#Analyst and Widget#Editor.

Resources tab listing the Dashboard and Widget resources with their keys and instance roles

2. Define the relation between the resources

A relation connects two resource types. Here, Dashboard is the parent of Widget.

1

Open the resource editor

In the Resources tab, click the three-dot menu of the Dashboard resource and select Edit.

Three-dot menu of the Dashboard resource with the Edit option
2

Add the parent relation

In the Relations section, click Add Relation and set Dashboard is parent of Widget.

Relations section of the resource editor with the relation Dashboard is parent of Widget
3

Save the relation

Click Save. Dashboard is the parent of Widget. You can derive widget roles from dashboard roles.

3. Define role derivations

A role derivation gives a user a role on one resource instance because of the user's role on a related instance.

1

In Policy, select the Roles tab. The tab lists every resource role, such as Dashboard#Owner and Widget#Editor.

Roles tab listing the Dashboard and Widget resource roles with their keys and resource types
2

Add the derivations

Add these two derivations to the Widget resource roles. For the dashboard steps that create a derivation, see Define role derivations.

Derived roleDerived fromMeaning
Widget#EditorDashboard#Owner, where Dashboard is parent of WidgetA user who is Owner of a Dashboard instance becomes Editor of every Widget instance under that dashboard.
Widget#ViewerDashboard#Viewer, where Dashboard is parent of WidgetA user who is Viewer of a Dashboard instance becomes Viewer of every Widget instance under that dashboard.

The first video adds the Dashboard#Owner to Widget#Editor derivation:

The second video adds the Dashboard#Viewer to Widget#Viewer derivation:

3

Save the role derivations

Save the changes. Each derivation shows as a rule, for example Dashboard#Owner to Widget#Editor if Dashboard is parent of Widget.

Derivation rule: Dashboard#Owner derives Widget#Editor if Dashboard is parent of WidgetDerivation rule: Dashboard#Viewer derives Widget#Viewer if Dashboard is parent of Widget

4. Configure permissions

In Policy > Policy Editor, check the actions each resource role can perform, then click Save Changes.

1

Dashboard permissions

RoleActions
Ownerview, create, edit, delete, add-widget, remove-widget
Viewerview
Analystview, add-widget, remove-widget
Policy Editor grid with the Dashboard actions checked for the Dashboard resource roles
2

Widget permissions

RoleActions
Ownerview, create, edit, delete
Viewerview
Editorview, edit
Policy Editor grid with the Widget actions checked for the Widget resource roles

Add the policy data

The schema is complete. Next, add the data the policy evaluates: users, resource instances, a relationship between the instances, and role assignments.

The following diagram shows the two ways a user reaches a widget under this schema. A user can hold a role directly on a widget, or hold a role on the dashboard, in which case the relation and the role derivations carry that role to every widget under the dashboard. The diagram uses example instance names, not the ones you create below.

Diagram of users with roles on a Dashboard instance and on Widget instances related to that dashboard

5. Add data and test the policy

1

Create users

In Directory, click Add user and create two users. Don't give them top-level roles. You assign each user an instance role in the Assign instance roles step below, so that only the instance roles and the derivations decide the checks.

UserKeyEmail
John Smithjohnsmithjohn@smith.com
Anna Smithannasmithanna@smith.com
2

Create resource instances and their relationship

Create a Widget instance, data_consumption, under a Dashboard instance, data.

  1. In Directory, open the Instances tab and click Add Instance.
  2. In Resource Type, select Dashboard.
  3. In Instance Key, enter data.
  4. In Tenant, select Default Tenant.
  5. Under Relationships, click Add Relationship and set Dashboard data is parent of Widget data_consumption.
  6. Click Save.

The Instances tab lists Widget data_consumption and Dashboard data, each with one relationship. Permit creates the data_consumption Widget instance from the relationship.

3

Assign instance roles

Give each user one instance role. John Smith gets a role directly on the widget. Anna Smith gets a role on the dashboard, so the role derivation from step 3 is what gives her access to the widget.

  1. In Directory, open the Users tab, click the three-dot menu of John Smith, and select Edit.
  2. Under Instance Access, click Add Instance Access.
  3. Select Widget, enter the instance data_consumption, and select the role Owner.
  4. Click Save.
  5. Repeat steps 1 to 4 for Anna Smith, this time selecting Dashboard, the instance data, and the role Owner.

John Smith's row shows Widget:data_consumption#Owner under Instance Access, and Anna Smith's row shows Dashboard:data#Owner.

4

Test the policy with a permission check

Call permit.check() with a user key, an action, and the widget instance. The resource object holds the resource type, the instance key, and the tenant. Run these three checks:

const widget = { type: "Widget", key: "data_consumption", tenant: "default" };

// John is Owner of the widget itself
const johnEdit = await permit.check("johnsmith", "edit", widget);
console.log("johnsmith edit:", johnEdit);

// Anna is Owner of the parent dashboard, so the derivation gives her Widget#Editor
const annaEdit = await permit.check("annasmith", "edit", widget);
console.log("annasmith edit:", annaEdit);

// Neither Widget#Owner nor Widget#Editor grants delete to a derived role
const annaDelete = await permit.check("annasmith", "delete", widget);
console.log("annasmith delete:", annaDelete);

The example prints:

johnsmith edit: true
annasmith edit: true
annasmith delete: false

Each decision comes from a different path through the policy:

CheckResultWhy
johnsmith edit on Widget:data_consumptiontrueJohn holds Widget#Owner on the instance, and Widget Owner has edit.
annasmith edit on Widget:data_consumptiontrueAnna holds Dashboard#Owner on data. Dashboard is parent of Widget, so the derivation from step 3 gives her Widget#Editor, which has edit.
annasmith delete on Widget:data_consumptionfalseThe derivation gives Anna Widget#Editor only, and Widget Editor has view and edit, not delete.

The second check is the one that proves the role derivation works. If it returns false, confirm that the Dashboard#Owner to Widget#Editor derivation is saved in step 3, that the data dashboard is the parent of the data_consumption widget in step 5, and that both instances are in the default tenant.

Each decision also appears on the Audit Log screen of the Permit dashboard.