Permission Systems that Scale

What is Role-Based Access Control?

Permission Systems that Scale

Lesson Description

The "What is Role-Based Access Control?" Lesson is part of the full, Permission Systems that Scale course featured in this preview video. Here's what you'd learn in this lesson:

Kyle introduces the concept of role-based access control, explaining how each user is assigned roles with specific permissions. He discusses the benefits of centralizing permission logic and demonstrates how to implement a simple role-based access control system using TypeScript. Kyle then instructs the students to create a new file for handling permissions, guiding them through defining different permissions for projects and documents within the system.

Preview

Transcript from the "What is Role-Based Access Control?" Lesson

[00:00:00]
>> Kyle Cook: So hopefully you have the same exact code that I do, and really before we dive into really making this code much cleaner, I want to talk about overall just the problems with this code. We've touched on it a little bit. The biggest thing is the duplication. We have the same if checks in our service layer, we have them inside of our UI, we have them inside of our pages. They're kind of sprinkled throughout our entire application, which makes it difficult to actually change something because it's everywhere.

[00:00:23]
We also don't quite have a single source of truth. Our services layer helps by adding a single source of truth, but we still have our page components and our UI that are conditionally rendering things based on these different checks. Also, most of this permission logic is quite difficult to read, especially the permission logic dealing with who can view a project or not. It's like a 4 or 5 line if statement that unless you really know what's going on, it can be easy to either write it incorrectly or you just read it incorrectly.

[00:00:49]
So having much easier to read permission logic is going to be one of the biggest things we're going to focus on going forward. Also, changing or adding any new permission is a pain because we not only need to update our service layer, we need to update all of the different pages that use this, we need to update our UI where this is used. We essentially need to update all of our application every time we either change or add or even remove a permission from our application.

[00:01:10]
So what we really want to focus on is we want to make it so that it's easier to do all of those different modifications, and that's where role-based access control comes in. Now the whole idea behind role-based access control, you've probably, like I said, used this in the past before, is that every single user is going to have a role or multiple roles assigned to them. It'll work the exact same either way, and each role has a set of permissions that that role can do.

[00:01:34]
So if we kind of take a look at a visualization of this, you can see we have a user that has a role, and that role grants different permissions. So for example, the admin role has the ability to create documents, create projects, and so on, while a viewer role has none of those additional create permissions associated with it. And these permissions are usually written in a way where you have a resource and an action.

[00:01:56]
So here I have the resource document and I have the action create. Sometimes you'll see it flipped the other way where it goes action first and then resource or say create colon document. I just have it written document colon create. It's entirely up to you which way you like to do that though. Now the reason that a role-based access control system works really well is because now we can centralize all of our permission logic.

[00:02:17]
We're never going to check a user's role directly. Instead, we're going to be checking, do they have these permissions, and those permissions are going to be granted to them by their role, and they could have one role, they could have many roles, it doesn't matter. Even a user with no roles, for example, a logged out user, could be handled by this system. We can call one single function to determine if they have permission to do something, and now instead of something being tied to their role, it's tied to a permission.

[00:02:42]
Also, we have one single location where we're going to be changing all of our code. We're going to write all of our code for role-based access control in a single file, and if we want to update what user has permission to do certain things based on their roles, we can change it in one file, and that'll propagate to all the rest of our application. It also just leads to cleaner code. For example, right now, we have these if checks that are hard to read, especially as they grow in complexity.

[00:03:03]
What our code is going to look like going forward is we're going to have a single function called can, where we pass in a user, and we pass in a permission, and it just returns true or false, based on if they have that permission or not, and that permission can be derived from many things. But since we're focusing on role-based access control, it's going to be derived from the role that's assigned to that user.

[00:03:22]
Also, we will hopefully have much less bugs going forward in our code, because it's easier to update and maintain since it's all in one place, so we have less likelihood of introducing bugs into our code. Now here is going to be kind of a simple example of what role-based access control will look like, then we're going to implement it into our system. But since we're using TypeScript, we essentially create a type that is going to act as an enum.

[00:03:41]
So if you're using another language, you'd probably use an enum here, and it's just a list of all the permissions that our application has. Since we only have create, read and update for projects and documents, you can see we wrote out create, read and update for our documents and our projects. Then we essentially create a map. This is just a dictionary lookup or a map, however you want to call it.

[00:04:00]
In our case it's a single JavaScript object that the keys are each one of the roles that we have. In our case it's just listing three of them, and then it's going to be an array of all the permissions associated with that role. And the nice thing about this is that the can function we write is now dead simple to write. It's a single line of code. All it is is essentially a lookup table. We look up, does this role have the permission inside of this array?

[00:04:22]
If so, return true, if not, return false. And if you wanted users to have multiple roles assigned to them, this lookup would essentially just loop through every role the user has and check, do at least one of the roles the user has, has access to this particular permission. So just add a few extra lines of code to this can function. And the nice thing is now it's really easy for us to write our if statements because we just call that can function, pass it in the user we're checking for, and then we can check whatever permission we want.

[00:04:48]
And if we want to add or change or remove permissions, all of it happens in this one single file for us. So let's go ahead and actually work on implementing out what that might look like inside of our code. So let's create a brand new file for handling this. We'll call this RBAC. We'll put it in a brand new folder. So inside of here, we'll create a new folder. Call it permissions, and then inside that permissions folder, we can just create a brand new file called RBAC.ts since this will be a TypeScript file.

[00:05:15]
Now, as I mentioned, we're going to need a type that contains all of our permissions. If you're using a language that has enum support that works better, you could use an enum here as well. It's entirely up to you. And again, we're just going to write out our permissions, so we have project create, and then we need to come in here and we're going to have project update, and let's just copy this down a bunch of times because we're going to have a ton of different permissions, so we have create, we have update, we have read.

[00:05:44]
We have delete, and then we need to do the exact same thing for documents, so we have create, read, update, and delete. These are the four different permissions that we're trying to check for each one of our different resources that we're dealing with.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now