Authorization: Who Can Do What
And Why It’s Separate From Authentication

I'm a passionate backend dev
After authentication, backend systems feel… calmer.
You know who the user is. You trust their identity. Requests stop failing randomly.
And then a new question appears. “Okay, but what is this user allowed to do?”
That question is authorization. And if there’s one mistake backend engineers make repeatedly, it’s this: Treating authorization as a continuation of authentication.
It isn’t. They solve very different problems.
A Simple Sentence That Clears Everything Up
Let’s lock this in early:
Authentication answers: Who are you?
Authorization answers: What are you allowed to do?
Same request. Different concern. When these get mixed, systems become fragile, insecure, and hard to reason about.
Why Auth Feels Like It Should Handle Authorization
At first, it feels logical to bundle authorization into authentication. When a user logs in, you already know: Who they are, Maybe what role they have, Maybe some claims like isAdmin.
So it’s tempting to think: “If the token already knows this, why not decide permissions there?”
But this is where systems quietly drift into trouble. Consider these two facts:
Identity answers “who”
Authorization answers “can you do this, here, right now?”
Those are very different questions. A user can be:
Authenticated ✔️
But not allowed to edit this document
Or allowed today, but not tomorrow
Or allowed on one resource, but not another
Identity is stable. Permissions are situational. This is why authentication cannot safely decide authorization on its own.
Identity Is Relatively Static
A user: Logs in, Has an ID, Has an email, Has an account. These things don’t change often. Authentication answers this once per request and moves on.
That stability makes auth predictable.
Permissions Are Contextual and Fluid
Authorization depends on: The resource being accessed, The action being performed, The current state of the system, Sometimes even time.
The same user can: Read one resource, Modify another, Be blocked from a third.
Authorization lives in context, not identity.
A Quick Real-World Analogy
You enter an office building. Security checks your ID. That’s authentication.
Then: You can access some floors, You’re blocked from others, You need approval for certain rooms.
That’s authorization. Same person. Different permissions.
Why Mixing Them Causes Trouble
When auth and authorization are tangled together: Tokens grow huge, Logic spreads everywhere, Changes require reissuing tokens, Security bugs hide in assumptions.
You start encoding business rules into identity. That never ages well.
Where Authorization Should Actually Live
Authorization should live: Close to the resource, Close to the decision, Close to the business logic.
Not inside the authentication mechanism. Authentication proves identity. Authorization interprets that identity in context.
Role-Based Authorization (The Simplest Model)
Roles are often the first authorization model teams adopt. It usually begins simply: admin, editor, viewer .
Rules feel clean: Admins can do everything, Editors can modify content, Viewers can only read.
This works… until reality shows up. Now imagine a growing system:
Some editors can only edit their own content
Some admins can manage users but not billing
Some users can approve changes only during business hours
Some permissions are temporary
Some permissions are resource-specific
What happens next? Roles multiply: admin, super-admin, content-admin, billing-admin, editor, senior-editor, external-editor.
Soon, roles stop being meaningful descriptions and start becoming permission bundles with unclear boundaries. At that point: Adding a role becomes risky, Removing one breaks things, No one is sure what a role actually allows.
This is why roles don’t scale well on their own.
Why Roles Don’t Scale Forever
Roles assume: Few user types, Simple rules, Stable permissions. Real systems are messier.
Questions start appearing:
Can this user edit this resource?
What about resources they created?
What about temporary permissions?
What about shared ownership?
Roles alone can’t answer these cleanly.
Permission-Based Thinking
Instead of asking: “What role does this user have?”
Ask: “Does this user have permission to perform this action on this resource?”
This shifts thinking from identity to intent. Authorization becomes a decision, not a label.
Resource-Centric Authorization
This is the mental upgrade. Authorization checks usually look like:
Who is the user?
What resource is being accessed?
What operation is requested?
The answer depends on all three. This is why authorization logic belongs near handlers and services, not auth middleware.
Why Authorization Happens on Every Request
(And Why That’s Still Okay)
Authorization decisions must be evaluated every time because:
Resource ownership can change
Permissions can be revoked
Context can differ per request
System state can evolve
That sounds expensive. And yes, it can be. But systems don’t handle this by skipping authorization. They handle it by optimizing how it’s checked.
Common strategies include:
Keeping authorization logic close to the data
Using indexed lookups instead of complex joins
Caching coarse permissions carefully
Avoiding embedding fine-grained rules in tokens
The important thing is this: You optimize authorization checks — you don’t eliminate them.
Skipping authorization for performance is how subtle security bugs appear.
Tokens Should Carry Identity, Not Decisions
This is a critical boundary. Good tokens contain: User ID, Basic claims, Maybe coarse roles.
Bad tokens contain: Fine-grained permissions, Resource-specific access, Business rules.
Why? Because permissions change faster than tokens expire.
Authorization Is a Business Problem, Not a Protocol Problem
HTTP doesn’t help you here. There’s no header for: “Is this user allowed to do this?”
That’s intentional. Authorization is deeply tied to: Product rules, Business logic, Domain concepts.
Trying to “standardize” it too early usually backfires.
The One Mental Model to Keep
Let’s tie everything together.
Authentication proves identity
Authorization evaluates intent in context
Identity is stable
Permissions are fluid
Authentication answers who you are. Authorization decides what you can do, here and now. When these concerns stay separate: Security stays predictable, Business rules stay readable, Systems evolve safely.
When they’re mixed: Tokens grow heavy, Logic spreads everywhere, Changes become dangerous.
The web works not because it hides complexity, but because it keeps responsibilities cleanly separated.
What Comes Next
Now that we know: Who the user is, What they’re allowed to do.
The next hard question is: “How do we protect systems from misuse, abuse, and overload?”
That’s where rate limiting and trust come in.
➡️ Next article:
Rate Limiting, Abuse, and Trust at Scale
This article is part of the Thinking in Backend series, where we learn backend engineering by focusing on how systems think, not just how code runs.




