Why Access Control Matters
Whether you're building a 2B SaaS platform or a consumer app, you can't escape permissions. Get them wrong, and you'll either lock users out of features they need or expose data that should stay private. Over the years, countless systems have been designed to control who can do what, but nearly all of them boil down to four classic models: DAC, MAC, RBAC, and ABAC.
At their core, every permission model has three basic ingredients: a user (the person or process making a request), an object (the thing being accessed, like a file or an order), and a policy (the rules that decide whether access is granted). Keeping that trio in mind makes the rest of this easier to follow.
DAC: Discretionary Access Control
DAC is the oldest and most straightforward model. The system identifies the user and checks the object's access control list (ACL) to see if they're allowed to read, modify, or delete it. The twist? The owner of the object gets to decide who else can access it. That's where the "discretionary" part comes from.
You've seen DAC in action if you've ever used Windows NTFS. You right-click a folder, go to Properties, and manually grant permissions to other users. It works fine for a single machine, but it falls apart when you need to apply the same policy to a group of files for a group of users. Managing permissions becomes a nightmare because there's no central control.
MAC: Mandatory Access Control
MAC was designed to fix DAC's messiness. Instead of letting object owners set permissions, the system itself enforces rules based on labels. Every object gets a classification (like "Top Secret"), and every user gets a clearance level. The system automatically decides whether access is allowed.
If you've watched spy movies, you've seen MAC in action: an agent tries to pull up a classified file, and the screen flashes "Access Denied: Requires Level 5 Clearance." The file has the label, the agent doesn't, and no amount of tweaking will change that.
MAC is perfect for military or government settings where hierarchy is non-negotiable. But for a typical business app, it's too rigid. You can't easily grant temporary access or customize rules on the fly, which is why you don't see MAC in most commercial software.
RBAC: The Workhorse of Modern Apps
RBAC, or role-based access control, is the model you'll find in most enterprise systems today. Instead of assigning permissions to each user individually, you create roles and assign permissions to those roles. Users then get one or more roles. It's a simple idea, but it scales beautifully.
MongoDB uses RBAC. It defines granular permissions like find (run queries) and insert (add data), then bundles them into predefined roles like read or readWrite. An admin can also create custom roles to match their exact needs. That flexibility is why RBAC has become the default choice for 2B SaaS products.
The RBAC Family Tree
RBAC isn't just one thing. The core version, RBAC0, covers the basics: users, roles, and permissions. But the model has evolved into several extensions.
RBAC1 adds role hierarchies. A child role inherits permissions from its parent. For example, a "Manager" role might inherit everything from "Employee" plus extra permissions. This reduces duplication and makes role management cleaner.
RBAC2 introduces separation of duties. The idea is to prevent conflicts of interest. You wouldn't want the same person to be both a player and the referee in a basketball game. Static separation means a user can't be assigned conflicting roles at all. Dynamic separation means a user can have both roles but can't activate them in the same session.
RBAC3 is the full package—it combines RBAC1 and RBAC2 on top of RBAC0. It's the most powerful but also the most complex to implement.
Designing a Permission System with RBAC
Let's make this concrete. Suppose you're building a suite of tools for a mid-sized manufacturing company with thousands of employees. They use OA, HR, CRM, and ERP systems. Not everyone needs the same features, so you need a permission system.
Start with account management. Every person who interacts with the system gets an account with basic info: name, department, contact details, and so on. This is the foundation.
Next, think about roles. Look at your actual users and group them by job function. What menus do they need? What data should they see? For example, a sales rep needs access to CRM but probably shouldn't see payroll data in the HR module. Define roles like "Salesperson," "HR Manager," or "System Admin."
Here's the key insight: permissions have two dimensions—menu permissions (what screens and buttons you can see) and data permissions (which rows of data you can access). A role might grant a user the ability to view a customer list, but only for customers in their region. Getting both right is what separates a good permission system from a frustrating one.
How granular should you go? It depends on your business. Some SaaS products only control access at the top-level menu. Others, like Salesforce, let admins control down to individual fields and buttons. More granularity gives admins more flexibility but also adds complexity and cost. Start with a level that matches your users' needs, not what's technically possible.
ABAC: Attribute-Based Access Control
ABAC is the new kid on the block, and some people call it the future of permissions. Instead of assigning roles, you define rules based on attributes. These attributes can be anything: user attributes (age, department), environment attributes (time of day), operation attributes (read, write), or object attributes (resource type, sensitivity).
Here's a classic example: "Allow all homeroom teachers to enter the school gate during class hours." The rule combines four attributes: user.role == 'teacher', user.homeroom == true, environment.time within school hours, and object.type == 'gate'. The system evaluates all of these dynamically before granting access.
ABAC is incredibly flexible—you can encode almost any policy. But that power comes with a cost. Implementing ABAC usually requires a rule engine and configuration files (XML or YAML), which can be overkill for most applications. Even Kubernetes, initially a proponent of ABAC, switched to RBAC in version 1.8 because ABAC was too hard to manage.
Which Model Should You Choose?
There's no one-size-fits-all answer. If you're building a military-grade system, MAC might be necessary. If you need dynamic, context-aware rules, ABAC could be worth the complexity. But for most business applications, RBAC is the sweet spot. It's well-understood, easy to implement, and can be extended to handle a wide range of scenarios.
One warning: don't make the mistake of checking for roles instead of permissions in your code. If you write if (user.hasRole('hr')), you'll be in trouble when the company decides that department managers can also approve raises. Instead, check for the permission itself: if (user.hasPermission('salary.update')). That way, you can assign the permission to any role without touching the code.
Access control is one of those things that seems simple until you have to build it. Start with the basics, understand the trade-offs, and choose the model that fits your product's reality.
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!