Skip to main content

Authorization Models

Control what users can do with role, attribute, relationship & policy approaches

TL;DR

RBAC (Role-Based): User has role (admin, editor, viewer); role has permissions. Simple, scalable, works for most apps. ABAC (Attribute-Based): Decisions based on attributes (user dept=finance, resource level=confidential, time=business hours). Fine-grained but complex. ReBAC (Relationship-Based): User can access resource if relationship exists (user is document owner, or in shared group). Modern, graph-based. PBAC (Policy-Based): Explicit policies define access (if user.dept=="finance" and resource.type=="ledger", allow read). Pick based on granularity needs.

Learning Objectives

  • Understand RBAC strengths and limitations
  • Implement ABAC for fine-grained control
  • Use ReBAC for collaborative access patterns
  • Write clear authorization policies
  • Audit and enforce least privilege

Motivating Scenario

Problem: A medical app needs fine-grained access. Doctor can view patient records only if: (1) patient assigned to doctor, (2) patient consented, (3) viewing during business hours, (4) doctor has valid license, (5) record not sealed by court order. Simple RBAC (role=doctor → can view) fails.

Solution: Use PBAC or ABAC. Policies enforce all conditions. ReBAC handles patient-to-doctor relationships. ABAC checks attributes (license status, time). Result: Flexible, auditable, compliant.

Core Concepts

RBAC (Role-Based Access Control)

Users assigned to roles. Roles have permissions.

User: alice
Roles: [admin, editor]

Role: admin
Permissions: [create_user, delete_user, view_audit]

Role: editor
Permissions: [create_post, edit_post, delete_own_post]

alice can: create_user, delete_user, view_audit, create_post, edit_post, delete_own_post

Strengths:

  • Simple to understand and implement
  • Scales to many users (add user to role, done)
  • Clear separation of duties

Limitations:

  • Can't express complex conditions (time, location, resource attributes)
  • Role explosion (need admin_finance, admin_hr, admin_sales...)
  • Difficult to express "user can edit only their own posts"

ABAC (Attribute-Based Access Control)

Decisions based on attributes of user, resource, environment.

User: alice
Attributes: { dept: "finance", level: 5, license_valid: true }

Resource: ledger_2025
Attributes: { type: "financial", sensitivity: "confidential", owner_dept: "finance" }

Environment: { time: "2025-02-14T14:00:00", location: "office" }

Policy:
IF user.dept == resource.owner_dept
AND user.level >= 3
AND user.license_valid == true
AND env.time IN business_hours
THEN allow read

Strengths:

  • Highly flexible and expressive
  • Handles dynamic attributes
  • Minimal role explosion

Limitations:

  • Complex to author and maintain
  • Performance impact (many attributes to evaluate)
  • Harder to audit ("why was access denied?")

ReBAC (Relationship-Based Access Control)

Access determined by relationships in a graph.

User: alice
Resources: [doc1, doc2, team_project]

Relationships:
- alice OWNS doc1
- alice MEMBER_OF team_project
- team_project OWNS doc2

Policy:
- Owner can delete
- Team member can edit if team owns resource

Result:
- alice can delete doc1 (owner)
- alice can edit doc2 (member of team that owns it)

Strengths:

  • Natural for collaborative systems
  • Scales with relationships, not explosion of rules
  • Easy to reason about ("who has access?")
  • Tools: Google Zanzibar (inspiration), Auth0 FGA, Ory Keto

Limitations:

  • Requires relationship storage and query
  • Can be slow for complex relationship chains

PBAC (Policy-Based Access Control)

Explicit policies define access.

{
"resource": "s3://bucket/sensitive",
"actions": ["s3:GetObject"],
"principal": "arn:aws:iam::123456789:role/DataAnalyst",
"conditions": {
"StringEquals": {
"aws:PrincipalOrgID": "org-123"
},
"IpAddress": {
"aws:SourceIp": ["10.0.0.0/8"]
}
},
"effect": "Allow"
}

Strengths:

  • Clear, explicit, auditab le
  • Widely used (AWS IAM, Google Cloud IAM)
  • Conditions can be very specific

Limitations:

  • Policy explosion (many similar policies)
  • Hard to query ("what can user do?")
  • Easy to introduce contradictions

Practical Examples

// Simple RBAC in Node.js
const roles = {
admin: ['read', 'write', 'delete', 'manage_users'],
editor: ['read', 'write', 'delete'],
viewer: ['read']
};

const userRoles = {
alice: ['admin'],
bob: ['editor'],
charlie: ['viewer']
};

function canDo(userId, action) {
const roles = userRoles[userId];
for (const role of roles) {
if (roles[role]?.includes(action)) {
return true;
}
}
return false;
}

canDo('alice', 'delete'); // true (admin)
canDo('bob', 'manage_users'); // false (editor lacks permission)

When to Use / When Not to Use

Use RBAC When
  1. Simple permission structure
  2. Roles map to org structure
  3. Few roles needed
  4. Admin/editor/viewer pattern
  5. Simplicity preferred over granularity
Use ABAC When
  1. Fine-grained control needed
  2. Many attributes vary (time, location, data sensitivity)
  3. Dynamic attribute evaluation required
  4. Few users but complex rules
  5. Willing to invest in policy engine
Use ReBAC When
  1. Collaborative, owner-based access
  2. Sharing (users, teams, orgs)
  3. Graph-like relationships
  4. Google Docs-style permissions
  5. Scalable relationship queries needed
Use PBAC When
  1. Explicit, auditable policies needed
  2. Cloud platforms (AWS, GCP)
  3. Fine-grained cross-cutting conditions
  4. Regulatory requirements
  5. Willing to manage policy lifecycle

Patterns and Pitfalls

Pattern: Start with RBAC; evolve to ABAC or ReBAC as needs grow.

Pitfall: Role explosion. Instead of admin, admin_finance, admin_hr, admin_sales → use ABAC (admin + dept attribute).

Pattern: Least privilege by default. Deny all, whitelist access. ("default deny")

Pattern: Separate "who decides?" from "who executes?". Admin approves deletion; system enforces it.

Pitfall: Authorization checks scattered in code. Centralize in middleware or policy service.

Pattern: Test authorization rules. Example: "user X with role Y should access resource Z" → automated test.

Design Review Checklist

  • Authorization model chosen (RBAC, ABAC, ReBAC, PBAC)
  • Least privilege principle applied
  • All sensitive resources require explicit authorization
  • Separation of duties enforced (check/approve/execute)
  • Default deny policy in place
  • Authorization decisions centralized (not scattered)
  • Audit logs capture authorization decisions
  • Regular access reviews conducted
  • Role/permission definitions documented
  • Tests validate authorization rules

Self-Check

  • When would RBAC alone be insufficient?
  • How would you model "user can edit only their own posts" in RBAC?
  • Why is ReBAC powerful for sharing systems?
One Takeaway

Choose authorization model based on complexity: start RBAC (simple), evolve to ABAC/ReBAC (flexible), use PBAC for explicit audit trail.

Next Steps

  • Read Session & Token Management for enforcing authorization in stateless systems
  • Study Least Privilege for detailed access control principles
  • Explore Audit Logging for verifying authorization compliance

References

  • NIST SP 800-192: Access Control (RBAC, ABAC)
  • ABAC in Cloud Identity (AWS IAM, GCP Identity & Access)
  • Google Zanzibar: Rethinking Authorization (ReBAC foundation)
  • OWASP Authorization Cheat Sheet