Authorization: RBAC, ABAC, Permissions and Policy Engines
Design authorization for distributed systems: RBAC, ABAC, scopes, policy engines, permission checks, multi-tenancy, and security tradeoffs.
Quick answer: Authorization: RBAC, ABAC, Permissions and Policy Engines
Authorization: RBAC, ABAC, Permissions and Policy Engines is covered here as a practical system design concept. Design authorization for distributed systems: RBAC, ABAC, scopes, policy engines, permission checks, multi-tenancy, and security tradeoffs. Use it to understand the APIs idea, where it appears in production systems, and how to discuss it clearly in interviews.
Focus on the problem being solved, the main design choice, the failure mode, and the tradeoff you would defend in front of a senior engineer. This page is part of the DosiBridge system design knowledge graph, so it links related concepts, interview problems, tradeoffs, and references instead of leaving the topic isolated.
Authorization answers: what are you allowed to do? After authentication confirms identity, authorization enforces permissions. In a monolith, a simple role check suffices. In microservices, you need a consistent policy engine that every service queries — otherwise each team implements its own rules and access control becomes unpredictable. The three dominant models are RBAC (role-based), ABAC (attribute-based), and ReBAC (relationship-based, used by Google Zanzibar).
| Aspect | Details |
|---|---|
| What it is | The process of determining what actions an authenticated user is permitted to perform on which resources |
| When to use | Any multi-user system, multi-tenant SaaS, API access control, data isolation between customers |
| When NOT to use | Single-user applications or internal tools where all users need the same level of access |
| Real-world example | Google Zanzibar handles authorization for Google Drive, YouTube, and Cloud IAM — trillions of checks per second |
| Interview tip | Always separate authentication from authorization — they are different concerns with different solutions |
| Common mistake | Hardcoding permission checks (if user.role == 'admin') throughout the codebase instead of using a policy engine |
| Key tradeoff | Granularity vs performance — fine-grained permissions are more secure but require more checks per request |
Why This Matters
Authorization failures are the second most common web vulnerability (OWASP A01:2021 Broken Access Control). In multi-tenant SaaS, one tenant seeing another's data is a company-ending bug. In microservices, authorization logic scattered across 50 services is impossible to audit. Centralizing authorization in a policy engine (OPA, Cedar, SpiceDB) lets you enforce consistent rules, audit who accessed what, and change permissions without redeploying code.
The Building Blocks
- RBAC (Role-Based Access Control): Users are assigned roles (admin, editor, viewer), roles have permissions. Simple, widely understood, works for 80% of applications. Breaks down when permissions depend on resource ownership.
- ABAC (Attribute-Based Access Control): Permissions depend on attributes of the user, resource, action, and context. Example: 'managers can approve expenses under $10,000 during business hours.' More flexible than RBAC but harder to reason about.
- ReBAC (Relationship-Based Access Control): Permissions defined by relationships between objects. Google Zanzibar: 'user:alice is editor of doc:readme, editors can view.' Natural for document/file sharing systems.
- Policy Engine: A dedicated service that evaluates authorization decisions. OPA (Open Policy Agent) uses Rego language, AWS Cedar uses a typed policy language. Decouples policy from code.
- Permission Propagation: In microservices, the API gateway validates authentication and attaches user claims/roles. Downstream services make local authorization decisions based on those claims without calling back to the auth service.
Under the Hood
When a request arrives, the API gateway extracts the user's identity from the JWT and enriches it with roles/groups (cached from the identity provider). It forwards the request with these claims to the target service. The service calls the policy engine: "Can user X perform action Y on resource Z?" The policy engine evaluates the request against stored policies and returns allow/deny.
For performance, authorization decisions are cached. Google Zanzibar uses a distributed cache with a consistency model — it guarantees that permission changes propagate within a bounded time (called "zookies" for consistency tokens). In simpler systems, caching RBAC role lookups in Redis with a 5-minute TTL balances performance and freshness.
The critical design decision is where to enforce authorization. Gateway-level enforcement (coarse: can this user access this API?) catches most unauthorized requests cheaply. Service-level enforcement (fine: can this user edit THIS document?) handles resource-specific permissions. Most systems need both layers.
How Companies Actually Do This
Google built Zanzibar to handle authorization for Drive, YouTube, Cloud IAM, and Maps. It serves trillions of authorization checks per second with single-digit millisecond latency using a global distributed graph.
AWS implements authorization through IAM policies — JSON documents that define who can do what on which resources. Every AWS API call is authorized through IAM, processing billions of decisions daily.
Airbnb uses a centralized authorization service called Himeji, built on SpiceDB (open-source Zanzibar). It handles complex relationships: host owns listing, guest booked listing, co-host manages listing.
Common Pitfalls
- Scattering authorization checks across services with inconsistent logic — one service allows access that another denies for the same user
- Checking only roles without verifying resource ownership — a user with 'editor' role should only edit THEIR documents, not all documents
- Not logging authorization denials — failed access attempts are critical security signals for detecting brute-force or privilege escalation attacks
Interview Questions Worth Practicing
- How would you design an authorization system for a multi-tenant SaaS platform?
- What are the tradeoffs between RBAC and ABAC, and when would you choose each?
- How does Google Zanzibar achieve consistent authorization at global scale?
The Tradeoffs
- RBAC Simplicity vs ABAC Flexibility: RBAC is easy to understand and audit but cannot express context-dependent rules. ABAC handles complex scenarios but policies become hard to reason about at scale.
- Centralized vs Distributed Enforcement: A central policy engine ensures consistency but adds latency. Distributed enforcement (cached policies) is faster but risks stale permissions.
- Granularity vs Performance: Object-level permissions (can user edit THIS row?) are the most secure but require a check per object. Role-level permissions are faster but coarser.
How to Explain This in an Interview
Here is how I would explain Authorization in a system design interview:
Authorization decides what a user can do after authentication confirms who they are. I would implement it in two layers: the API gateway enforces coarse checks (does this user's role allow access to the /admin endpoints?), and individual services enforce fine-grained checks (can this user edit THIS specific document?). For the policy engine, I would use RBAC for most resources since it covers 80% of cases simply. For complex sharing scenarios (like Google Docs), I would use a relationship-based model similar to Zanzibar — define permissions as relationships (user:alice is editor of doc:X) and traverse the graph. I would cache authorization decisions in Redis with short TTLs and log every denial for security auditing.
Related Topics
Original DosiBridge notes for Authorization: RBAC, ABAC, Permissions and Policy Engines
This section is written specifically for this page, not copied from a general system-design checklist. The useful way to study Authorization: RBAC, ABAC, Permissions and Policy Engines is to connect the concept to a trust boundary where convenience must not weaken identity, confidentiality, or auditability. That framing changes the design discussion from definitions to operating choices.
What makes this topic distinct
- Contract Evolution: For Authorization: RBAC, ABAC, Permissions and Policy Engines, decide the contract evolution before choosing tools; otherwise the design looks clean but fails when authorization changes.
- Idempotency: For Authorization: RBAC, ABAC, Permissions and Policy Engines, decide the idempotency before choosing tools; otherwise the design looks clean but fails when authorization changes.
- Pagination: For Authorization: RBAC, ABAC, Permissions and Policy Engines, decide the pagination before choosing tools; otherwise the design looks clean but fails when authorization changes.
- Error Shape: For Authorization: RBAC, ABAC, Permissions and Policy Engines, decide the error shape before choosing tools; otherwise the design looks clean but fails when authorization changes.
- Consumer Compatibility: For Authorization: RBAC, ABAC, Permissions and Policy Engines, decide the consumer compatibility before choosing tools; otherwise the design looks clean but fails when authorization changes.
Production review question
If a team adopts Authorization: RBAC, ABAC, Permissions and Policy Engines, what observable signal proves it helped instead of only making the architecture diagram more fashionable?
Practical metric to track
Track authorization health as a named dashboard or review item: combine one user-facing metric, one saturation metric, and one correctness metric. For Authorization: RBAC, ABAC, Permissions and Policy Engines, this keeps the discussion grounded in behavior that can be measured after deployment instead of generic advice that sounds good in an interview but never gets verified.