Introduction to Roles and Permissions Use Cases
Hi. Bryant here for Directus and in this video, we’re going to dive even deeper down the rabbit hole and show you how to recreate some of the most common use cases for the powerful roles and permissions feature inside Directus.
If you’re not already familiar with the basics of roles and permissions work, then I’d recommend you check out our overview video first and then coming back.
We're going to cover four use cases. The first is the public role, what data is available to the general public from your API. The second is going to be to create a website user so that your server can communicate with Directus. Number three is going to be restricting access to data based on certain types of users. And number four is a doozy, how to create tenancy inside Directus.
Configuring the Public Role
With that, let's set up the first use case, setting up the public role. The public role controls what API information is available without authentication. So anybody in the public, any random person, can access this data. And for that reason, you want to be pretty strict about what you allow. So, in this case, we're only going to allow the articles collection inside our instance to be available to the public. So I will just go in and click all access under the read permission, and I am going to test this out by opening up another tab, dropping my URL in there, and adding /items/articles.
Now I can also see that we've got all our articles here, but maybe I don't want to show the draft articles to our users. So, I am going to go in, and under the read permission, I am going to give this a custom permission. In the items permission section, I am going to add a filter for the status. So I only want to show articles where the status is equal to publish. I'll save that and let's test this out one more time. As you can see now, we are only getting articles that are published.
But I could also take this one step further and say I don't want to show the status, or maybe I don't want to show the ID field or some other sensitive data. I'll go back to our permissions and go to the field permissions section. And here is where I can control what fields the public role can actually view. So we've set the items that they can view but now we are going to set the fields that they have access to. I'll just refresh the page, and you can see those hidden fields no longer display in the API response.
So that's a really simple use case for setting up a public role. You may have other collections that you want to enable but I would highly advise you against giving create, update or delete access to the public role. Be very careful.
Creating a Secure Website User
Let's cover our next use case, creating a website user. Maybe you have a contact form or a demo request form on your website and you want to push that data inside your Directus instance. Maybe to an inbox collection or some other collection that you've got. We don't want anyone in the general public to be able to submit this data, it's a good way to open yourself up for attack.
So instead, we are going to create a new role for this. So we'll just click the create role button and give this a name, maybe "website". I will disable access for this particular role and then I will go in and set the permissions that I want our website front end to be able to access. In this case, I am just going to enable the create access for the inbox collection. So now we've created the user role, we need to actually create our website user.
So I'll hop over to the user directory and create a new user for the website role. I am not going to fill out email or password, I am going to hop right down to the token section and generate a new static access token. Make sure you copy this and keep it in a safe place because you won't be able to see it again. And typically, this is going to go into your .env file and if you're using the Directus SDK, your setup might look something like this. Where you've got the static token that you're passing to the auth object when creating a new instance of the SDK.
And that's it, now you have direct server-to-server connection with your Directus API.
Restricting Data Access by User Role
Alright, let's jump into our next use case, which is restricting data access based on the type of user, or the user role. Maybe I have several employees that I want to assign tasks to but I don't want them to see anyone else's tasks. So I can jump into our staff role in this case, I'll scroll down to our task collection and let's update some permissions.
I still want these users to create tasks for themselves so I am going to give All Access to the create operation. And on the other operations, I am going to use custom permissions. So I'll open up the read operation and click use custom. In here under item permissions, we're going to create a rule using a dynamic variable. So I am going to go to the assign_to field and I am going to key in $CURRENT_USER.id. Now they will only be able to see tasks that they've been assigned to.
But there's a problem because what happens if they create a task. I still want them to be able to see that. I can solve that by using the OR filter group and creating another rule for the user_created field. So I will do the same variable, $CURRENT_USER.id, and I'll put those in the or group, and now, this specific user will only see tasks that they've been assigned to or tasks that they've created. And don't forget to update the field permissions to let this user see all the fields with the tasks.
Now we will jump into update operation and apply the same rules. So under item permission, I will set the same thing up. And now that that's done, I am going to hop into field permissions and make sure I update the fields that they can update. Simple enough. So we will save this operation and for the delete tasks, I am not going to let them delete tasks so I will just leave that blank.
But now I can log in as this specific user and test it out. So as you can see, this user only has two tasks out of hundreds that are in that collection that show up when they log in. And if I switch back and forth, I can easily see the difference. Now we'll switch back, and I will go ahead and create a task just to go ahead and check that as well. I'll add some sample test data here and save it just to make sure this is working, but as you can see, everything checks out ok.
And that's it for restricting user data based on a role.
How to Set Up Multi-Tenancy in Directus
Alright, the last use case is creating tenancy. So how do we set up multi-tenants in a single Directus instance? I am starting with a blank slate here, we're going to create a new collection for our tenants. You can call this tenants, I really like accounts as the terminology. I'll use the generated UUID type, and I am going to add some optional systems here. For this accounts collection, I am going to give it a name and make that required so they have to fill it out. And I am also going to add a slug, just to give another type of identifier. Maybe I want to expose that on the front end and I will make sure that's a unique value. I am going to hop to the interface tab and make sure I check the slugify box to make sure this is input correctly.
So that's it for our tenant collection. The next collection we are going to create is going to be the task collection. We'll just stick to the same theme, we'll use the generated UUID field again and add some optional system fields. The most important part about this tasks collection is creating a many-to-one relation to that tenant collection, which is called accounts. So I'll do a key called accounts and the related collection is going to be accounts and for the display template, I'll simply do the name. I'll save this and let's go in and add some task data like a title and we will keep this really simple, maybe just a toggle for completed and save.
Alright, so the last step of this process is to go into our system collection to Directus users and we're going to add that many-to-one relation for accounts to the user as well. So each user belongs to an account. We will choose the accounts as the related collection and set the name as the display template. Perfect.
So, now we've got the data model set up, we're going to hop into the roles and set up a new role for these front-end users. If you are doing a SaaS app, you may want to turn off app access. But I'm going to leave this on just to showcase this functionality to you guys. I'll hit save and now we'll go in and start editing our permission. So first, we are going to work on the accounts collection. I'll go to the read operation and am going to leave all these field operations available, but when it comes to the field presets, I want to pre-populate that user account. So I am just going to use some JSON here and I am going to use that dynamic user variable to populate that data for a new task. Now I will open up the read operation and under item permissions, we're going to go in and add some rules here. So I am looking for the account field and the rule is going to be equals to $current_user.account. So that will prevent any user from seeing tasks that are not in their account. We will do that for the update operation as well as the delete operation. Perfect.
Alright, so now we've got accounts and tasks set up, let's go in and create an account and test this out. So we'll give it a name, give a slug "test tenant", let's save this specific account and then we can go in and create a couple sample users. So we'll do a test tenant user, give them a login and a password, hey that's great. We will make sure we will select the account that they are a part of, save this user. And then we log in to test out our work.
And walla! Now we have set up tenancy inside our Directus instance and this is going to work with the API as well as the app. So you can use this for a SaaS use case or if you have multiple clients that you want to serve inside one Directus instance, this is one way that you can achieve that.
Conclusion and Next Steps
So that's it for some of the most common use cases for Directus roles and permissions. If you have other use cases that you would like us to cover, hop into our Directus community Discord server, check us out on Twitter or just contact us through the website. And make sure you subscribe to the YouTube channel so you can get notified when our next video drops.