The word "auth" is complicated because there a wide range of topics that fall in the bucket of "auth." In this series, we'll take a practical approach to understanding many of these topics with examples to learn from.
Previously, we wrote about user authentication. Now, let's look at a related topic, authorization.
What is Authorization?
Authorization is the process of determining if someone has access to something. This is different from authentication, which is about determining who someone is in the first place.
As an example, imagine we are building a simplified Twitter. Users can sign up, post tweets, and delete tweets. When we receive a request to delete a tweet, we need to do two things:
- Determine who made the request
- Determine if they are allowed to delete the tweet
Step 1 is authentication - we are determining who the user is. Step 2 is authorization - we are determining if that user is allowed to delete the tweet.
In this case, step 2 could be as simple as only the user that made the tweet is allowed to delete it:
function canDeleteTweet(request, tweet) {
// Authentication
const userId = getUserThatMadeTheRequest(request)
// Authorization
return userId === tweet.userId
}
Step 2 could also include other rules, like maybe we hire a moderation team and allow them to delete tweets as well:
function canDeleteTweet(request, tweet) {
// Authentication
const userId = getUserThatMadeTheRequest(request)
// Authorization
return userId === tweet.userId || isUserAModerator(userId)
}
Implementing Authorization
There are a lot of different approaches to implementing authorization. One example that you might have come across before is role-based access control (RBAC). Role-based access control is a fancy way of saying "assign each user to a role (or group) and each role has a defined set of actions they can take".
We actually already looked at an example of RBAC above. In our simplified Twitter example, we had two roles:
- Moderators
- Users (we implicitly defined this as everyone who isn't a moderator)
Users can create tweets and delete their own tweets. Moderators can delete anyone's tweets.
You can extend this in a lot of ways. For example, maybe your roles are hierarchical. Each role has its own set of permissions and also gets all the permissions from any role beneath it in the hierarchy.
RBAC is generally seen as a coarser form of authorization, since each user must belong to a role and every user within that role gets the same permissions. Another example approach is attribute-based access control (ABAC), where you look at attributes (e.g. what team the user is on, is this production or staging, etc.) to determine if a user can perform some action.
Authorization for B2B Businesses
Let's look at another example - building a B2B / SaaS business. In this case, let's say we're making an MVP of Slack.
In a B2B business, users will use your product along with their coworkers. To accommodate that, each user can be a member of an organization.
The first permission that we need is the ability to create an organization and every user should be allowed to do it. Once an organization is created, we have three hierarchical roles:
- Owner - Able to delete the organization, manage billing, and invite new owners
- Admin - Able to create new channels, manage organization settings, and invite new admins/members
- Member - Able to send messages in any channel
Importantly, these roles apply only within the context of an organization. I can be an Owner of organization A and a Member of organization B. Those roles dictate my permissions within the organization - not globally.
Since these roles are hierarchical, Admins have all the permissions that Members have, and Owners have all the permissions that Admins have.
The Owner, Admin, and Member hierarchy is straightforward, and works for a lot of B2B businesses but it can be tricky to manage in practice. If you'd prefer to let someone else handle it, PropelAuth provides this structure by default - including UIs for inviting users, UIs for managing roles, and libraries for adding authorization to your backend.
Top comments (0)