RBAC vs ABAC

RBAC attaches permissions to roles; ABAC evaluates policies over user, resource, action and environment attributes. RBAC scales with role explosion; ABAC with policy opacity. Real systems use both.

Banner

Prefer to watch? ▶ RBAC vs ABAC in 90 seconds ✈ Telegram

Authorization is a single decision gate: is this user allowed to perform this action on this resource? RBAC and ABAC both answer that question, but they model the answer in completely different ways — and mixing them up is how you end up with either a thousand near-duplicate roles or policies so tangled you can't tell who actually has access.

  • Mental model: RBAC is a static role-to-permission lookup table; ABAC is a rule engine evaluated at request time over live attributes.

RBAC: Static Roles, Simple Audit Trail

Role-Based Access Control is the simplest authorization model you can build. You define a role, attach permissions to it, and drop users into that role.

role: editor
  - publish
  - edit
  - delete

role: viewer
  - read

user: alice → editor
user: bob → viewer

This is genuinely powerful in its simplicity. An auditor can open one table and immediately see that Alice is an editor and therefore can publish, edit, and delete. There is no simulation, no contradiction, no hidden state. You know exactly who can do what because it's written in a static mapping.

RBAC works brilliantly for coarse-grained boundaries: is this user a customer or an admin? Can they see the billing page or not?

The Cost: Role Explosion

The moment your authorization rules become contextual, RBAC collapses into absurdity.

Suppose editors can only publish their own drafts, and only within their department, and only during business hours. You cannot express this as a single editor role. So you create:

role: editor_own_dept
role: editor_own_dept_business_hours
role: editor_own_dept_business_hours_own_drafts
role: editor_eu
role: editor_eu_fin
role: editor_eu_fin_daytime

Now you have 20 roles when you started with 2. Now you have 200. Now you have 2,000. Each is a near-duplicate of the others, and nobody dares delete one because they cannot remember which user depends on it. This is role explosion — the moment every contextual condition spawns a new role, RBAC has failed.


ABAC: Attribute Policies, No Role Inflation

Attribute-Based Access Control abandons the role-permission table entirely. Instead, you write a policy — a condition evaluated at request time against live attributes of the user, the resource, the action, and the environment.

allow publish if
  user.role == "editor" and
  resource.owner_id == user.id and
  resource.department == user.department and
  now().hour >= 9 and now().hour < 17

Added a new rule? Do not create a new role. Write one more condition. The policy engine evaluates the entire ruleset every time, and decides yes or no.

ABAC is genuinely flexible. You can express almost any authorization rule without spawning a new role for every edge case.

The Cost: Opacity and Silent Failure

The moment you gain flexibility, you lose auditability.

A simple question — "Can Alice delete this document?" — now requires:

  1. Simulation. You cannot read off a table. You must run every policy rule against live data: what is Alice's department? Who owns the document? What time is it?
  2. Contradictions. Policies overlap. One policy says "finance can read every document in their department." Another says "only the document owner can read drafts." When Alice (finance, draft owner) tries to read someone else's draft, which rule wins?
  3. Silent failure. One stale attribute can grant access you never intended. If the systems that compute user.department lag or return a wrong value, authorization silently succeeds or fails based on stale data.

ABACis powerful but opaque. An auditor cannot read "who can do what" off a table anymore. They must trace through every policy, simulate every condition, and hope they did not miss a contradiction.


Head-to-Head Comparison

DimensionRBACABAC
ModelStatic role-to-permission lookup tableRule engine evaluated over live attributes
Adding a contextual ruleCreate a new role (role explosion)Add a condition to a policy (no new role)
AuditabilityHigh. "Who can do what?" is a simple table lookup.Low. You must simulate every policy against live data.
Operational overheadRole management becomes heavy when you have hundreds of rolesPolicy management is lighter, but policy contradictions are hard to spot
Failure modeYou know which user is in which role; the worst case is a user with too much accessA stale attribute silently grants or denies access; you may not know why
PerformanceLookup is O(1): user → roles → permissionsEvaluation cost depends on policy count and attribute availability; can require multiple service calls

The Real Answer: Layer RBAC and ABAC

You do not choose between them. Real production systems use both.

Start with RBAC as the coarse gate. Is this user an admin, an editor, a viewer? That is a role. You drop users into roles and cache it aggressively.

Then layer ABAC-style conditions on top for the fine-grained rules. Within the editor role, can this editor edit this document? Evaluate that as an attribute policy: user.id == doc.owner_id and doc.department == user.department.

allow edit if
  user.role == "editor" and           # coarse gate (RBAC)
  user.id == document.owner_id and    # fine-grained (ABAC)
  user.department == document.dept    # fine-grained (ABAC)

This gives you the best of both worlds:

  • The coarse gate is still auditable. "Editors can edit" is clear.
  • Contextual rules do not spawn new roles. You add conditions, not roles.
  • You evaluate the expensive attribute checks only after the coarse gate passes, so you do not run policies for viewers or admins.

The LLM Angle: Inference Time vs. Latency

If you are serving authorization decisions through an LLM inference engine (for example, a policy-generation model that evaluates whether a token or request is authorized), the choice between RBAC and ABAC becomes a latency problem.

RBAC is TTFT-friendly. The first token (the authorization decision) arrives immediately — a simple table lookup. You get time-to-first-token in microseconds.

ABAC is throughput-heavy. Evaluating policies over attributes may require multiple service calls or attribute lookups before you can emit a decision. You pay latency for flexibility. If you are batching authorization decisions (evaluating many policies in parallel), ABAC amortizes that cost better — higher tokens-per-second overall, but higher latency per single request.

In practice, the hybrid approach (RBAC gate + ABAC conditions) minimizes this cost: the coarse role check is a TTFT hit (immediate), and the fine-grained attribute evaluation is deferred or cached.


Verdict

Reach for pure RBAC when your authorization rules are stable and coarse (admin vs. user, editor vs. viewer). Reach for ABAC when rules are deeply contextual and attributes change frequently. In almost every real system, start with RBAC as the gate and layer ABAC conditions on top for context.

Watch the 90-second reel to see this concept in motion.

RBAC vs ABAC | Vahid Aghajani