Authentication vs authorization: who is the caller, what can they do
coreintermediateAuthentication proves who is making a request — a login, a token, a certificate. Authorization decides what that already-proven identity is allowed to do. A system can get the first right and still be broken if it never checks the second.
Think of it as
Think of a building with a badge reader at the front door and a locked door on each floor. The badge reader authenticates you — it confirms you are an actual employee, not a stranger off the street. But a valid badge at the front door says nothing about which floors you should reach; a separate check at each floor door is what authorizes you into finance versus the shared kitchen. A building that only checks badges at the front door lets any employee wander into any floor.
What we're doing: Show a request that passes authentication cleanly but must still be rejected by authorization.
- 2
- Authentication succeeding only proves the JWT belongs to a real, currently-valid user_id 482 — it proves nothing yet about invoice 900.
- 8
- This is the authorization check: same confirmed identity, a different question entirely — ownership of this specific resource.
- 12
- The status code distinguishes the two failure modes for the client: 401 means "prove who you are again," 403 means "you already did, and the answer is still no."
Why this works: The request never fails to authenticate — the token is completely valid — which is exactly the case that exposes a system that conflates the two checks: code that stops at "token is valid" and treats that as permission would incorrectly let user 482 delete an invoice they do not own.
Treating a valid token as proof of permission
Wrong
Better
What you see: Any logged-in user can delete, read, or modify any other user's resources by ID — a valid session is silently treated as blanket permission, and the bug produces no error anywhere until someone notices data that should have been private is reachable by guessing or enumerating IDs.
Why: Authentication only confirms the caller is a genuine, currently-valid identity — it carries no information about which specific resources or actions that identity is permitted to touch. Skipping the authorization check does not fail loudly; it just silently grants access that was never supposed to exist, which is why this exact gap is the root cause behind a large share of real-world broken-access-control incidents.
- Client → API: Request + credentials/token
- API → Auth check: Who is this? (authentication)
- Auth check → API: user_id 482 (identity confirmed)
- API → Authz check: Can 482 delete invoice 900? (authorization)
- Authz check → API: No — not the owner
- API → Client: 403 Forbidden
Authentication and authorization compared
Remember: Authentication proves identity (who); authorization decides permission (what they can do with that identity). They are two separate checks, not one — a valid token only ever answers the first question.
See also: session and cookie vs token auth · rbac abac and object level authorization

