Authentication and authorization sound alike, are often abbreviated the same way ("auth"), and are frequently implemented in the same middleware. They answer completely different questions, though, and confusing them is behind the most common serious vulnerability in web applications today.
Authentication: who are you?
Authentication (often written AuthN) is the process of verifying an identity. A user proves who they are with one or more factors:
- Something you know: a password or PIN.
- Something you have: a phone with an authenticator app, a hardware security key, a passkey stored on a device.
- Something you are: a fingerprint or face scan, usually used to unlock a device-bound key rather than sent to the server.
Machines authenticate too: a service presents an API key, a client certificate or a signed token. The result of authentication is a verified identity, usually carried in a session cookie or token for subsequent requests.
Authorization: what are you allowed to do?
Authorization (AuthZ) decides whether that identity may perform a specific action on a specific object. It's expressed as policies such as:
- Role-based (RBAC): admins can delete projects; members can only edit them.
- Attribute-based (ABAC): users can read documents where the document's tenant matches their own tenant.
- Relationship-based (ReBAC): you can edit a file if you're its owner or it's shared with a group you belong to.
Authentication usually happens once, at login. Authorization has to happen on every request, for every object, because the question changes each time: this user, this invoice, this action.
Side by side
| Authentication | Authorization | |
|---|---|---|
| Question | Who are you? | Are you allowed to do this? |
| When | At login, or when a token is issued | On every request |
| Where it's implemented | Usually one place: a login service or identity provider | Spread across every endpoint and query |
| Typical failure | Credential stuffing, weak MFA, session theft | IDOR, missing role checks, privilege escalation |
| HTTP status on failure | 401 Unauthorized | 403 Forbidden (or 404 to avoid revealing the object exists) |
| STRIDE category | Spoofing | Elevation of privilege, information disclosure |
Why authorization fails more often
Authentication is a solved problem in the sense that most teams use a framework or an identity provider for it, and it lives in one place that gets a lot of scrutiny. Authorization can't be outsourced as easily, because the rules depend on your data model. Every new endpoint needs its own check, and a single forgotten check is enough.
That's why Broken Access Control has been ranked first in the OWASP Top 10 since the 2021 edition, and kept the top spot in the 2025 edition. Its most common form is IDOR: an endpoint confirms the user is logged in, then returns whatever record ID the request asks for.
Worked example: Invoicely
Invoicely's two highest-scoring threats sit on opposite sides of this line:
- T1, an authentication failure: credential stuffing on the login endpoint, because there's no rate limit or breached-password check. The attacker becomes someone else.
- T2, an authorization failure: any logged-in customer can read another customer's invoices by changing the invoice ID, because ownership is checked in the UI but not on every endpoint. The attacker stays themselves and simply asks for data that isn't theirs.
Adding MFA would reduce T1 and do nothing at all for T2, which scored higher (20 versus 16). The fix for T2 is an ownership check in the data access layer, applied to every query.
How to model both in a threat model
On a data flow diagram, look at every flow that crosses a trust boundary and ask two separate questions: how is the caller identified, and where is the permission for this specific object checked? If the answer to the second is "the frontend hides the button", that's a finding.
Good patterns to look for: authorization enforced in one shared layer (a policy engine, a query scope or a repository method) rather than repeated by hand in each controller; deny by default; and tests that log in as user A and try to read user B's objects.
Common mistakes
- Trusting identifiers from the client. A user ID or tenant ID in the request body is a claim, not a fact. Take it from the authenticated session.
- Checking roles but not ownership. "Is this a customer?" is not the same as "is this their invoice?".
- Treating internal APIs as authorised. A service-to-service call still needs to prove which service it is and what it's allowed to touch. See zero trust.
Key takeaways
- Authentication answers "who are you?". Authorization answers "are you allowed to do this, to this object, right now?".
- Authentication is usually centralised and well tested. Authorization is spread across every endpoint, which is why it fails more often.
- Broken access control has been the top category of the OWASP Top 10 since 2021, and IDOR is its most common form.
- In a threat model, every data flow that crosses a trust boundary needs both questions answered, not just the first.
Frequently asked questions
What is the difference between authentication and authorization?
Authentication confirms identity: you are user 4812. Authorization confirms permission: user 4812 may read invoice 991 but not invoice 992. A system can authenticate perfectly and still be insecure if it never checks authorization.
What is the difference between HTTP 401 and 403?
401 Unauthorized actually means unauthenticated: the request has no valid credentials. 403 Forbidden means the server knows who you are and you are not allowed to do this. The naming is a historical mix-up in the HTTP specification.
Is OAuth authentication or authorization?
OAuth 2.0 is an authorization framework: it lets an application get limited access to an API on a user's behalf. OpenID Connect is the identity layer built on top of OAuth that adds authentication, through the ID token.
Is MFA authentication or authorization?
Multi-factor authentication is authentication. It makes it harder to impersonate a user, but once someone is logged in, it does nothing to stop them reaching data their account shouldn't access.