After Uber’s hack of 2022, where an attacker got into the company’s internal network and accessed its tools, there was one prominent takeaway in the industry: Security breaches are not something you react to but something you have to prevent. A major step organizations can take in this direction is to keep software under access control policies and continuously audit access and actions.
There are multiple access control mechanisms on the market today to help you do this, including role-based access control (RBAC). In this article, we look at the advantages of RBAC in terms of operability and security, how to implement it with a schema and how it can help you with compliance. We also discuss a few other access control mechanisms to understand how they work.
Role-based access control is a mechanism where you allow users to access certain resources based on permissions defined for the roles they are assigned to. There are three major components to RBAC:
Each role is granted specific permissions to access certain resources, and a user is assigned a given role. So upon being given a role, a user will then be able to view and use everything that role is allowed to access.
Organizations implement RBAC with the help of schema. In this SQL-based pseudo schema, we will see how to map roles, users and permissions. Database schema contains tables and their relationships. There are five main tables needed to implement an RBAC schema:
- Users: Keeps track of all the users and their basic details
- Permissions: Shows the permissions defined in the systems, which can be divided further per resource and actions allowed on that resource
- Roles: Roles defined in the system
- User_Roles: Mapping of roles per user to see all the roles a user has; a many-to-many relationship
- Role_Permissions: Shows the association between roles and permissions
With a few unique requirements, you may need to assign a user some permissions directly. This is not recommended at all, as once you do this, a floodgate will open, with your team potentially creating a ton of permissions assigned directly to one user. If, for some specific use cases, you do want to accommodate this, you can create another table, User_Permissions, to associate users with permissions.
With these five or six tables, you will be able to create a function that performs authorization checks for you. Below is a pseudo function for checking permissions:
function check_permissions(user, permissions): user_role = get_role(user) user_permissions = user_role.get_permissions() if permissions in user_permissions: Return “allowed” else: Return “Not allowed”
The definition of permissions here can differ from implementation to implementation. One implementation could be an object-permission like “profile-edit,” which means the user can edit the profile.
You may also want to implement role hierarchy, which means that one role can have different roles, and the permissions will resolve from these roles. In these cases, the implementation can be a bit tricky. You would need two field names: is_parent_role and child_roles. Or you can create another table for this mapping.
Importance of Role-Based Access Control
Role-based access control standardizes the process of giving permissions to users to execute or perform operational tasks. The advantages of RBAC include:
- Less redundant work: Since you have roles defined, you simply have to assign a user a role for them to be granted the appropriate permissions. Otherwise, you would have to add each permission manually to each user.
- Better security: Since a centralized team defines these roles, RBAC is less prone to error and easier to manage. Defined roles also mean there is a lower chance bad permissions are granted by mistake.
- Easy to audit: Predefined roles mean fewer changes in role definitions and assignments, meaning audits will be simpler compared to assigning permissions to each user.
- Compliance requirements: Implementing access control will help you adhere to compliance regulations, which is always a major aspect of security.
Best Practices with RBAC
A single bad implementation can hamper the most secure system. So it’s of utmost importance that best practices are followed.
Write detailed information for each role and what it should do. Include a note column in the roles table to define the usage of each role and why it was created. Refrain from blindly creating roles; instead, try to find the best-suited roles already present and assign those.
Avoid explicit user-level permissions, as this can cause confusion and result in improper permissions being given.
Make sure that all tables have a created_by, updated_by, updated_at and created_at column. Also, each change in the tables should be emitted to a centralized auditing system to help identify if any permissions were improperly assigned or someone was given any escalated permission that was not required.
Not everyone should be able to control who can change roles. This is an important operation, and every change should pass through a well-audited approval-based pipeline.
Aside from these, the team managing access control should publish guidelines on how to create permissions for the roles.
Other Access Control Mechanisms
There are multiple access control mechanisms in use today. We cover a few of the major ones below.
Attribute-Based Access Control
In this access control mechanism, permissions are provided to resources based on the attributes of those resources. One of the major examples of this is AWS, where you can provide access to resources using tags.
Pros: This is a very flexible method; it is easy to make changes to the attributes for a user to receive a permission
Cons: Unintended permissions can propagate if the attribute is associated with another entity. It also takes a longer time to implement, as each resource has to be associated with an attribute, and the team has to define those attributes and plan them.
User-Level Access Control
In this mechanism, a user is allowed access to resources based on the permission assigned directly to the user.
Pros: Looks simplistic at first and is the easiest mechanism to implement.
Cons: It’s tough to manage because it can get really complex as users and permissions grow.
Policy-Based Access Control
Here, users are given access based on a policy defined for the user on a business level. The policy evaluates the subject, object, action and context. The subject can be a department such as engineering; the object can be a tool like SonarQube; the action can be the activity you’re trying to perform, e.g., viewing reports; and the context is the given environment, such as staging or production.
Pros: Human-readable policies make more sense and have context-level control.
Cons: The implementation is complex since its execution can involve different verticals and their tools.
There are many ways to implement access control. A very common method has been to combine RBAC and ABAC. AWS has implemented what appears to be one of the better combinations of these two.
Apart from choosing between the control mechanisms, you have to make sure that each and every event is audited and have alerting in place in case incorrect permissions are created.
It is really tough to crack all of these requirements smoothly, as you will face multiple hindrances. For instance, the centralized tool you use must integrate with numerous internal tools; some may be restricted and support only a few protocols.
Problems aside, you should implement access control on all your systems, as this will give you confidence in scenarios where your systems are compromised.