What Is Authorization?
The complete beginner-to-production guide to how systems decide what you're allowed to do — not just who you are.
Imagine you walk into a large office building. At the front desk, a security guard checks your ID card and confirms you are really you — that’s the front door. But once you’re inside, you can’t just wander into every room. The guard’s badge system also decides which floors your keycard opens, which doors buzz you through, and which ones stay locked no matter how hard you push. That second part — deciding what you’re allowed to touch, see, or change once your identity is already confirmed — is called authorization. It is one of the most misunderstood ideas in software security, constantly confused with its cousin, authentication, yet it is the difference between a system that merely knows who you are and one that actually keeps your data safe.
This guide walks through authorization from the ground up: what it is, why it exists, how it’s built inside real systems, the models companies like Google, Netflix, and Amazon actually use, and the mistakes that cause some of the biggest data breaches in history. No prior security background is assumed — every term is explained the moment it appears.
1Core Concepts
Authentication vs. Authorization
Authentication answers “who are you?” It’s the login screen, the fingerprint scanner, the one-time code sent to your phone. Authorization answers a completely different question: “now that I know who you are, what are you allowed to do?” A hotel key card system authenticates you when the front desk verifies your booking and hands you a card. It authorizes you every time you tap that card on a door — the system checks whether your specific card is permitted to open that specific room, at that specific time.
Authentication happens once per session (you log in). Authorization happens on nearly every single action (you try to open a file, delete a record, view a page) — it’s checked again and again, constantly, silently, in the background.
Why Authorization Exists
Without authorization, any logged-in user could do anything: read every customer’s private messages, delete another company’s financial records, or promote themselves to administrator. Authorization is the layer that enforces boundaries — it turns “I know who’s knocking” into “and here’s exactly which doors they can open.”
Permissions, Roles, and Policies
Three words show up constantly in this space, and beginners often blur them together:
- Permission — a single allowed action, like “can read invoices” or “can delete users.”
- Role — a labeled bundle of permissions, like “Manager” or “Support Agent,” assigned to a person instead of listing every permission one by one.
- Policy — a rule (or set of rules) that a system evaluates at the moment of a request, which can consider context like time of day, location, or resource ownership, not just a static role.
Think of a hospital. A “permission” is being allowed to view one specific patient’s chart. A “role” is being labeled a “Nurse,” which bundles together dozens of permissions like viewing vitals, administering medication, and updating charts. A “policy” is the rule that says “a nurse may only view charts for patients currently assigned to their ward, and only during their shift hours.” The role gives you a broad toolkit; the policy narrows it down to exactly what applies right now.
Subjects, Resources, and Actions
Every authorization decision, no matter how complex the system, boils down to the same three ingredients:
Subject
The user, service, or device making the request — the one asking “can I do this?”
Resource
The thing being acted upon — a file, a database row, an API endpoint, a physical door.
Action
The verb — read, write, delete, approve, share — describing what the subject wants to do to the resource.
An authorization system’s entire job is answering one sentence: “Can this subject perform this action on this resource, right now?” Every model discussed in this guide — roles, attributes, relationships — is just a different strategy for answering that one sentence at scale.
2Architecture & Components
Security architects borrow four terms from a standard called XACML (eXtensible Access Control Markup Language) to describe the moving parts of an authorization system. You don’t need to memorize the acronym, but the four roles it describes are everywhere, from AWS IAM to Google’s internal systems:
- PEP — Policy Enforcement Point. The gatekeeper sitting directly in the path of the request (an API gateway, a middleware layer, a service’s own code). It intercepts the request and asks, “am I allowed to let this through?”
- PDP — Policy Decision Point. The brain. It receives the question from the PEP, evaluates the rules, and returns a simple yes or no (technically “Permit,” “Deny,” or sometimes “Not Applicable”).
- PIP — Policy Information Point. The librarian. It supplies extra facts the PDP needs to decide — the user’s department, the resource’s sensitivity label, the current time, the user’s location.
- PAP — Policy Administration Point. The rulebook editor. This is the admin console or configuration system where security teams write and update the rules themselves.
graph LR
U["User / Service
(Subject)"] -->|"1. Sends request"| PEP["Policy Enforcement Point
(API Gateway / Middleware)"]
PEP -->|"2. Is this allowed?"| PDP["Policy Decision Point
(Authorization Engine)"]
PDP -->|"3. Fetches context"| PIP["Policy Information Point
(User attributes, resource data, time, location)"]
PIP -->|"4. Returns facts"| PDP
PAP["Policy Administration Point
(Admin console: rules & roles)"] -->|"Writes rules into"| PDP
PDP -->|"5. Permit / Deny"| PEP
PEP -->|"6a. Permit: forward request"| RES["Protected Resource
(Database, File, API endpoint)"]
PEP -->|"6b. Deny: reject with 403"| U
Notice something important in that diagram: the resource itself never makes the decision. Well-designed systems keep authorization logic centralized in the PDP, rather than scattering “if user.role == admin” checks across hundreds of files. This separation is what lets a security team update one rule and have it apply everywhere instantly.
Where This Lives in a Real Stack
In a typical web application, the PEP is usually the API gateway (like AWS API Gateway or an NGINX layer) or a small piece of middleware inside each microservice. The PDP is often a dedicated authorization service — companies like Netflix and Airbnb have built their own internal ones, and open-source options like Open Policy Agent (OPA) are popular off-the-shelf choices. The PIP might be a user directory service (like an internal HR system or AWS IAM) supplying attributes on demand.
3Internal Working
Request Arrives
A user, already authenticated (they have a valid session or token), tries to perform an action — say, clicking “Delete” on a document.
PEP Intercepts
Before the delete operation touches the database, the enforcement point pauses the request and packages up the key details: who is asking, what they want to do, and to which specific resource.
Context Gathering
The decision point may need more facts than the request alone provides — is this user the document’s owner? Are they in the same organization? Is it currently within business hours? It asks the information point for these details.
Rule Evaluation
The decision point runs the gathered facts against the stored policies. This might be a simple lookup (“is ‘delete’ in this role’s permission list?”) or a complex evaluation involving multiple conditions chained together.
Decision Returned
A verdict — Permit or Deny — travels back to the enforcement point, usually in single-digit milliseconds, since this happens on every protected action across the entire application.
Action Taken
On Permit, the request proceeds and the document is deleted. On Deny, the request is rejected, typically with an HTTP 403 “Forbidden” response, and the attempt is usually logged for security review.
Many beginners assume authorization only happens once, at login. In reality it happens on nearly every single request — viewing a page, calling an API, opening a file — because permissions can change mid-session (someone gets demoted, a document gets reshared, a subscription lapses) and every request must reflect the current state of the world, not what was true when you logged in.
4Data Flow & Lifecycle
Creation. When a user is onboarded, an administrator (or an automated workflow) assigns them a role or a set of permissions. This is typically written into a database table or an identity provider like Okta, Auth0, or AWS IAM.
Propagation. Large systems are distributed across many services, so permission data often needs to reach dozens of independent components. Some systems check a central authority on every request (strong consistency, but adds latency); others cache a snapshot of permissions locally and refresh periodically (faster, but can serve stale decisions for a short window).
Evaluation. Covered in the previous chapter — the moment-by-moment checking described in the internal working section.
Modification. Roles change constantly: promotions, team transfers, project completions. A robust system needs modifications to take effect quickly, especially for revocations — removing access needs to be fast, while adding access can usually tolerate a short delay.
Revocation & Expiry. When someone leaves a company, changes teams, or a temporary access grant expires (like a 24-hour contractor pass), the system must remove those permissions. This is one of the highest-risk steps: a forgotten revocation is a standing security hole.
graph TD
A["Permission Created
(Admin assigns role)"] --> B["Stored in Identity System
(Database / IAM / Auth0)"]
B --> C["Propagated to Services
(Cached or fetched live)"]
C --> D["Evaluated on Every Request
(PDP checks Permit/Deny)"]
D --> E{"Change Event?"}
E -->|"Role changed / promoted"| F["Modification
(Update stored permission)"]
E -->|"Employee leaves / access expires"| G["Revocation
(Remove permission, invalidate cache)"]
F --> C
G --> H["Access Removed
Future requests denied"]
Production Example: Netflix
Netflix’s internal authorization system evaluates billions of decisions daily across hundreds of microservices — deciding which internal engineers can access which production systems, and which content is licensed for which regions. They built caching layers so that most authorization checks never need to hit a central service, keeping decisions fast even at their global scale, while still propagating revocations quickly when access must be pulled.
5Authorization Models
RBAC — Role-Based Access Control
The most common model in business software. Permissions are attached to roles (“Editor,” “Viewer,” “Admin”), and users are assigned one or more roles. It’s simple to reason about and easy to audit — you can ask “what can an Editor do?” and get one clear answer.
RBAC is like a job title at a company. If you’re a “Cashier,” you automatically get the till key and the register password — you don’t get those permissions individually assigned; they come bundled with the title.
ABAC — Attribute-Based Access Control
Instead of static roles, decisions are based on attributes of the subject, resource, and environment — department, clearance level, document sensitivity, time of day, location. This is far more flexible than RBAC but harder to audit, since the “rule” is really a formula rather than a fixed label.
ABAC is like an airport security checkpoint that considers multiple facts at once: your ticket class, your boarding time, your citizenship, and whether you’re flagged for extra screening — no single fixed “role” determines the outcome; it’s a combination of attributes evaluated together.
ReBAC — Relationship-Based Access Control
Access is granted based on relationships between entities — “you can view this document because you’re a member of the team that owns it,” or “you can comment on this photo because you’re friends with the person who posted it.” Google’s internal system, Zanzibar, popularized this model, and it now powers access checks across Google Docs, Drive, and Photos.
PBAC — Policy-Based Access Control
A broader umbrella where rules are written as explicit policies (often in a dedicated policy language) rather than baked into application code — think of tools like Open Policy Agent, where a policy might read: “allow if user.department equals resource.department AND current_time is within business hours.”
| Model | Best For | Trade-off |
|---|---|---|
| RBAC | Simple orgs with clear job functions | Struggles with fine-grained, contextual rules |
| ABAC | Complex, context-sensitive environments | Harder to audit and debug “why was I denied?” |
| ReBAC | Social/collaborative products (docs, photos, teams) | Requires a relationship graph to query |
| PBAC | Large orgs needing centralized, code-independent rules | Needs a dedicated policy engine and language |
6Advantages, Disadvantages & Trade-offs
Advantages of Strong Authorization
- Limits blast radius when an account is compromised — a stolen login only exposes what that account was allowed to touch
- Enables safe collaboration — multiple people and teams can share one system without stepping on each other’s data
- Supports compliance requirements (like requiring that only finance staff can view payroll data)
- Makes audits possible — you can answer “who could have accessed this record?” after an incident
Disadvantages & Costs
- Adds latency — every protected action now involves a decision check
- Adds architectural complexity — someone must design, maintain, and test the rules
- Poorly designed rules create friction (legitimate users blocked) or gaps (unauthorized access allowed)
- Fine-grained models (ABAC, ReBAC) are harder to reason about and debug than simple RBAC
The central trade-off is almost always flexibility versus simplicity. RBAC is easy to explain to an auditor but clumsy for nuanced situations. ABAC and ReBAC handle nuance beautifully but require more engineering investment and more careful testing, since the rules themselves become a piece of software that can have its own bugs.
7Security
The Principle of Least Privilege
Perhaps the single most important idea in this entire guide: every subject should be granted the minimum permissions necessary to do their job, nothing more. A support agent who only needs to view order status should never also be able to issue refunds — even if it seems “convenient” to grant broad access up front.
Default Deny
Well-designed authorization systems default to denying access unless a rule explicitly permits it — never the reverse. This means a missing or broken rule fails safely (blocking access) rather than dangerously (allowing it).
Broken Access Control
The OWASP Top 10 — an industry-standard list of the most critical web application security risks — has ranked “Broken Access Control” as the #1 risk in its most recent editions, ahead of even injection attacks. This category covers failures like:
- Insecure Direct Object Reference (IDOR): changing a URL from
/invoice/1001to/invoice/1002and viewing someone else’s invoice because the system never checked ownership - Privilege escalation: a regular user manipulating a hidden form field or API parameter to grant themselves admin rights
- Missing function-level checks: an admin-only page that’s “hidden” from the menu but still reachable if you know the URL, with no server-side check at all
Problem
Hiding a “Delete” button in the UI for users without permission feels like authorization, but it isn’t.
Why It Fails
Any user can bypass the UI entirely and call the underlying API directly with a tool like a browser’s developer console or a simple script. If the server doesn’t independently verify permission on every request, the hidden button was cosmetic, not protective.
Correct Approach
Authorization must always be enforced on the server (or a trusted enforcement point), never trusted to the client. The UI can hide buttons for a better experience, but the server must re-check permissions regardless of what the client sends.
Defense in Depth
Mature systems don’t rely on a single authorization check. They layer checks at the network edge (API gateway), the service layer (application code), and sometimes the data layer (database row-level security) — so that even if one layer has a bug, others may still catch an unauthorized request.
8Monitoring, Logging & Metrics
Every serious authorization system logs its decisions. At minimum, a good log entry captures: who made the request, what resource and action were involved, what the decision was (Permit/Deny), and why (which specific rule fired). This is essential for two very different reasons:
Detecting Attacks
A sudden spike in “Deny” responses for one account often signals an attacker probing for weaknesses — trying URLs and IDs they don’t own to see what slips through.
Root-Cause Tracing
When a legitimate user is incorrectly blocked, logs let engineers trace exactly which rule caused the denial, instead of guessing.
Audit Trails
Regulations in finance and healthcare often require proof of exactly who accessed sensitive records and when — logs are the evidence.
Latency Tracking
Since every protected request passes through the decision point, teams monitor how long decisions take, because a slow authorization check slows down the entire application.
Log every Deny by default — it’s a security signal. Many teams sample Permit logs (not logging every single one, to save storage) since there are vastly more successful checks than denied ones, but nearly always keep every denial.
9Design Patterns & Anti-patterns
Good Patterns
- Centralized Policy Engine: one authoritative service (like Open Policy Agent) that all other services call, instead of each team reinventing authorization logic independently
- Attribute Caching with Short TTLs: caching user attributes briefly to keep decisions fast, while still refreshing often enough that revocations take effect quickly
- Deny-by-Default: covered earlier — the system fails closed, not open
- Ownership Checks: resources record who owns them, and every access check verifies the requester against that recorded owner rather than trusting the request alone
Anti-patterns to Avoid
Common Mistakes
- Trusting client-side checks (covered in Chapter 7)
- Hardcoding role checks scattered across hundreds of files instead of a central policy source
- Forgetting to re-check authorization after a resource is transferred or reshared
- Using the same broad “admin” role for convenience instead of narrowly scoped roles
- Never expiring stale permissions from employees who changed teams years ago
10Real-World & Industry Examples
Google Docs & Drive — Zanzibar (ReBAC)
When you share a Google Doc with “Anyone in your organization with the link can comment,” Google’s internal Zanzibar system is evaluating a relationship graph — checking whether your account belongs to the same organization as the document owner, and whether the document’s sharing setting includes that relationship. This same engine backs YouTube and Google Calendar sharing decisions at massive global scale.
AWS IAM — Policy-Based Access Control
Amazon Web Services uses JSON-based policy documents attached to users, groups, and roles, specifying exactly which actions (like “read this storage bucket” or “launch this server type”) are allowed on which resources. A single misconfigured policy — like a storage bucket accidentally left publicly readable — has been the root cause of numerous major data exposure incidents across the industry.
Banking Systems — Strict RBAC + ABAC Hybrid
Banks commonly combine role-based access (a “Teller” role limited to routine transactions under a certain amount) with attribute checks (transaction amount, time of day, branch location) to flag or block unusual activity, reflecting how sensitive financial authorization decisions need multiple layers of nuance.
Uber — Location and Time-Based Attributes
Ride-sharing platforms authorize driver actions partly based on attributes like current location and active shift status — a driver marked “offline” cannot accept ride requests, regardless of their account role, because the authorization check considers real-time context, not just a static permission list.
11Frequently Asked Questions
12Summary and Key Takeaways
Key Takeaways
- Authorization ≠ Authentication — one confirms identity, the other governs permitted actions, and it’s re-evaluated on nearly every request, not just at login.
- Every authorization decision reduces to three ingredients: who (subject), what (resource), and how (action).
- Real systems separate concerns using four components: the enforcement point, decision point, information point, and administration point.
- Choose an authorization model based on your needs: RBAC for simplicity, ABAC for context-aware nuance, ReBAC for relationship-driven products, and PBAC for centralized, code-independent policy management.
- Least privilege and default-deny are non-negotiable security principles — grant only what’s needed, and fail safely when a rule is missing.
- Never trust client-side checks alone — hiding a button is a UX choice, not a security control; the server must always independently verify permission.
- Logging every denied request is essential for detecting attacks, debugging legitimate user issues, and satisfying compliance audits.