RBAC vs ABAC: Access Control Models Explained
RBAC grants access based on a user's assigned role; ABAC evaluates attributes of the user, resource, and context at request time. How they compare.
Role-based access control (RBAC) grants permissions based on the role a user is assigned — admin, editor, viewer — and every user with that role gets the same access. Attribute-based access control (ABAC) grants permissions by evaluating a policy against attributes of the user, the resource, and the request context at the moment access is requested, which lets it express rules RBAC can’t without exploding into dozens of roles.
Both answer the same question — should this request be allowed? — but they get there through different models, and most systems that start with one eventually feel the pull toward the other as their rules get more specific.
How RBAC works
RBAC sits between users and permissions with an intermediate layer: roles. Instead of granting “can delete invoices” directly to a person, you grant it to a role like billing-admin, then assign that role to whichever users need it. Permissions attach to roles; roles attach to users. Change what a role can do, and every user holding it is updated at once.
This mirrors how most organizations already think about access — job titles, teams, and responsibilities — which is why RBAC is the default model behind most admin panels, database grants, and OAuth-issued scopes. It’s easy to audit: to answer “who can delete invoices,” you list the users with the billing-admin role, rather than scanning every user’s individual permission set.
The limitation shows up when access depends on more than “what role are you.” Should a billing-admin be able to delete any invoice, or only invoices for their own region? Only during business hours? Only for accounts under a certain dollar threshold? Pure RBAC handles this by multiplying roles — billing-admin-us, billing-admin-eu, billing-admin-under-10k — and that combinatorial growth is where role-based systems tend to get unwieldy.
How ABAC works
ABAC replaces the fixed role-to-permission mapping with a policy engine that evaluates attributes at request time. An attribute can come from the user (department, clearance level, employment status), the resource (owner, sensitivity classification, region), the action (read, delete, export), or the environment (time of day, request IP, device posture). A policy might read: allow delete on invoice if user.department == resource.department and user.role == 'billing-admin' and time.hour is within business hours.
Because the decision is computed per request instead of looked up from a static role table, ABAC can express fine-grained and dynamic rules — region-scoped access, time-boxed access, ownership checks — without a combinatorial explosion of roles. This is the model behind most modern cloud IAM systems, where policies reference resource tags and request context rather than a fixed role list.
The cost is complexity. Policies are harder to write correctly, harder to audit at a glance (“who can delete invoices” now requires evaluating the policy against every possible combination of attributes rather than reading a role membership list), and harder to reason about when multiple policies interact. A misconfigured ABAC policy can silently grant or deny access in ways that don’t show up until someone hits the specific combination of attributes that triggers it.
RBAC vs ABAC: comparison table
| RBAC | ABAC | |
|---|---|---|
| Decision basis | Fixed role assignment | Attributes evaluated at request time |
| Granularity | Coarse — per role | Fine — per user, resource, and context |
| Adding a new rule | Often requires a new role | Usually just a new policy condition |
| Auditability | Simple — list role members | Requires evaluating policy logic |
| Context-awareness (time, location, device) | Not native | Native |
| Complexity to implement | Low | Higher — needs a policy engine |
| Typical use | Admin panels, internal tools, database grants | Cloud IAM, multi-tenant SaaS, regulated data access |
Where the two meet
Few large systems are purely one or the other. A common pattern layers ABAC-style conditions on top of RBAC roles: a user’s role determines the category of actions they can attempt, and attribute checks narrow that down for the specific resource in front of them — the billing-admin role grants delete access broadly, and an attribute policy scopes it to the user’s own region. This hybrid gets RBAC’s easy auditability for coarse access and ABAC’s precision for the exceptions, without forcing every rule through one model.
The same tension shows up in zero trust security architectures, which lean heavily on attribute-style evaluation — device posture, session risk, request origin — precisely because a static role can’t capture “this login looks like it’s coming from a new country.” Multi-factor checks, covered in what multi-factor authentication is, are themselves a kind of contextual attribute: a policy engine can require a fresh MFA challenge as one of the conditions before granting a sensitive action, something a plain role assignment has no way to express.
Which one to reach for
Start with RBAC if your access rules map cleanly onto job functions and don’t vary by resource, tenant, or context — most internal admin tools, small SaaS products, and database permission schemes fit this shape, and RBAC’s auditability is worth keeping as long as it holds. Reach for ABAC, or a hybrid, once you find yourself creating near-duplicate roles to express a condition (editor-region-a, editor-region-b), once access needs to depend on properties of the resource itself rather than just the user, or once regulatory requirements demand attribute-level justification for every access decision — common in multi-tenant platforms and anything handling regulated data.
Whichever model you pick, the enforcement point matters as much as the model: access decisions belong behind a consistent check — a middleware layer, an API gateway, or a dedicated policy service — rather than scattered if statements across the codebase. A single point of enforcement is what makes an access control model auditable in the first place, whether that model is a role table or a policy engine.
The takeaway
RBAC assigns permissions to roles and roles to users, which is simple to reason about but coarse when rules depend on more than job function. ABAC evaluates attributes of the user, resource, and context at request time, which handles fine-grained and dynamic rules at the cost of more complex policies to write and audit. Most systems that outgrow pure RBAC don’t replace it outright — they layer attribute checks on top for the cases where “what role are you” isn’t enough of an answer.
Keep reading
Chisato · · 5 min read What Is Session Fixation?
Session fixation tricks a victim into using an attacker-known session ID, so logging in hands the attacker an authenticated session too.
Chisato · · 4 min read What Is IDOR? Insecure Direct Object References Explained
IDOR is an access control flaw where an app trusts a user-supplied ID to fetch a record without checking the requester actually owns it.
Chisato · · 4 min read The OAuth PKCE Flow Explained
PKCE hardens the OAuth authorization code flow against interception, and is now recommended for every client type, not just mobile and single-page apps.