Authentication vs. Authorization
AuthN proves who you are. AuthZ decides what you may do. Conflating them is a classic bug.
By the end of this lesson, keep authentication and authorization separate in your designs and spot where they are wrongly merged.
Authentication (AuthN) answers 'who are you?' — it establishes the subject. Authorization (AuthZ) answers 'what are you allowed to do?' — it makes a decision about a specific action on a specific resource. They run in that order, and they are different systems with different lifecycles.
First, see the whole system. Then we’ll open it up.
Two distinct gates
- A request first hits authentication; failure returns 401.
- If the subject is known, authorization decides; failure returns 403; success handles the request.
flowchart LR
req[Request] --> authn{AuthN: who?}
authn -->|unknown| deny1[401 Unauthorized]
authn -->|subject| authz{AuthZ: allowed?}
authz -->|no| deny2[403 Forbidden]
authz -->|yes| allow[Handle request]- 401 vs 403
- 401 Unauthorized means 'I don't know who you are' (authN failed). 403 Forbidden means 'I know who you are, and you may not' (authZ failed).
You know what happens. Now see why it works.
Separating them lets identity be established once (at the edge, via a token) while authorization is enforced everywhere (at each service, per action). If you merge them — e.g., 'if authenticated, allow' — every authenticated user becomes an admin the day you add a sensitive endpoint.
Your API checks the JWT signature and, if valid, serves the request. A regular user copies the URL of an admin-only report. What stops them? Nothing — you authenticated but never authorized.
Missing function-level authorization
- Trigger
- An endpoint verifies authN but not authZ (or checks it only in the UI).
- Symptom
- Any authenticated user reaches privileged actions by calling the API directly.
- Blast radius
- Every under-protected endpoint; often full data exposure or privilege escalation.
- Mitigation
- Enforce authZ server-side on every action; default-deny; test with low-privilege tokens.
Deep dive: Privilege Escalation
Centralizing authZ (one policy service) gives consistency and auditability but adds a dependency on every request. Distributing it (each service decides) is faster and more autonomous but risks drift. Most enterprises centralize policy definition and distribute enforcement.
A user gets a 403 on their own profile page. AuthN or AuthZ problem?
AuthZ. 403 means the identity was established but the action was not permitted.