Relationship Based Access Control (ReBAC)
Permify was designed and structured as a true Relationship Based Access Control(ReBAC) solution, so besides roles and attributes Permify also supports indirect permission granting through relationships.
Here are some common use cases where you can benefit from using ReBAC models in your Permify Schema.
Protecting Organizational-Wide Resources
This example demonstrates grouping the users by organization and giving them access to organizational-wide resources.
In this use case we’ll follow a simplified version of Github’s access control that shows how to model basic repository push, read and delete permissions with our authorization language DSL, Permify Schema.
Before we get started, here’s the final schema that we will create in this tutorial.
entity user {}
entity organization {
// organizational roles
relation admin @user
relation member @user
}
entity repository {
// represents repositories parent organization
relation parent @organization
// represents user of this repository
relation owner @user
// permissions
action push = owner
action read = owner and (parent.admin or parent.member)
action delete = parent.admin or owner
}
Schema Deconstruction
Entities
This schema consists of 3 entities,
user
, represents users. This entity is empty because it’s only responsible for referencing users.
entity user {}
-
organization
, represents organization that user and repositories belongs. -
repository
, represents a repository in a github.
Relations
To define a relation, relations need to be created as entity attributes.
organization entity
In our schema we defined 2 relations in the organization entity: admin
and member
.
entity organization {
relation admin @user
relation member @user
}
admin
indicates that the user got an administrative role in that organization and with the same logic member
represents a default user that belongs to that organization.
repository entity
Repository entities have 2 relations: parent
and owner
. Both of these relations represent actual database relations with other entities rather than a role-based approach similar to the organization entity above.
entity repository {
relation parent @organization
relation owner @user
}
The parent
relation represents the parent organization of a repository. And owner
represents the specific user, the repository’s owner.
Actions
Actions describe what relations, or relation’s relation, can do. You can think of actions as entities’ permissions. Actions define who can perform a specific action and in which circumstances.
Permify Schema supports and, or, and not and or not operators to define actions.
repository actions
In our schema, we examined one of the main functionalities user can make on any GitHub repository. These are pushing to the repo, reading & viewing the repo, and deleting that repo.
We can say only,
- Repository owners can
push
to that repo. - Repository owners, who have an admin or member role of the parent organization, can
read
. - Repository owners or admins of the parent organization can
delete
the repository.
entity repository {
action push = owner
action read = owner and (parent.admin or parent.member)
action delete = parent.admin or owner
}
Since parent
represents the parent organization of a repository. It can reach repositories parent organization relations with comma. So,
-
parent.admin
indicates admin role on organization -
parent.member
indicates member of that organization.
Sample Relational Tuples
organization:2#admin@user:daniel
organization:54#member@user:ege
organization:12#member@user:jack
repository:34#parent@organization:54
repository:68#owner@user:12
repository:12#owner@user:46
…
For more details about how relational tuples are created and stored in your preferred database, see Relational Tuples.
For instance, you can define that a user has certain permissions because of their relation to other entities.
An example of this would be granting a manager the same permissions as their subordinates, or giving a user access to a resource because they belong to a certain group. This is facilitated by our relationship-based access control, which allows the definition of complex permission structures based on the relationships between users, roles, and resources.
Deeply Nested Hierarchies
This use case shows solving deeply nested hierarchies with the Permify Schema.
We have a unique action usage for nested hierarchies, where parent and child entities can share permissions between them. Let’s follow the below team project authorization model to examine this case.
Before we get started, here’s the final schema that we will create in this tutorial.
entity user {}
entity organization {
// organization user types
relation admin @user
}
entity team {
//refers to the organization that a team belongs to
relation org @organization
// Only the organization administrator can edit
action edit = org.admin
}
entity project {
//refers to the team that a project belongs to
relation team @team
// This action is responsible for nested permission inheritance
// team.edit refers to the edit action on the team entity which we defined above
// This means that the organization admin, who can edit the team
// can also edit the project related to the team.
action edit = team.edit
}
Sample Relational Tuples
organization:1#admin@user:1
team:1#org@organization:1#…
project:1#team@team:1#…
Lets assume we created the above tuples. If we try to enforce Can user:1 edit project:1?
we will get Allow since the user:1
is an admin of the organization:1
and project:1
belongs to team:1
, which belongs to organization:1
.
Let’s break down this case,
entity project {
relation team @team
action edit = team.edit
}
In the above team.edit
points to the edit action in the team (that the project belongs to). That edit action on the team entity (action edit = org.admin
) states that only admins of the organization (which that team belongs to) can edit. So our project inherits that action and conducts a result accordingly.
If we go back to our question: Can user:1 edit project:1?
this will give an Allow result, because user:1 is an admin in an organization that the projects’ parent team belongs to.
User Groups & Team Permissions
This use case shows how to organize permissions based on groupings of users or resources. In this use case we’ll follow a simple project management app with our authorization language, Permify Schema.
Before we get started, here’s the final schema that we will create in this tutorial.
entity user {}
entity organization {
//organizational roles
relation admin @user
relation member @user
}
entity team {
// represents owner or creator of the team
relation owner @user
// represents direct member of the team
relation member @user
// represents the organization that the team belongs to
relation org @organization
// organization admins or team owners can edit, delete the team details
action edit = org.admin or owner
action delete = org.admin or owner
// to invite someone you need to be an organization admin and either an owner or member of this team
action invite = org.admin and (owner or member)
// only team owners can remove users
action remove_user = owner
}
entity project {
// represents team and organization that a project belongs to
relation team @team
relation org @organization
action view = org.admin or team.member
action edit = org.admin or team.member
action delete = team.member
}
Schema Deconstruction
Entities
This schema consists of 4 entities,
user
, represents users. This entity is empty because its only responsible for referencing users.
entity user {}
-
organization
, represents an organization that contain teams. -
team
, represents teams, which belong to an organization. -
project
, represents projects that belong to teams.
Relations
organization entity
We can use relations to define roles.
The organization entity has 2 relations admin
and member
users. Think of these as organizational-wide roles.
entity organization {
relation admin @user
relation member @user
}
Roles (relations) can be scoped with different kinds of entities. But for simplicity, we follow a multi-tenancy approach, which demonstrates that each organization has its own roles.
team entity
The team entity has its own relations respectively, owner
, member
and org
entity team {
relation owner @user
relation member @user
relation org @organization
}
project entity
The project entity has team
and org
relations. Both these relations represent parent relationships with other entities, parent team and parent organization.
entity project {
relation team @team
relation org @organization
}
Actions
Actions describe what relations, or relation’s relation, can do. You can think of actions as entities’ permissions. Actions define who can perform a specific action and in which circumstances.
Permify Schema supports and, or and not operators to define actions.
team actions
-
Only organization admin (admin role) and team owner can edit and delete team specific resources.
-
Moreover, to invite a colleague to a team you must have an organizational admin role and either be a owner or member of that team.
-
To remove users in team you must be an owner of that team.
And these rules are defined in Permify Schema as:
entity team {
action edit = org.admin or owner
action delete = org.admin or owner
action invite = org.admin and (owner or member)
action remove_user = owner
}
project actions
And here are the project actions. The actions consist of checking access for basic operations such as viewing, editing, or deleting project resources.
entity project {
action view = org.admin or team.member
action edit = org.admin or team.member
action delete = team.member
}
Sample Relational Tuples
team:2#member@user:daniel
team:54#owner@user:daniel
organization:12#admin@user:jack
organization:51#member@user:jack
organization:41#member@team:42#member
project:35#team@team:34#…
… . .
organization:41#member@team:42#member
—> represents members of team 42 are also members of organization 41
project:35#team@team:34#…
—> represents project 54 is in team 34
Need any help on Authorization ?
Our team is happy to help you get started with Permify. If you’d like to learn more about using Permify in your app or have any questions about this example, schedule a call with one of our Permify engineers. Alternatively you can join our discord community to discuss.