SystemDesign.website
Track 8 ยท Module 8.3Security & Access Control

Authorization: ACL, RBAC, ABAC & ReBAC

How enterprise distributed systems enforce granular permissions: the progression from simple Access Control Lists (ACL) to Role-Based (RBAC), Attribute-Based (ABAC), Google Zanzibar Relationship-Based Access Control (ReBAC), and Open Policy Agent (OPA) policy decoupling.

โฑ๏ธ Estimated Reading: 30 minsโ€ขPrerequisites: Modules 8.1 & 8.2โ€ขInteractive Lab: Multi-Model Auth Engine
๐Ÿฅ REAL-WORLD ANALOGY ยท THE HOSPITAL ACCESS SYSTEM

1. The Evolution of Authorization: A Hospital Analogy

Authentication proves who you are (Alice, an employee). Authorization answers what you are allowed to touch right now. To understand how authorization models evolved, imagine designing the physical security system for a major metropolitan hospital:

1. Access Control List (ACL)

Analogy: A physical paper clipboard taped to the door of Room 402 with names: [Alice: Read, Bob: Write].

โš ๏ธ Fails at scale: When Alice leaves the hospital, you must walk to 10,000 doors to erase her name from 10,000 paper clipboards.

2. Role-Based Access Control (RBAC)

Analogy: Color-coded badges. Anyone with a Doctor badge can enter any examination room; Nurses can enter supply closets.

โš ๏ธ Fails on context: Cannot express “Dr. Alice can only access Room 402 if she is currently on shift AND assigned to Patient Charlie”. Leads to Role Explosion!

3. Attribute-Based Access Control (ABAC)

Analogy: Smart biometric locks evaluating dynamic rules: IF (User.Role == "Doctor" AND User.Dept == Room.Dept AND Time BETWEEN 08:00-20:00 AND IP IN HospitalWiFi) THEN UNLOCK.

โœ… Highly expressive: Context-aware security without creating thousands of static roles.

4. Relationship-Based (ReBAC / Zanzibar)

Analogy: Google Drive sharing graph: Alice → MemberOf(Cardiology Team) → ViewerOf(Folder Patient 402) → InheritsAccess(LabResults.pdf).

โœ… Gold standard for SaaS: Handles deep nested folder sharing, user-to-user delegation, and group inheritance.

๐Ÿ“Š COMPARATIVE MATRIX

2. Architecture Comparison Matrix

ModelCore Data StructureBest Suited ForPrimary Architectural Trade-off
ACL(ResourceID, UserID, Permissions)Simple file systems, single-tenant toolsO(N) management cost; impossible reverse lookup ("What can Alice see?")
RBACUser → Role → PermissionsInternal admin tools, standard SaaS tiersRole Explosion: Creating thousands of hyper-specific roles for minor exceptions
ABACBoolean Policy (Subject, Object, Action, Env)Fintech, Healthcare, Zero-Trust EnterpriseHigher evaluation latency (CPU rule evaluation per request)
ReBAC(Object#Relation@Subject) Graph TuplesGoogle Docs/Drive, Figma, GitHub OrganizationsRequires specialized graph database / Zanzibar index cluster
๐Ÿ›ก๏ธ ARCHITECTURE PATTERN ยท OPA

3. Policy Decoupling & Open Policy Agent (OPA)

A critical anti-pattern in microservices is hardcoding authorization rules directly into controller business logic:

โŒ Hardcoded Anti-Pattern

if user.role == "doctor" and user.dept == patient.dept:
    if request.is_emergency or (time.now().hour >= 8 and time.now().hour <= 20):
        return allow_access()
        

Modifying a security policy requires recompiling, testing, and redeploying 25 different microservices across the company.

โœ… Decoupled Policy Engine (OPA)

# Open Policy Agent (Rego Policy)
default allow = false
allow {
    input.user.role == "doctor"
    input.user.department == input.patient.department
    is_valid_shift(input.time)
}
        

Security teams update policies declaratively in Git. Microservices query OPA sidecars in <1ms via local UNIX sockets.

Policy Enforcement Point (PEP) vs Policy Decision Point (PDP)
Client / MobilePOST /patients/402Microservice (PEP)Policy Enforcement Point1. Intercept Request2. Query OPA SidecarOPA Sidecar (PDP)Policy Decision PointRego Policy EngineEvaluates in <0.8msQuery (JSON)allow: true
๐ŸŒ DISTRIBUTED SYSTEMS SCALE

4. Google Zanzibar & Relationship-Based Access Control (ReBAC)

How does Google determine if you can view a Google Doc shared with an email group inside a subfolder owned by an organization? They built Zanzibar: a globally distributed authorization system storing trillions of relation tuples.

Zanzibar Relation Tuple Notation:
object#relation@user
doc:design_spec#owner@alice
Alice is the owner of design_spec.
folder:engineering#viewer@group:devs
Devs group can view folder.
doc:design_spec#parent@folder:engineering
Doc inherits folder permissions.
๐Ÿงช LIVE AUTHORIZATION LAB

5. Interactive Multi-Model Authorization Simulator

Configure request attributes and switch between authorization models (ACL, RBAC, ABAC, ReBAC) to see how different authorization paradigms evaluate access in real-time.

ACL Engine
ALLOW
Explicit match on document ACL sheet.
RBAC Engine
ALLOW
Role 'Doctor' has global read permission.
ABAC (OPA) Engine
ALLOW
Matches: Dept == Cardio && Shift == Day.
ReBAC (Zanzibar)
ALLOW
User in Team → Team owns Folder → Inherited.
๐Ÿ’ป PRODUCTION PATTERNS ยท CODE TEMPLATES

6. Policy Decision Engine in 5 Languages

Below is an implementation of a dynamic Attribute-Based Access Control (ABAC) evaluation engine enforcing context rules.

abac_policy_evaluator
from typing import Dict, Any

class AbacPolicyEngine:
    @staticmethod
    def evaluate(subject: Dict[str, Any], resource: Dict[str, Any], action: str, env: Dict[str, Any]) -> bool:
        # Rule 1: Superadmins always have full access
        if subject.get("role") == "superadmin":
            return True

        # Rule 2: Doctors can view records in their own department during working hours
        if action == "read" and subject.get("role") == "doctor":
            dept_match = subject.get("department") == resource.get("department")
            time_valid = 8 <= env.get("hour", 0) <= 20
            ip_valid = env.get("is_trusted_network", False)
            if dept_match and time_valid and ip_valid:
                return True

        # Rule 3: Emergency override mode
        if env.get("is_emergency", False) and subject.get("role") in ["doctor", "nurse"]:
            return True

        return False
        
interface Subject {
  id: string;
  role: string;
  department: string;
}

interface Resource {
  id: string;
  department: string;
  sensitivity: 'public' | 'confidential' | 'restricted';
}

interface Environment {
  hour: number;
  isTrustedNetwork: boolean;
  isEmergency?: boolean;
}

export class AbacEngine {
  static evaluate(sub: Subject, res: Resource, action: string, env: Environment): boolean {
    if (sub.role === 'superadmin') return true;

    if (action === 'read' && sub.role === 'doctor') {
      const isDeptMatch = sub.department === res.department;
      const isDayShift = env.hour >= 8 && env.hour <= 20;
      return isDeptMatch && isDayShift && env.isTrustedNetwork;
    }

    if (env.isEmergency && ['doctor', 'nurse'].includes(sub.role)) {
      return true;
    }

    return false;
  }
}
        
package main

type Subject struct {
	ID         string
	Role       string
	Department string
}

type Resource struct {
	ID         string
	Department string
}

type Environment struct {
	Hour             int
	IsTrustedNetwork bool
	IsEmergency      bool
}

func EvaluateABAC(sub Subject, res Resource, action string, env Environment) bool {
	if sub.Role == "superadmin" {
		return true
	}
	if action == "read" && sub.Role == "doctor" {
		if sub.Department == res.Department && env.Hour >= 8 && env.Hour <= 20 && env.IsTrustedNetwork {
			return true
		}
	}
	if env.IsEmergency && (sub.Role == "doctor" || sub.Role == "nurse") {
		return true
	}
	return false
}
        
public class AbacEngine {
    public record Subject(String id, String role, String department) {}
    public record Resource(String id, String department) {}
    public record Environment(int hour, boolean isTrustedNetwork, boolean isEmergency) {}

    public static boolean evaluate(Subject sub, Resource res, String action, Environment env) {
        if ("superadmin".equals(sub.role())) return true;
        
        if ("read".equals(action) && "doctor".equals(sub.role())) {
            boolean deptMatch = sub.department().equals(res.department());
            boolean timeValid = env.hour() >= 8 && env.hour() <= 20;
            return deptMatch && timeValid && env.isTrustedNetwork();
        }
        
        if (env.isEmergency() && ("doctor".equals(sub.role()) || "nurse".equals(sub.role()))) {
            return true;
        }
        
        return false;
    }
}
        
#include <string>

struct Subject {
    std::string id;
    std::string role;
    std::string department;
};

struct Resource {
    std::string id;
    std::string department;
};

struct Environment {
    int hour;
    bool is_trusted_network;
    bool is_emergency;
};

bool evaluate_abac(const Subject& sub, const Resource& res, const std::string& action, const Environment& env) {
    if (sub.role == "superadmin") return true;

    if (action == "read" && sub.role == "doctor") {
        bool dept_match = (sub.department == res.department);
        bool time_valid = (env.hour >= 8 && env.hour <= 20);
        return dept_match && time_valid && env.is_trusted_network;
    }

    if (env.is_emergency && (sub.role == "doctor" || sub.role == "nurse")) {
        return true;
    }

    return false;
}
        
๐ŸŽฏ ARCHITECTURE INTERVIEW SCENARIOS

7. Authorization Architecture Quizzes

Scenario 1: An enterprise cloud platform starts with 4 simple roles: 'Admin', 'Editor', 'Viewer', 'Billing'. Over 2 years, enterprise customers demand permissions like 'Editor-US-East-Only', 'Viewer-Night-Shift', and 'Billing-Department-Finance', causing the database to balloon to 3,500 distinct role definitions. What architectural problem is this, and what is the standard solution?

Scenario 2: You are designing a collaborative cloud design tool like Figma or Google Drive where users can create arbitrary folders, invite teams, share individual files with view/edit rights, and inherit folder permissions hierarchically. Which authorization model is the industry standard for this use case?

โ—‹

Completed this module?

Mark as finished to update your curriculum progress tracker.