Authentication vs Authorization: What's the Difference?
Authentication checks who you are. Authorization checks what you're allowed to do. Mixing them up is behind many of the worst security holes in AI-built apps. A plain-English explanation with the hotel analogy, the mistakes to look for, and a five-minute test.
Two words that sound almost the same, often shortened to authn and authz, and routinely confused. The difference matters a lot: many serious security problems in apps come from getting the first one right and forgetting the second.
The hotel
You arrive at a hotel.
- At the front desk, you show your passport. They confirm you are who you say you are. That's authentication: who are you?
- They give you a key card. It opens your room, the gym, and the pool — but not other guests' rooms or the manager's office. That's authorization: what are you allowed to do?
Checking your passport doesn't decide which doors you can open. Both checks are needed, and they're separate.
In an app
Authentication is logging in. Email and password, "Sign in with Google," a magic link, a fingerprint. The result is that the app knows: this is Ana.
Authorization is everything after. Every time Ana does something, the app should check: is Ana allowed to do this?
- Can Ana see this invoice? Only if it's hers.
- Can Ana delete this comment? Only if she wrote it, or she's a moderator.
- Can Ana open the admin dashboard? Only if she's an admin.
Why AI-built apps often get authorization wrong
AI tools are good at authentication — add a login page, connect an auth service, done. It's visible, and you can test it by logging in.
Authorization is invisible. An app with no authorization checks looks exactly the same as one with them, as long as you only click where you're supposed to. The gaps only appear when someone does something unexpected — which is exactly what attackers do.
The three classic mistakes
1. Authorization only in the interface
The app hides the "Delete" button from people who aren't allowed to delete. But the backend's delete endpoint doesn't check anything. Anyone who sends the request directly — easy with the browser's developer tools — can delete whatever they like.
Hiding a button isn't authorization. The check must happen on the server, for every request. (Frontend vs Backend)
2. Trusting IDs from the browser
A page loads data with a request like /api/invoices/1042. The server returns invoice 1042 to anyone logged in. Change it to 1043, and you see someone else's invoice.
This mistake is so common it has a name — IDOR (insecure direct object reference). The fix: the server checks that the logged-in user owns (or may see) invoice 1043 before returning it.
3. Trusting roles from the browser
The app stores isAdmin: true in the browser, or accepts a role field when users update their profile. A user edits it, and they're an admin.
Roles and permissions must be stored and checked on the server, and users must never be able to set their own.
Where authorization lives
- In a traditional app, in your backend code: every endpoint that reads or changes data checks the user's permissions first.
- In apps where the browser talks to the database directly (Supabase, Firebase), in the database's security rules. If those rules are missing or too loose, logging in protects nothing. (Supabase Row-Level Security Explained)
The five-minute test
You don't need to read code to check authorization. Create two test accounts, A and B, each with some data. Then:
- Logged in as A, open one of B's pages by changing the ID in the address bar. You should get an error or "not found."
- Logged in as A, try to edit or delete B's data the same way.
- Log out and visit private pages directly. They should send you to the login page — and show no data.
- As a normal user, visit the admin page URL directly.
- Check the browser's Network tab: when a page loads, does the response contain data you shouldn't see, even if the page doesn't display it?
If anything works that shouldn't, you've found an authorization hole. Tell your AI tool exactly what you did and ask it to add a server-side check.
A prompt that helps
Review every API route and server action in this app. For each one, tell me: who is allowed to call it, and where in the code that is checked on the server. List any route that reads or changes data without checking the logged-in user's permission.
Then verify the answers with the two-account test.
The summary
| Authentication | Authorization | |
|---|---|---|
| Question | Who are you? | What may you do? |
| Happens | At login | On every request |
| Example | Password, Google sign-in | "Only the owner can see this invoice" |
| Common mistake | Building it yourself | Forgetting it, or only doing it in the interface |
Authentication is the front door. Authorization is the lock on every room.
EasySpawn runs your app with a real backend and managed database, so permission checks live in server code you control — with secrets on the server and SSL on your own domain. See how it works for AI-built apps or join the waitlist.
Related: How to Add Login to an AI-Built App · A Security Checklist for Vibe-Coded Apps · What Is a Cookie? · What Is a JWT? · CSRF Explained
Keep reading
What Is a JWT? JSON Web Tokens Explained Simply
Supabase, Firebase, Auth0, and Clerk all hand your app JWTs. What a JSON Web Token is, its three parts, why anyone can read it but nobody can forge it, how apps use it for login, and the mistakes AI-generated code makes with tokens.
GDPR Basics for App Builders: What a Small App Actually Needs
If anyone in the EU or UK uses your app, GDPR probably applies. What personal data is, the principles in plain English, lawful bases, the rights users have (access, deletion), what to do about third-party services and data breaches, and a practical checklist for a small app. Not legal advice.