Outsourcing authorization is generally an overlooked concept when comparing outsourcing of other key pieces of any Saas app such as authentication, payment gateway etc.
In the early stages of product development most of the developers build simple solutions for authorization.
These simple authorization mechanisms probably with a couple of predefined roles and a simple permission table generally covers the minimum requirements at start.
It's easy to whip up the first use case - adding a roles table to your database works for a while.
However, products will eventually change, and further development needs to be done on bare minimum authorization systems because of different user needs and access management requirements.
When complex authorization systems are needed, the status quo is building it from starch with high development efforts and broken approaches which is super inefficient for your business.
I don't want to dive deep on this inefficiency topic because it's beyond our scope. However, If you are wondering more, you can check my article on why you need to outsource authorization.
Actually outsourcing authorization is super simple and you will get tons of benefits from it.
In this article, I'll show you how to set up a complex and future proof authorization mechanism to your NodeJS applications in minutes using Permify.
Friendly reminder, this is the continuation part of the article Token-Based Authentication system in Node using PassportJs, Express, and MongoDB. So we will integrate Permify to the demo app which we created in that article.
Source Code of full implementation: https://github.com/Permify/node-auth-boilerplate
Create Permify Client
We first need to install permify node package to our NodeJs app with the following command:
We need to create a Permify client using our Workspace ID and API private key which is provided in the Permify Panel.
If you don't have Workspace ID and API private key that means you don't have an account yet, you can create your free account at Permify. I will use a test account in this tutorial.
If you have workspace and corresponding API keys, let's create a file called permify.js in our root folder and add the following code to create a Permify Client instance. We will use this client to reach out to all Permify functions.
After installing and setting up Permify to our application, let's create our authorization model with it in 3 easy steps. Respectively:
- Create Group
- Integrate/Create Users
- Create Policy
Create a group
We need to have at least one group entity which is part of our workspace.
Groups are unique organizations/clients that use your apps. Groups consist of a party of users.
For instance; Acme Corp is using your project management app, and has 5 users. Acme Corp. is a group and users are nested under that group.
If your application is not multi-tenant, as in this demo application, you can create a group from Permify Panel.
If you're not following the demo app and your application is multi-tenant, add the below code to your app's tenants creation flow. The id field should be the same as the Id of each group/tenant in your system.
In order to perform access checks we need to create or integrate users of our app in Permify.
You can create users in Permify without sharing all user data. Permify just needs a unique user id for matching users. However, you can support more information like name or photo to arrange access rules, roles on the Permify Panel manually.
The simplest way of adding existing users to Permify is add Permify createUser() function to your login flow. In our demo app we have simple users/login endpoint, update that endpoint with following code;
As you notice, other than matching users with id. We also:
- Give id of the group we just created above. Each user should be part of at least one group.
- Add user's role names and attributes to use them in rule creation. These are optional fields. However, It's easier to give them when creating user.Also you can always add roles and attributes to a user from the Permify Panel or with API calls.
Also let's add Permify Create User to our app's register flows to collect newcomers. So update the /signup endpoint;
Permify Policies consist of different options and rules that determine who can do action on a particular resource or event and under what conditions.
The policy returns you a decision as to whether the user is authorized for that action as a result of these options, rule definitions, and the inputs you provide.
In order to create a policy we need to create rules and options.
In our demo app I will create a policy called “user-index” to check access to get user list action. We need to specificity options for that access, let's say only
- Users who has manager role or admin role
- Users who worked more than 8 years in this company can perform this action.
So let's create our policy according to these rules.
Rules are the functions which you can compare user roles, user attributes, and resource attributes.
You can create rules with two property:
- Name of the rule.
- Condition, a simple comparison statement.
In our example we want to create a “user-index” policy with 2 option statements, which breaks down to 3 rules as follows:
(Note: If you prefer you can directly create these rules from Permify Panel Rules Section with a simple UI)
Users who has manager role
Users who has admin role
Users who worked more than 8 years in this company. Let's assume if the user worked more than 8 years he/she is considered a senior. We can use our users tenure attribute for that:
Options allow you to establish 'or' relationship between rules and create a more organized and legible authorization structure at policies.
Let's created a options with rules which we defined previously:
(Note: Also you can directly create these options from Permify Panel Options Section)
Users who has manager role or admin role
Users who worked more than 8 years in this company
Finally, we need to define our option to create our policy as follows.
(Note: You can directly create this policyfrom Permify Panel Policies Section)
Note: I try to keep things simple for demonstration purposes, you can define more complex attribute based conditions with Permify, for more details check out Permify Policies
Now we can use the user-index policy to perform access check in anywhere, both server side and/or client side to protect our resources.
Let's use it in the users/ endpoint which returns users list. Since we have a verify user middleware which cheks authentication we can implement authroiation check to in our JWT strategy.
For this acces check we can use isAuthorized() function with following code:
That's how you can set up authorization and perform access checks with Permify.
Moreover, Permify is a full stack solution which also covers frontend, you can use our libraries to implement and check access on your client app.
If you have any questions or doubts, feel free to ask them.
For more content like this, join our newsletter. Get best practices on Authentication, Authorization and Subscriptions to build ultimate B2B SaaS apps.