Skip to main content

🚦 Authorization

What you're allowed to do

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

AspectAuthenticationAuthorization
QuestionWho are you?What can you do?
TimingFirstAfter authentication
ExamplesLogin, passwordAdmin actions, file access
Error401 Unauthorized403 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.