Implementing an authorization model for a SaaS application

Published by James Walker on October 31, 2023
Implementing an authorization model for a SaaS application

Authorization (authz) is the process of verifying whether a user can perform a particular action inside a software product. It comes after authentication (authn), which establishes the user's identity.

SaaS applications need robust authorization models. Access to different actions within the app should be gated behind permissions that can be assigned to users through expressive roles.

Because there are several kinds of authz architecture available, selecting the right approach for your system can be daunting. This article outlines a method for implementing authorization within a typical workspace SaaS application.

Identifying authorization requirements

Begin implementing authorization by identifying your application's requirements. Although these naturally vary by system, authz for most SaaS solutions can be planned in three stages:

1. List the resources and actions in your system

SaaS authorization decisions are usually predicated on the combination of a resource (noun) and verb (action), such as raising an invoice or deleting a task.

List all the resources your system handles (*invoice* and *task*), then determine the different actions that users can perform for each one (*raise* and *pay* for *invoice*, *assign* and *delete* for *task*). This procedure defines your permissions by identifying the operations that your authz model needs to protect.

2. Devise roles that mirror your organization's structure

Next, determine who'll access your system and the permissions they'll require. For example, support staff could need the *assign task* and *delete task* permissions, resulting in a *Task Manager* role. Meanwhile, the *Account Manager* role might require *raise invoice* only.

Plan for roles to be individually assigned to the users who need them, with some users having multiple roles. Administrators, for example, should be able to access all of the system's functions.

Your roles should ideally replicate your organization's physical structure in your authz architecture to ensure everyone has the access they need and nothing more.

3. Evaluate the security risks and vulnerabilities in your application and workspace

The functionality of authz systems should always reflect the severity of the security risks you face. For each of the resources and actions you've identified, question what would happen if an *un*authorized user was allowed to perform the interaction. This exercise informs awareness of the exact risks and vulnerabilities you face.

Particularly vulnerable areas might need to be placed behind additional layers of protection. Merely allocating a role may be insufficient if you need to delete users or if they need to access medical information, for example. In these situations, your authz model might need to request that the user reauthenticates to demonstrate that they still hold their security token.

Selecting an authorization model

Once you've established what needs protecting, who'll access it afterwards, and the effects on your security posture, you can start comparing different authorization models against your needs and risks. There are three main authz patterns widely used by modern SaaS systems:

Access control lists

An access control list (ACL) is the simplest form of authorization constraint. They directly map users to permissions such as *raise invoice*. Only users included in a permission's access control list are able to perform the interaction it controls.

ACLs are simple to implement because they need no supporting infrastructure. They're easy to reason about as users are either in a permission's list or excluded. However, maintaining ACLs is cumbersome at scale because you can't repeatedly assign sets of related permissions to multiple users. This is where RBAC comes in.

Role-based access control

Role-based access control (RBAC) adds an additional layer between users and permissions. Users are assigned roles that act as collections of permissions. You can easily create roles to mimic your organization's structure, which allows new staff members to be quickly onboarded with the permissions they need.

A weakness of RBAC is its tendency to spawn a large number of roles. Unless carefully managed, roles can become either too precise or too broad, making it harder to ascertain who can perform each task.

Attribute-based access control

Attribute-based access control (ABAC) is the most powerful form of authz. It can be trickier to implement, but it's the most scalable pattern for complex systems in the long term.

ABAC imbues your authorization system with contextual information at the time each decision is made. It lets you return a different outcome based on the characteristics of the user and the requested resource. For example, access to resources with a "high security" attribute might require the requesting user to hold a certain security clearance.

Choosing between ACLs, RBAC, and ABAC

The decision whether to use ACLs, RBAC, or ABAC should be based on the authorization requirements you identified for your system. ACLs could work well for simpler solutions with relatively few resources, actions, and users. This approach is quick to build and secure as the small scope reduces the risk of oversight and complicated logic bugs.

Most applications of any significant scale will lend themselves to RBAC, though. Users of SaaS apps frequently join, leave, and change positions within their organization. RBAC can accommodate these changes without making you micromanage individual permission assignments.

Use ABAC in systems where authz outcomes are dependent on the context surrounding each user and resource. It allows you to create powerful policies, but it's consequently more complex to set up and maintain. However, reaching for a prebuilt authz solution can help alleviate the learning curve.

Implementing authorization using RBAC

RBAC-based authorization is one of the most common models found in SaaS solutions. You can implement it by following four basic steps.

1. Set up your authorization infrastructure

Selecting a prebuilt authz platform simplifies the integration of roles, permissions, and policies in your codebase by removing the need to write complex logic yourself. Set up your infrastructure first, then add it to your SaaS application using the APIs that the platform provides. Your app should call the service each time it needs to perform an authorization check.

Take the time to set up any extra tools that form part of your infrastructure. These could include CLIs and web UIs for performing ad-hoc tests and managing your roles, users, and policies. Configure any monitoring and compliance solutions that are part of the platform, such as decision outcome audit trails.

2. Create your roles and permissions

With your platform ready to use, you can create the permissions and roles you identified during the requirement-gathering stage. Add the permissions you need first, such as *raise invoice* and *pay invoice*. Then set up roles like *Account Manager* and link in the appropriate permissions.

Simultaneously, start to register users into the system. Grant them the roles they require for their work, then review all the assignments you've made. This is an important step to ensure nobody's been given too many permissions. If in doubt, don't assign a role until you've checked it's needed.

3. Configure your access control policies

Next, you need to configure your access control policies and rules. How you do this will vary depending on the authorization system you're using. When you're building your own solution, you can write custom logic yourself, but for better interoperability, try to adopt an industry-standard policy framework.

Decoupling policies from your code makes them easier to change. You can test your policies within standalone CI/CD pipelines without having to run the jobs for your entire project. This produces quick actionable feedback that informs whether policies are correct. Declarative configuration results in expressive rules, which makes it easier for future security admins to interpret your intentions.

It's best to keep policies as simple as possible. Overly complex hierarchies, relationships, and rules are difficult to reason about and maintain. They often fail to model your access requirements accurately and can drift away from your expectations over time. You'll improve your system's versatility by sticking to simple policies that are composed into larger ones by using multiple roles and permissions.

4. Test your model

In larger systems, issues with your permissions and roles often only become apparent once the model is in use. You could find that roles are too broad, which cause users to become overprivileged, or they might be excessively granular. In the latter case, administrators can be overwhelmed by the number of roles they have to manage. This allows for oversights to occur.

You can avoid facing these problems by thoroughly testing your model before you launch it into production. Testing will reveal any anomalies in your access control policies and associated logic. If you're using a policy framework for your authz implementation, you can use its developer toolkit to test your model. This will help you robustly inspect your rules, check their outcomes, and evaluate performance.

Ongoing maintenance and updates

Authorization systems shouldn't be set adrift after the initial implementation. As one of the foundational components of your SaaS solution, authz should be reviewed at regular intervals so you can make sure it's still meeting your business and security demands.

In the context of RBAC, this means frequently assessing your roles to check they remain relevant to your organization's structure. Remove roles you no longer need to avoid confusion and disarm overprivileged users. Conversely, if you find some users require only a few permissions from a role, split that role into two to maintain good separation.

Visibility into role usage is also crucial. Integrating your authorization system with an observability solution lets you log authz decisions and track who's using each role in your workspace. Besides informing accurate role allocations, this practice also enhances security by recording denied authorization hits. If a user's repeatedly denied access to multiple functions, the attempts could be an attacker who's speculatively trying stolen credentials.

Moreover, activity monitoring helps ensure your SaaS app's ongoing compliance with relevant laws, regulations, and industry standards. Access control lists let you prove future conformity by demonstrating who can perform particular actions, while audit logs provide a comprehensive history of access attempts recorded by your model. If the worst transpires and you suspect illegitimate access has been obtained, past authz outcomes can help determine who did what and when.

Conclusion

Authorization is the process by which software systems check whether a user can perform a given task. A resilient authorization model is essential for SaaS applications since these apps often serve several users across multiple organizations.

Proper authorization is a prime factor affecting your overall workspace security and your application's integrity. Poorly planned authorization systems can lack sufficient depth to reliably segment data between users, teams, and customers. This results in unintentionally empowered accounts that could leak data and make you noncompliant with relevant industry regulations.

Selecting a proven authorization model reduces the risk of oversight by letting you focus on your app's business requirements. Once you've distilled its functions down to resources (nouns) and actions (verbs), you can create granular authorization policies ready to grant to your users. Regularly reviewing your roles, permissions, and access logs will keep you updated on authorization activity and provide opportunities to prune unused policies.

GUIDE

Book a free Policy Workshop to discuss your requirements and get your first policy written by the Cerbos team