← Learn

Definition

Authentication vs authorization: what's the difference?

We scanned nearly 2,000 AI-built apps and 1 in 8 shipped a high-severity flaw. Want to check yours?Scan free →

Authentication is proving who you are, for example by logging in with a password. Authorization is deciding what you are allowed to do once you are known, for example whether you can view a given record. They are separate steps: a request can be authenticated but still not authorized, and confusing the two is a common source of access bugs.

Why the distinction matters

Many apps get authentication right, a real login, and then assume that a logged-in user is allowed to do anything. That skips authorization. The result is that any signed-in user can often read or change another user's data just by changing an id in the request, because nothing checks ownership.

Where each belongs

Authentication happens once, at the edge, establishing identity. Authorization happens on every action, close to the data, answering does this specific user have permission for this specific thing. Both must run on the server; a check that only exists in the UI is not a check at all.

What this means for AI-generated code

AI tools reliably generate the login (authentication) because it is a visible feature, but routinely omit the per-request ownership check (authorization) because the feature works without it. That is why missing authorization is one of the most common high-severity issues we find in AI-built apps.

Common questions

What is an example of a missing authorization bug?

An API route that takes /api/invoices/:id and fetches the invoice by id — but never checks that the invoice belongs to the authenticated user. Any logged-in user can change the id in the request and read any other user's invoice. The route is authenticated (requires a login) but not authorized (does not verify ownership).

How do I add authorization to an existing API route?

Scope every database query to the authenticated user: instead of db.findById(id), use db.findOne({ id, userId: session.userId }). If no record is found — whether it does not exist or belongs to someone else — return 404, not 403, to avoid confirming the record exists.

Is middleware enough for authorization?

Middleware handles authentication (confirming the request has a valid session) but usually cannot handle authorization (confirming the record belongs to this user) because it runs before the route knows which record is being requested. Authorization belongs in the route handler, close to the data query.

Want to know if your app has this issue? Scan your live app or a public repo free, no account needed.

Scan my app →

Related: fix a missing authorization check

Authentication vs Authorization: The Difference, Explained | Prbl