Foundation14 min

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.

How deep?
How the pieces actually move.

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, the whole system

First, see the whole system. Then we’ll open it up.

Two distinct gates

Two distinct gates

  1. A request first hits authentication; failure returns 401.
  2. 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).
Why it exists

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.

Now break it

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

Authority

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.

Both authN and authZ need to carry facts about the subject across services. What format carries those facts?

Next: JWT / JWS / JWE →