Skip to main content

Modeling Custom Roles

note
Auth0 Fine Grained Authorization (FGA) is the early-stage product we are building at Auth0 to solve fine-grained authorization at scale. Sign up for the Developer Community Preview to try it out, and join our Discord community if you are interested in learning more about our plans.

Please note that at this point in time, it is not considered production-ready and does not come with any SLAs; availability and uptime are not guaranteed. Limitations of Auth0 FGA during the Developer Community Preview can be found here.

In this guide you'll learn how to model custom roles in your system using Auth0 FGA.

For example, a Business-to-Business (B2B) application could allow customers to create their own custom roles on the application to grant their users.

When to use

In many cases, roles would fit in well as relations on an object type, as seen in Modeling Roles and Permissions. In some cases, however, they may not be enough.

Custom roles are useful when:

  • Users of the application are able to create arbitrary sets of roles with different permissions that govern the users' access to objects.
  • It is not known beforehand (at the time of Authorization Model creation) what the application roles are.
  • The team responsible for building the authorization model is different from the teams responsible for defining roles and access to the application.

Before you start

Before you start this guide, make sure you're familiar with some Auth0 FGA Concepts and know how to develop the things listed below.

Initial Model

To start, let's say there is an application with a type called asset-category. Users can have view and/or edit access to assets in that category. Any user who can edit can also view.

We'll start with the following authorization model showing a system with an asset-category type. This type allows users to have view and edit access to it.

type asset-category
relations
define viewer as self or editor
define editor as self

In addition, you'll need to know the following:

Modeling Roles and Permissions

You need to know how to add users to groups and grant groups access to resources. Learn more →

Modeling Object-to-Object Relationships

You need to know how to create relationships between objects and how that might affect a user's relationships to those objects. Learn more →

Concepts & Configuration Language

The Playground

Try this guide out on the Auth0 FGA Playground

Step by Step

Starting with the authorization model mentioned above, we want to enable users to create their own custom roles, and tie permissions to those roles to our two users and to the permissions on the logo asset category.

For this guide, we'll model a scenario where a certain organization using our app has created an asset-category called "logos", and another called "text content".

The company administrator would like to create:

  • a media-manager role that allows users to edit assets in the logos asset category
  • a media-viewer role that allows users to view all assets in the logos asset category
  • a blog-editor role that allows users to edit all assets in the text content asset category
  • a blog-viewer role that allows users to view all assets in the text content asset category

Imagine these are what the permissions the roles in one organization using our service are like:

Image showing custom roles and permissions

Finally, the administrator wants to assign Anne the media-manager role and Beth the media-viewer role.

At the end, we'll verify our model by ensuring the following access check requests return the expected result.

Image showing expected results

In order to do this, we need to:

  1. Update the Authorization Model to add a Role Type
  2. Use Relationship Tuples to tie the Users to the Roles
  3. Use Relationship Tuples to associate Permissions with the Roles
  4. Verify that the Authorization Model works

01. Update the authorization model to add a role type

Because our roles are going to be dynamic and might change frequently, we represent them in a new type instead of as relations on that same type. We'll create new type called role, where users can be related as assignee to it.

The authorization model becomes this:

type asset-category
relations
define viewer as self or editor
define editor as self
type role
relations
define assignee as self

With this change we can add relationship tuples indicating that a certain user is assigned a certain role.

02.Use Relationship Tuples to tie the Users to the Roles

Once we've added the role type, we can assign roles to Anne and Beth. Anne is assigned the "media-manager" role and Beth is assigned the "media-viewer" role. We can do that by adding relationship tuples as follows:

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

await fgaClient.write({
writes: {
tuple_keys: [
// Anne is assigned the media-manager role
{ user: 'anne', relation: 'assignee', object: 'role:media-manager'},
// Beth is assigned the media-viewer role
{ user: 'beth', relation: 'assignee', object: 'role:media-viewer'}
]
}
});

We can verify they are members of said roles by issuing the following check requests:

Image showing expected membership checks

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

// Run a check
const { allowed } = await fgaClient.check({
tuple_key: {
user: 'anne',
relation: 'assignee',
object: 'role:media-manager',
},});

// allowed = true

03. Use Relationship Tuples to associate Permissions with the Roles

With our users and roles set up, we still need to tie members of a certain role to it's corresponding permission(s).

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

await fgaClient.write({
writes: {
tuple_keys: [
// Users assigned the media-manager role can edit in the Logos assets category
{ user: 'role:media-manager#assignee', relation: 'editor', object: 'asset-category:logos'},
// Users assigned the media-viewer role can view from the Logos assets category
{ user: 'role:media-viewer#assignee', relation: 'viewer', object: 'asset-category:logos'}
]
}
});

04. Verify that the Authorization Model works

To ensure our model works, it needs to match our expectations:

Image showing expected results

Initialize the SDK
// FGA_ENVIRONMENT can be "us" (default if not set) for Developer Community Preview or "playground" for the Playground API
// import the SDK
const { Auth0FgaApi } = require('@auth0/fga');

// Initialize the SDK
const fgaClient = new Auth0FgaApi({
environment: process.env.FGA_ENVIRONMENT,
storeId: process.env.FGA_STORE_ID,
clientId: process.env.FGA_CLIENT_ID,
clientSecret: process.env.FGA_CLIENT_SECRET,
});

// Run a check
const { allowed } = await fgaClient.check({
tuple_key: {
user: 'anne',
relation: 'editor',
object: 'asset-category:logos',
},});

// allowed = true

The checks come back as we expect, so our model is working correctly.

Modeling Roles and Permissions

Learn how to remove the direct relationship to indicate nonassignable permissions.

Modeling Concepts: Object to Object Relationships

Learn about how to model object to object relationships in Auth0 FGA.

Custom Roles Sample

Explore the Custom Roles sample on the Auth0 FGA Playground.

Have Feedback?

Join us on the Discord community if you have any questions or suggestions.