GoodNotes Architect Journal
🏠 Index 1. Single Server 2. Selecting DB 3. Relational & SQL 4. ACID Integrity 5. NoSQL Types 6. Scaling Guide 7. Load Balancing 8. SPOF & HA 9. API Design 10. Comm Protocols 11. TCP & UDP 12. REST Design 13. GraphQL Architecture 14. Authentication Protocols 15. JWT & OAuth 2 16. Authorization Models
System Design Chapter 16

Authorization Strategies: RBAC, ABAC, ACL & Token Enforcement

What Are They Allowed to Do? RBAC Roles, ABAC Policies, Resource ACLs, OAuth 2 Delegation & JWT Enforcement

★ Tokens only carry claims and identity! The token doesn't decide what is allowed — your backend policy engine does.

1 The Core Paradigm: “What are they allowed to do?”

“
Authentication verifies identity ('Who are you?'). Authorization determines access rights ('What resources and actions are you permitted to execute?').
— System Design Axiom

Every secure distributed system enforces a strict boundary between Identity Verification and Permission Enforcement. Authentication must happen first; once the user’s identity is cryptographically validated, the system queries its authorization model to evaluate whether the requested operation is permitted.

🛡️ The Complete Request Authorization Pipeline

📥 Incoming Client Request (Credentials / Bearer JWT)

⬇️
🔑Phase 1: Authentication
Verify signature, unpack claims & resolve Subject ID (sub: user_123)
⬇️
⚖️Phase 2: Authorization Check
”Does user_123 have permission to perform DELETE /api/posts/99?”Evaluated against: RBAC roles, ABAC attributes, or Resource ACLs

✅ Allowed Actions

Policy permits action ➔ Forward to Business Logic & Controller.

HTTP 200 / 204 Success

🚫 Denied Actions

Policy rejects action ➔ Short-circuit request immediately.

HTTP 403 Forbidden
💡 401 Unauthorized vs. 403 Forbidden
  • 401 Unauthorized: “I don’t know who you are (or your token is missing/expired/invalid).” (Actually means unauthenticated!)
  • 403 Forbidden: “I know exactly who you are, but you are not allowed to touch this resource.” (True authorization failure!)
🔑 Real Systems Combine Models

Production enterprise platforms rarely use one model in isolation. Real architectures combine multiple models:

  • RBAC for organization-wide coarse baseline access (e.g. Admins vs Staff vs Customers).
  • ABAC / ACL for fine-grained resource checks (e.g. Can only edit documents you own or during business hours).

2 Model 1: RBAC (Role-Based Access Control)

In RBAC, permissions are not assigned directly to individual users. Instead, permissions are grouped into Roles (e.g., Admin, Editor, Viewer), and users are assigned one or more roles.

👑 Admin

Permissions: Full Superuser Access.

  • Create, Read, Update, Delete (CRUD) any resource.
  • Manage Users: Invite, deactivate, assign roles, change billing settings.
All Access

✏️ Editor

Permissions: Content Operations.

  • Create, Read, Update articles, documents, media assets.
  • Cannot manage users, edit tenant billing, or alter global workspace security settings.
Write & Read Content

👀 Viewer

Permissions: Read-Only Access.

  • Read Only: Browse records, view dashboards, download generated reports.
  • Cannot create draft posts, modify records, or trigger mutation endpoints.
Read Only
🏢 Real-World RBAC Architecture in Modern Dashboards
Where RBAC is standard in industry:
  • Stripe Dashboards: Administrator, Developer, Analyst, Support Specialist, View-Only.
  • CMS Platforms (WordPress, Contentful): Super Admin, Editor, Author, Contributor, Subscriber.
  • B2B SaaS Multi-Tenant Workspaces: Workspace Owner, Member, Guest.
Express.js RBAC Middleware Pattern
// Express.js declarative RBAC guard
function requireRole(...allowedRoles: string[]) {
  return (req: Request, res: Response, next: NextFunction) => {
    const user = req.user; // populated by JWT verification middleware
    if (!user) {
      return res.status(401).json({ error: "Unauthenticated" });
    }

    const hasRole = user.roles.some((role) => allowedRoles.includes(role));
    if (!hasRole) {
      return res.status(403).json({ 
        error: "Forbidden: Insufficient privileges",
        required: allowedRoles,
        actual: user.roles 
      });
    }

    next();
  };
}

// Protected route binding
app.delete("/api/v1/users/:id", requireRole("admin"), deleteUserHandler);
app.post("/api/v1/posts", requireRole("admin", "editor"), createPostHandler);
app.get("/api/v1/posts", requireRole("admin", "editor", "viewer"), listPostsHandler);
⚠️ The “Role Explosion” Bottleneck:

As organizations grow, pure RBAC breaks down. What happens when an editor can edit documents, but only if the document is in draft mode, in their region, and during business hours? You are forced to invent hundreds of hyper-specific roles like Editor_US_East_DraftOnly_Weekday. This is where ABAC solves the problem.

3 Model 2: ABAC (Attribute-Based Access Control)

Rather than evaluating static role names, ABAC dynamically evaluates policies based on contextual attributes across three primary dimensions: the Subject (User), the Resource, and the Environment.

👤 User Attributes

  • department (e.g. “HR”, “Finance”)
  • age / employmentType
  • clearanceLevel (e.g. Level-3)
  • organizationId

📄 Resource Attributes

  • confidentiality (e.g. “internal”, “top-secret”)
  • ownerId (e.g. “user_123”)
  • classification / projectTag
  • status (e.g. “published” vs “draft”)

🌐 Environment Attributes

  • timeOfDay (e.g. current_time < 18:00)
  • ipLocation / geoCountry
  • deviceType (e.g. Corporate Laptop vs Unknown Mobile)
  • tlsVersion / VPN connection state
📜 ABAC Policy Evaluation Engine

📝 Example Policy from Real World (Handwritten Note):

allow = (user.department == “HR”) && (time < 18:00) && (resource.confidentiality == “internal”)

1. Request Intercepted

User attempts action on target object

2. Fetch Attributes

Enrich with DB metadata & clock/IP info

3. Policy Evaluator

Execute Boolean expression rules

4. Grant or Deny

200 OK or 403 Forbidden

✨ Advantages
  • Tremendous flexibility. No need to invent new roles for business conditions.
  • Zero role explosion. Supports contextual & time-sensitive security.
⚠️ Trade-offs
  • Requires dedicated policy management engine (e.g., Open Policy Agent).
  • Performance overhead: Fetching extra attributes adds latency per request.

4 Model 3: ACL (Access Control Lists)

In ACL, instead of attaching roles to users or writing broad attribute policies, each resource holds its own individual list of permitted subjects and their granted actions.

📁 Resource-Centric Access Control List (Google Drive Architecture)
📄
Resourcedocument_quarterly_report.pdf

Each resource owns its permission list

Subject (User)Permission
👤 AliceRead Only
👤 BobRead / Write
👤 CarolNo Access (Denied)
🌍 Canonical Real-World Example: Google Drive & AWS S3 Object ACLs

When you click “Share Document” in Google Drive and type a specific colleague’s email with “Commenter” or “Editor” permissions, you are directly appending a row to that specific file’s Access Control List.

✨ Granular Precision

Unmatched fine-grained user-to-resource sharing capability. Ideal for multi-user file storage.

⚠️ Hard to Scale

Auditing is excruciating (“Show me all 100,000 files Bob can read”). Querying requires expensive joins on ACL mapping tables.

5 Authorization Models: Comparison Matrix

Choosing the right authorization model is one of the most consequential architectural decisions in database and backend design:

ModelCore ConceptGranularityBest Used ForPrimary Bottleneck
RBACUsers ➔ Roles ➔ PermissionsCoarseB2B SaaS dashboards, Stripe, CMS platformsRole explosion when nuanced business rules emerge
ABACPolicies on User, Resource & Env attributesDynamic & FineHealthcare (HIPAA), Finance, Government clearancePolicy evaluation complexity & attribute retrieval latency
ACLResource stores table of permitted subjectsUltra-GranularGoogle Drive, Dropbox, AWS S3 object sharingAuditing across resources & massive scale table joins

6 OAuth 2 Delegation: Access on Behalf of the User

“
OAuth 2 is an authorization delegation framework. It answers: 'How can a user let a third-party application access their resources without ever handing over their password?'
— OAuth 2 RFC 6749

As illustrated in page 4 of the notes, the textbook scenario is connecting Vercel to GitHub so Vercel can clone repositories and deploy code on your behalf:

🤝 The OAuth 2 Delegation Flow: Vercel & GitHub Handshake
👤
Resource Owner
The User
▲
Client Application
Vercel Service
🐙
Authorization Server
GitHub OAuth API
1. User Requests Access / Connect AccountUser ➔ Vercel

The user clicks “Connect GitHub” on the Vercel dashboard.

2. Redirect to Consent Screen with ScopesVercel ➔ GitHub Consent

GitHub presents consent modal: “Vercel wants permission to read:repo, read:user”. Notice it explicitly does not request delete:repo!

3. Authorization Code GrantGitHub ➔ Vercel

User clicks “Authorize”. GitHub redirects back with a short-lived, single-use authorization_code.

4. Secure Token Exchange (Backend-to-Backend)Vercel Backend ➔ GitHub

Vercel trades the code + client_secret for a scoped Access Token.

📌 Critical Rules from Handwritten Notes:
  • Access Token is given (Not Password): Vercel never knows your GitHub master password.
  • Scoped Access: The token only represents the exact permissions you approved (e.g. read:repo, not delete:repo).
  • GitHub never shares your password: If Vercel is compromised, your GitHub account credentials remain completely secure. Revoking access takes 1 click.
  • OAuth 2 defines the secure token issuance flow: It is an industry-standard authorization framework.

7 Token-Based Authorization: JWT Claims & Enforcement

In distributed microservices, we don’t query a database for every single user privilege check. Instead, we use Token-Based Authorization where cryptographically signed tokens (JWTs) carry identity claims and scopes directly to downstream services.

📦 Anatomy of an Authorization JWT (Bearer Token)

👤 User

➔ Request with Bearer Token ➔

🎟️ JWT Token

➔ Evaluated at ➔

🖥️ Server Backend

📋 Decoded JWT Payload (From Handwritten Note)

Claims & Scopes
// Subject Identity
”sub”: “user-123”,
// RBAC Roles
”roles”: [“admin”, “editor”],
// OAuth2 Scopes
”scopes”: [“read:posts”, “write:posts”],
// Expiration & Issuer
”exp”: 1774892400, // 24 hours
”iss”: “https://auth.example.com”

⭐ The Key Distinction (The Golden Rule of AuthZ)

“Token carries identity and claims, and authorization models define what is allowed.
Tokens are just the transport mechanism. They don’t make decisions — your backend does.”

8 Production Scale: PEP / PDP & Google Zanzibar (ReBAC)

In high-scale enterprise architectures, mixing authorization logic directly inside endpoint handler code creates spaghetti code. Standard engineering patterns decouple policy evaluation into dedicated architectural layers:

🛡️ PEP (Policy Enforcement Point)

The guard at the gate (API Gateway, reverse proxy, or HTTP middleware). It intercepts incoming requests, extracts tokens, asks the PDP for a verdict, and strictly denies (403) or permits the request.

🧠 PDP (Policy Decision Point)

The brain. A dedicated engine (such as Open Policy Agent / OPA) that executes compiled declarative logic (like Rego) against attributes and inputs to return a pure Boolean allow: true.

🕸️ ReBAC & Google Zanzibar

Relationship-Based Access Control. Used by Google (Drive, YouTube, Cloud) to handle billions of ACLs. Instead of tables, permissions are modeled as graph relation tuples (e.g. doc:42#viewer@user:alice).

🏛️ Centralized vs Distributed Authorization Engines

🚀 OPA / Rego Sidecar Engine

Each microservice runs a local Open Policy Agent sidecar process in memory. Zero network hop latency when evaluating ABAC/RBAC rules!

default allow = false
allow {
  input.method == “GET”
  input.user.roles[_] == “viewer”

}

🌐 Google Zanzibar Graph Store

Solves deep nested group memberships (e.g. “Alice is in Team A which is inside Org B which has viewer rights on Folder C containing File D”).

Check(User, Relation, Object)
➔ Evaluates graph traversal in <10ms at global scale.

9 Quick Revision & Interview Takeaways

1. AuthN vs AuthZ

AuthN: Who are you? (401 if missing/invalid).
AuthZ: What can you do? (403 if forbidden).

2. The 3 Core Models
  • RBAC: Roles map to permissions (Stripe, CMS).
  • ABAC: User + Resource + Env rules (HR < 6PM).
  • ACL: Per-file subject permission lists (Google Drive).
3. OAuth 2 Delegation

Never give your password to third parties. Tokens grant specific, revocable scopes (e.g. read:repo).

4. The Token Axiom

A JWT is just the carrier of claims. Your backend decision engine (PDP) decides whether the operation is permitted!