Permit logo
Home/Blog/

How to Add RBAC Authorization to Auth0

Learn how to add RBAC Authorization to your Auth0 application with Permit.io. Implement authz with low code and ensure only the right users have access.
How to Add RBAC Authorization to Auth0
Gabriel L. Manor

Gabriel L. Manor

|
  • Share:

Authentication SaaS is everywhere

The authentication and identity management world has changed dramatically over the last decade. As applications migrate to authentication-as-a-service providers such as Auth0, internal databases, and password hashes become a thing of the past. With these solutions, you can easily implement authentication into your app while taking advantage of great features such as federated identity, social logins, MFA, identity verification, and more. For a modern web application that needs to verify who its users are, you don’t need anything but to open an Auth0 account. After a short configuration setup, you can integrate a rich authentication feature set into your application with single lines of code.

Authentication alone is not enough

One of the access control challenges with Auth0 is the authorization phase. While Auth0 excels in verifying who the users are, they are limited in telling you what they can do. Having any authenticated user be able to perform any action poses great risks, as we recently saw in the Bing hack incident.

Authorization is a critical phase in monitoring user access and making sure only the right people have the right access to the right resources within your application.

The solution? Authentication SaaS + Authorization SaaS 

Permit.io is a cloud service that provides a low-code tool for implementing and managing authorization. By configuring identities, resources, and actions, you can create policies and enforce them in your application. Basically the same concept as Auth0, but for authorization.

Combining the two services gives your application a complete cycle of access control and helps you ensure your authenticated users can do only what they should be allowed to.

In this article, we will review the steps of implementing Auth0 together with Permit.io.

Using the Auth0 getting started guide for Next.JS, we will demonstrate how you can completely redefine the permission model of our application with nothing but a few lines of code - Limiting your Auth0 authenticated users to only perform the actions they are allowed within your app.

By the end of this article, you should have a solid understanding of how Permit.io can be implemented into your app in your favorite coding language using any of our SDKs.

Before we begin, let’s dive a little deeper into how these two solutions work together.

Authentication vs. Authorization - Auth0 vs. Permit.io

In an application that uses Auth0 for authentication, the authentication process is typically handled client side. This means that when a user attempts to access a protected resource, such as a restricted page or API endpoint, the client-side code sends a request to Auth0 to authenticate the user. Auth0 then returns a token that the client-side code can use to authenticate subsequent requests to the server.

pasted image 0.png

Authorization, on the other hand, is typically performed server-side. This is because authorization involves enforcing access policies specific to the application and its resources. In order to enforce these policies, the server-side code needs access to the user's identity, which is typically included in the authentication token.

When using Permit.io, the authentication process remains unchanged. However, when a user attempts to access a protected resource, the server-side code sends a request to Permit.io, which checks whether the user is authorized to perform the requested action.

pasted image 0.png

Permit.io uses the identity information provided by Auth0 to determine the user's permissions and enforce access policies. This means that the application can easily define fine-grained access controls based on user roles, permissions, and other attributes and enforce those controls in a central location.

Demo Application

To demonstrate the relationship between authentication and authorization, we created a simple  to-do application, with authentication already implemented into it based on the Auth0 Next.JS getting started guide. Let’s clone it and run it on your local environment.

Note: while this article does not require you to have Next.JS knowledge, it requires an Auth0 account with a basic configuration, and Node.JS installed in your local or remote environment.

  1. Open the terminal and type the following command in your desired development folder

    npx create-next-app@latest permit-auth0-todo --use-npm --example https://github.com/permitio/permit-next-todo-starter auth0-tutorial && cd permit-auth0-todo
  2. Paste your Auth0 keys in the .env.local file as listed below. To get your own keys in the desired format, use this link while logged in to your Auth0 account

    AUTH0_SECRET='<auth0_secret>'
    AUTH0_BASE_URL='http://localhost:3000'
    AUTH0_ISSUER_BASE_URL='<auth0_issuer_base_url>'
    AUTH0_CLIENT_ID=<auth0_client_id>
    AUTH0_CLIENT_SECRET='<auth0_client_secret>'
  3. Run the following command from the application folder

    npm run dev
  4. In your browser, go to localhost:3000, log in with one of your Auth0 users, and see the tasks list on the screen.

We now have an app with basic authentication rules set up and running. Now, let’s see how we can add a granular authorization layer into this app using Permit. 

Building Permissions - Roles and Attributes

The first step when building authorization is designing your permission model. 

The basic building blocks of every permission model are IdentityResource, and Action. The relationship between these three elements defines access control policies (Identity can perform Action on a Resource).

Identity

The basic identities in our application are those provided by the Auth0 Authentication process. To create a permission model, we would need to translate those identities into roles (which will allow us to implement Role Based access control) or add attributes onto them (for Attribute Based access control).

Resource

As our application is quite simple, we have only one resource we want to manage access to - the tasks. Similar to identities, resources also have attributes that identify them. For example, tasks have an isCompleted attribute that identifies it as a completed task or an owner attribute that belongs to a particular user who created it.

Action

This part of the policy is the glue between the Identity and the resource. By understanding what actions identities can perform on resources, we can enforce our access control policies and decide who can do what on which resource within the app. 

The full picture 

We can describe the relationships between our identities, resources, and actions by putting them all on a table. By creating a separate table for each role, we can see exactly which actions this role can perform on our resource. 

Here is an example of the permission model where Editor that can create tasks but not delete them while Moderator is not able to create tasks but can update them:

Admin

Action 👉

Resource 👇

Post

Put

Patch

Delete

Get

Task

V

V

V

V

V

Editor

Task

V

V

Moderator

Task

V

V

Roles…

Building Permissions

Now that we clearly know how our permissions should look, it’s time to log in to app.permit.io and create it.

  1. Go to the Policy page and click  Create > Resource

  2. Create a Resource, and assign it with Actions:

    Frame 68089.png

Next, we will create our Roles:

  1. Go to the Policy page and click Create > Role

  2. Add the following roles

    Frame 68088 (1).png

To make things easier, make sure to mirror the roles you have set up in Auth0. In your production application, you can think of the right way of maintaining one source of truth for roles in the application. 

In the Auth0 admin application, go to User Management > Roles and add the following.

pasted image 0.png

For each role, we would like to add a user assigned to this role. In Auth0, go to User Management > Users and add the following. Pay attention that you assigned the relevant role to each user.

pasted image 0.png

With the roles, resources, and actions you just created, we have an outline of the policy table configuration. Let’s go back to Permit.io policy editor screen and check the following boxes to adopt the policy for our needs.

Auth0 Policy Editor Screenshot.png

Manage Identities - Sync Users

Having defined permissions in Permit.io, it is time to connect the dots between our authentication and authorization services and make Permit.io aware of our application users and roles managed by Auth0.

Auth0 provides the option to write actions that run as a result of user actions. We will use the post-login action to sync the users to Permit.io. This way, we can ensure every user login to our applications is updated with their roles in Permit.io. You can read more about actions here.

Follow the following steps to enable sync users action in your Auth0 account:

  1. In the Permit.io application, go to Project and copy the API key.

    saveAPI.png
  2. In your Auth0 account, go to Actions > Library, click the + Build Action button, and create the following action.

    pasted image 0.png
  3. In the online IDE opened, click the key icon on the left side, and paste your copied Permit SDK key.

    pasted image 0.png
  4. In the same left bar, click the package icon to install permitio sdk in Auth0

    pasted image 0.png
  5. Paste the following code that will sync users while they are login to the application.

    const { Permit } = require('permitio');
    
    exports.onExecutePostLogin = async (event, api) => {
        const permit = new Permit({
            pdp: 'https://cloudpdp.api.permit.io',
            token: event.secrets.permit,
        });
        const { email, given_name: first_name, family_name: last_name } = event.user;
        const user = await permit.api.syncUser({
            key: email,
            email,
            first_name,
            last_name,
            attributes: {},
        });
    
        for (let role of event.authorization.roles) {
            await permit.api.assignRole({ role, tenant: "default", user: email });
        }
    };
  6. Click on the Deploy button, and we're done. All the users will sync to Permit.io after they log in.

To test the user synchronization to Permit.io, go back to the browser and log out/log in with one of your users. Then, go to the Permit.io Users screen and see the new user appear at the table with the relevant role.

Sync Troubleshooting

If your users are not syncing between Auth0 and Permit.io at this point, no worries this can be tricky 😉, here are some suggestions to help you debug the sync functionality:

  1. Test the sync action in the Auth0 UI and verify that it successfully syncs users to Permit.io. Ensure that all the attributes in the API call exists and valid in Permit.io.
  2. Confirm that the Login/Post Login action is being called as a callback after login. You can check this by auditing the API logs in Permit.io under Settings > API Logs.
  3. If the previous steps do not resolve the issue, you can explore additional methods to synchronize users to Permit.io for more advanced use cases.

Enforce Permissions in the Application

At this point, we have everything configured in both Auth0 and Permit.io. The only thing left is adding enforcement points to our APIs. As we explained before, the enforcement will occur at the API route where we want to allow or deny a particular user to perform an action.

  1. Grab the SDK key again and paste it into the .env.local file in the following format.

    PERMIT_SDK_TOKEN=<permit_sdk_token>
  2. Run the following command from the terminal to install the Permit.io SDK into the project.

    ⁠npm i permitio –save
  3. In the tasks.ts file, paste the following code just below the import.

    import { Permit } from 'permitio';
    
    const permit = new Permit({
      pdp: 'https://cloudpdp.api.permit.io',
      token: process.env.PERMIT_SDK_TOKEN,
    });
  4. Find the beginning of the handler and paste the following code. This code takes the identity that Auth0 provides and sends it to Permit.io to verify if the user is allowed to perform the operation.

    const isAllowedForOperation = await permit.check(
        session?.user?.email as string || '',
        req.method?.toLowerCase() as string,
        'Task'
    );
  5. At this point, we are only left to return an error if the user is not allowed.

    if (!isAllowedForOperation) {
        res.status(403).json({ message: 'forbidden' });
        return;
    }

After implementation, let’s go back to your application in the browser and see it in action. Go to the browser, log out with the current user, and log in with a different role user to see how the application responds differently to operations by user roles.

What Next?

Congratulations, you successfully implemented a fully functional permission model to an application and created fine-grained access control that enforces policies on what users can do. 

As you saw in this post, Permit.io gives you a full-stack authorization management solution, so you don’t have to build one yourself. Permit.io provides SDKs for many programming languages, so you can investigate them and find the relevant solution for your particular application.

Permissions and authorization are essential to success in access control. Still, the model we created here is just the beginning of a good permissions model you can implement in the application. For example, what if you want to differentiate the same resource types by their attributes? What if you want a more granular level of control than user roles but user-detailed identity? For that and more, we recommend you to continue reading our learning materials, such as the difference between RBAC and ABACadding ABAC to your application with Permit, and more.

Written by

Gabriel L. Manor

Gabriel L. Manor

Full-Stack Software Technical Leader | Security, JavaScript, DevRel, OPA | Writer and Public Speaker

Test in minutes, go to prod in days.

Get Started Now

Join our Community

2026 Members

Get support from our experts, Learn from fellow devs

Join Permit's Slack