The VIP Pass Analogy
At an event:
- Badge proves who you are (authentication)
- Badge color determines where you can go (authorization)
Red badge: Staff areas only Gold badge: VIP areas + main floor Green badge: Main floor only
You proved who you are. Now, what can you do?
Authorization decides what actions you're allowed to take.
Authentication vs Authorization
| Aspect | Authentication | Authorization |
|---|---|---|
| Question | Who are you? | What can you do? |
| Timing | First | After authentication |
| Examples | Login, password | Admin actions, file access |
| Error | 401 Unauthorized | 403 Forbidden |
Order matters:
1. Prove identity (authentication)
2. Check permissions (authorization)
Can't authorize unknown users!
Common Authorization Models
1. Role-Based Access Control (RBAC)
Assign users to roles.
Roles have permissions.
User → Role → Permissions
Example:
Alice → Admin → [read, write, delete]
Bob → Editor → [read, write]
Carol → Viewer → [read]
2. Attribute-Based Access Control (ABAC)
Decisions based on attributes:
- User attributes (department, clearance)
- Resource attributes (classification, owner)
- Environment (time, location)
Example:
Allow if:
user.department = "Engineering"
AND resource.classification <= "Confidential"
AND time is business hours
3. Access Control Lists (ACL)
Each resource has a list of who can access it.
document.txt:
- Alice: read, write
- Bob: read
- Everyone else: no access
4. Permission-Based
Users have explicit permissions.
Alice:
- user:read
- user:write
- report:generate
Bob:
- user:read
RBAC: The Most Common
Structure
Roles:
Admin: [create, read, update, delete, admin]
Editor: [create, read, update]
Viewer: [read]
Users:
Alice: Admin
Bob: Editor
Carol: Viewer
Checking Access
Bob wants to delete a post.
Check:
1. Bob's role = Editor
2. Editor permissions = [create, read, update]
3. "delete" not in permissions
Result: DENIED
Hierarchical Roles
Admin inherits everything:
Admin → Manager → Employee
Admin has all Manager permissions,
Manager has all Employee permissions.
Implementing Authorization
Where to Check
Frontend:
Hide buttons user can't use
Better UX, not security!
Backend:
Check before performing the action
Treat the client as untrusted input
if (!user.can('delete', post)) {
return 403 Forbidden
}
Middleware Pattern
Route: DELETE /posts/:id
Middleware chain:
1. Authenticate user (is logged in?)
2. Authorize action (can delete posts?)
3. Handle request
Each step can reject with appropriate error.
Resource-Level Permissions
Beyond Actions
"Can edit posts" isn't enough.
"Can edit THIS post" is what matters.
Alice owns Post #1
Bob owns Post #2
Alice tries to edit Post #2:
Has edit permission: YES
Owns the post: NO
Result: DENIED
Common Patterns
Owner: Can do anything to their resources
Admin: Can do anything to any resources
Shared: Explicit permission to specific users
Public: Anyone can read
Authorization in APIs
Token-Based
JWT payload:
{
"user_id": "123",
"roles": ["admin"],
"permissions": ["user:create", "user:delete"]
}
API extracts permissions from token.
No database lookup needed.
Database Lookup
Request comes in with user ID.
Query database for user's roles/permissions.
Check against required permission.
More up-to-date, but slower.
OAuth Scopes
OAuth tokens have scopes:
scope=read:email write:posts
App can only do what scopes allow.
User granted limited permissions.
Best Practices
1. Principle of Least Privilege
Give minimum permissions needed.
Don't make everyone admin "for convenience."
2. Check on Server
Client-side checks are for UX.
Server-side checks are for security.
Verify permissions server-side.
3. Fail Closed
If in doubt, deny access.
Missing permission = denied
Error checking permissions = denied
4. Log Access Decisions
Log who accessed what, when.
Essential for auditing and debugging.
Common Mistakes
1. Only Checking on Frontend
Hide the delete button? Good UX.
But attacker can call DELETE API directly.
Check on backend.
2. Inconsistent Checks
Delete post API checks permissions.
Edit post API doesn't.
All actions need authorization.
3. Hardcoded Admin Bypass
If (user.email === 'admin@company.com') {
return allowed;
}
What if that email is compromised?
Use roles, not hardcoded checks.
FAQ
Q: Where should I store permissions?
Database for flexibility. Cache for performance. JWTs for stateless systems.
Q: RBAC vs ABAC?
RBAC is simpler. ABAC is more flexible. Start with RBAC, add ABAC when needed.
Q: How do I handle changing permissions?
With database: immediate effect. With JWTs: wait for token refresh, or use short-lived tokens.
Q: Should permissions be in the token?
Simple permissions: yes, convenient. Complex/dynamic: no, query at request time.
Summary
Authorization controls what authenticated users can do, determining access to resources and actions.
Key Takeaways:
- Authentication = who you are
- Authorization = what you can do
- RBAC is most common (User → Role → Permissions)
- Check permissions server-side
- Least privilege: minimum necessary access
- Log access decisions for auditing
Authentication opens the door. Authorization decides which rooms you can enter!
Related Concepts
Leave a Comment
Comments (0)
Be the first to comment on this concept.
Comments are approved automatically.