Best Practices for Effective User Permissions and Access Delegation
- Share:
With applications' ever-growing complexity and microservice-based architectures' growing popularity, it becomes increasingly important to ensure the security of our services. One critical security aspect is authorization - ensuring that the right users have appropriate access to the right resources at the right times.
Who uses our application and the level of control they expect to have has changed as well. Aside from end users, weāve got dozens of stakeholders, including internal non-technical members of our organization, DevOps, RevOps, AppSec teams, developers, and, donāt forget, AI agents and non-human users. These users each require their own level of access to the application, and, to make things even more difficult, they need a way to safely delegate permissions and permission management.
In this blog, Iāll outline some of the challenges of handling user permission management effectively and suggest some best practices for building effective user permissions management, with a focus on effective access delegation based on a cascading authorization model.
These should help you plan an authorization model that provides a better security posture and a seamless user experience. To start, talk bout users:
Who Uses Our Application?
As we're talking about user permissions management, we need to first take a look at the user side of things. The question āWho Uses Our Application?ā can be a lot less straightforward than you might think. It obviously depends on the individual thing that you are building. Letās look at an example:
This diagram shows all the different types of users in our application and the questions about user and role management and access delegation we should ask ourselves when dealing with each of them. Letās dive into each of these separately:
End Users
End users are the primary group interacting with our application to utilize its services. Their interaction spans multiple areas, each of which must be considered when designing our authorization layer:
- FrontendāWe need to control what users can see in the application. Not all users should have access to every feature. The simplest example of this is segmenting users based on payment/subscription status: paying users might have access to premium features that non-paying users cannot see.
- BackendāIt's crucial to manage what actions users can perform. Depending on the complexity of our application, there are different ways of handling this challenge. The simplest example comes from the solution side of things: In a Role-Based Access Control (RBAC) system, users with an Editor role will have different permissions than those with a Viewer role.
- DBāWe must also regulate which data users can access, whether it's stored in local or external databases.
Itās also important to remember that what we call āUsersā arenāt necessarily human - especially with LLMs and AI on the rise. End users can include automated systems or bots that interact with the application programmatically.
Internal Users
Internal users are members of our organization who need access to the application. For example, in a banking application, end users are the bankās customers, while internal users include tellers and account managers. These internal users often require different levels of access, and some may need to manage as well as delegate access to end-users. For instance, an account manager might need to approve loan requests from clients. As these are not technical users, they need to be provided with an interface that will allow them to easily manage and make changes to the end-user authorization layer within strict per-defined limits.
Organizational Stakeholders
Modern applications involve more than just end users and developers. Various stakeholders, such as DevOps, RevOps, and AppSec teams, require access to specific parts of the application. These stakeholders often need the ability to manage user roles and delegate access management to internal users.
Developers
Developers are responsible for building and implementing the application's security features, including authorization. They need a level of user permissions management that allows them to create and handle new policies, requests, and processes, impacting all other user levels. This obviously doesn't mean their access is unlimited, and it requires monitoring and management as well.
Authorization Administrators (Overseers)
It doesn't end with the developers themselves, thoughāthereās actually one more level of access here. Who decides what developers can access and what level of control they have over our application's authorization layer? More often than not, a specific person or group will be directly in charge of managing the applicationās user and role management. These āAuthorization Administratorsā (Or, as I decided to call them here after watching the new Fallout series - Overseers) decide what access developers have and control the authorization system's management. They create access request flows and ensure a secure management structure. However, to avoid creating a centralized root user, they do not have the ability to manage individual authorization policies fully.
Now that we have a better understanding of this cascading model of application authorization, letās see what we can do about it -
The Challenge of Access Delegation and User Permissions Management
As we saw, deciding who can do what inside an application is one thing when we're just dealing with end users - but we never are. The challenge of creating an efficient model of user permissions management that enables access delegation between all of our applicationās users is another story entirely.
This challenge raises two major issues we need to deal with - Recursiveness, which can be a tough technical challenge to solve, and Trust, which can be hard to handle as it can have dire consequences if managed incorrectly.
The prospect of creating all-powerful superusers is alluring to many developers. What can be more secure than directly calling all the shots yourself? While thatās true to some extent, this approach backfires very quickly. If you, as a developer, are the person directly in charge of all user roles and permission management in your organization, you will very quickly realize the strain this will have on you and the entire R&D team as you turn into a bottleneck for the entire business operation. Only one person/group can manage authorization for every user of your application? Great - itās their full-time job now.
The opposite approach, delegating all power away from developers to other stakeholders, is often equally dangerous. It creates a slow-moving, inefficient bureaucracy (Iām looking at you, security and compliance) or an unstable, risk-filled environment (hi, sales and product).
At the end of the day, itās a question of balanceāone that varies for every company and application. When building this balance, itās important to empower the various stakeholders (and customers) working with the application, giving them a significant amount of control and decision-making abilities to enable the business to move quickly and securely while enabling developers to monitor the flow without becoming a bottleneck.
Here are some guidelines for how this can be achieved:
The Solution? A Cascading Authorization Model -
āĀ Create a cascading waterfall of trust and permissions
By creating a cascading system of permissions and trust, you can ensure that the right permissions are granted to the right users at the right time. Often, developers and security become the main part of this waterfall, but it mustnāt end with them. Design your flow to gradually delegate access in a balanced amount between the different levels, with each level empowering the ones below it.
āĀ Assign an owner
To avoid conflicts, such as two admins being able to remove each other, always have a primary admin, or āowner,ā who takes precedence to avoid conflict. Owners often cannot be removed without transferring the title first.
āĀ Identify bottlenecks early on
Identify potential bottlenecks in permissions that are hard to delegate or manage, and have a plan and interfaces to mitigate these issues in advance - before friction piles up.
āĀ Use classic policy models for your āhigh-levelā authorization policies (e.g. RBAC, ABAC)
Just like with your regular permissions, thereās no need to reinvent the wheel. When handling the higher levels of your user waterfall (Organizational Stakeholders, Developers, and Overseers), start with a common policy model first. Itās even better if you can use the same policy model across the different levels, if applicable. This can help ensure consistency and ease of understanding across the system, lowering the cognitive load on system managers and users.
āĀ Generate audit logs across the entire authorization system
The information on who changed permissions at every level of this waterfall is crucial - especially at its higher levels. Make sure to log and track these changes.
āĀ Build on top of existing cascading authorization solutions
Some tools (Such as Permit.io) provide a cascading system of authorization from the get-go, so you donāt have to design one from scratch. This could be useful to save time and effort and help build a more secure system.
Common Pitfalls to Avoid:
āĀ Mixing up authentication and authorization
This might seem trivial, but it happens all the time. Authentication is the process of identifying the user, while authorization is the process of granting access to specific resources based on the authenticated userās roles or privileges. Solutions are required for both.
āĀ Thinking you wonāt need a system this complex
Thereās a good chance that if your application doesnāt at least partially require this type of authorization structure, it will eventually. Applications grow and develop over time, and it's important to at least consider setting the groundwork for a system that will be able to scale with your applicationās needs from day one.
āĀ Limiting access control to the vendor side
Itās not enough to delegate access control from developers to the rest of the organization. Doing so merely moves the bottleneck up the chain. To appropriately delegate the workload, you must be able to assign at least some access controls to the end customers themselves, providing them with true self-service.
āĀ Thinking access control is limited to direct human use
Your first users are likely to be human users, but with increasing automation, more and more of your āusersā will be automated agentsāother applications and AI agents acting on behalf of humans. You will need to cater to them, too, and it might be sooner than you think.
āĀ Delaying providing interfaces to non-technical people
A powerful interface thatās intuitive to non-technical users is crucial for access control systems. See how you can provide friendly authorization management user interfaces that are usable by non-technical users early on.
Conclusion
Effective user role and permissions management is crucial for maintaining the security and efficiency of modern applications. By understanding the diverse range of usersāfrom end users and internal employees to developers and organizational stakeholdersāyou can design an authorization system that meets their specific needs while maintaining proper security.
Implementing a cascading authorization model is a practical solution to the challenges of access delegation and user permissions management. By creating a hierarchical system of trust and permissions, assigning ownership, identifying bottlenecks, and using classic policy models like RBAC and ABAC, you can ensure that the right permissions are granted to the right users at the right time.
Ultimately, striking a balance in access delegation and empowering various stakeholders will allow your business to move quickly and securely without the risk of creating bottlenecks. With these best practices, you can build an authorization framework that ensures both security and operational efficiency for all application users.
Written by
Daniel Bass
Application authorization enthusiast with years of experience as a customer engineer, technical writing, and open-source community advocacy. Comunity Manager, Dev. Convention Extrovert and Meme Enthusiast.