Security – Role vs Permission Based Access Control

access-controlauthorizationpermissionsrolesSecurity

I'm trying to understand the inherent tradeoff between roles and permissions when it comes to access control (authorization).

Let's start with a given: in our system, a Permission will be a fine-grained unit of access ("Edit resource X", "Access the dashboard page", etc.). A Role will be a collection of 1+ Permissions. A User can have 1+ Roles. All these relationships (Users, Roles, Permissions) are all stored in a database and can be changed on the fly and as needed.

My concerns:

(1) What is so "bad" about checking Roles for access control? What benefits are gained by checking for permissions instead? In other words, what's the difference between these two snippets below:

if(SecurityUtils.hasRole(user)) {
    // Grant them access to a feature
}

// vs.
if(SecurityUtils.hasPermission(user)) {
    // Grant them access to a feature
}

And:

(2) In this scenario what useful value do Roles even provide? Couldn't we just assign 1+ Permissions to Users directly? What concrete value of abstraction do Roles offer (can someone give specific examples)?

Best Answer

(1) What is so "bad" about checking Roles for access control? What benefits are gained by checking for permissions instead?

At the moment of checking, the calling code only needs to know "does user X have permission to perform action Y?".
The calling code does not care about and should not be aware of relationships between roles and permissions.

The authorization layer will then check if the user has this permission, typically by checking if the user's role has this permission. This allows you to change authorization logic without updating the calling code.

If you directly check for role at the call site, you are implicitly forming role ⇄ permission relationships and injecting authorization logic into the calling code, violating separation of concerns.

Should you later decide that role foo should not have permission baz, you would have to change every code which checks if the user is a foo.

(2) In this scenario what useful value do Roles even provide? Couldn't we just assign 1+ Permissions to Users directly? What concrete value of abstraction do Roles offer (can someone give specific examples)?

Roles conceptually represent a named collection of permissions.

Let's say you are adding a new feature which allows a user to edit certain settings. This feature should be available to administrators only.

If you are storing permissions per user, you would have to find all users in your database which you somehow know are administrators (If you're not storing role information for users, how would you even know which users are administrators?), and append this permission to their list of permissions.

If you use roles, you only have to append the permission to the Administrator role, which is both easier to perform, more space efficient, and is less prone to mistakes.