Permit logo
Home/Blog/

Best Practices for Effective User Permissions and Access Delegation

Learn best practices for managing user roles and access delegation and how to implement a cascading authorization model to enhance your app's access control.
Best Practices for Effective User Permissions and Access Delegation
Daniel Bass

Daniel Bass

|
  • 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:

Untitled (92).png

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.

Untitled (93).png

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.

Untitled (94).png

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

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.

Test in minutes, go to prod in days.

Get Started Now

Join our Community

2026 Members

Get support from our experts, Learn from fellow devs

Join Permit's Slack