How to Add Authentication to a Vibe-Coded App: A Pre-Launch Checklist
A working login screen does not prove that private routes and data are protected. Check the boundaries that matter before inviting anyone into your app.
The login screen works, so you invite a friend to try your app. Then you discover that changing an account ID in a request shows someone else's data. When you add authentication to a vibe-coded app, test the permissions behind the interface before you treat the feature as ready. Use these checks while the implementation is still small enough to inspect.
Authentication establishes who someone is. Authorization determines what that person can do. AI-generated code can produce a convincing sign-in flow while leaving the second question unanswered. If the app handles sensitive information, get an experienced security review before production use.
Choose the sign-in boundary
- Pick a maintained authentication approach. Prefer a provider or library you can support over a sign-in scheme assembled from generated code. Read its current documentation before implementing it.
- Name the routes that require an account. Write down which pages and API actions are public, signed-in, or restricted to an owner or admin. Do this before prompting for middleware.
- Keep credentials and secrets out of the client. Store server secrets in environment variables and check that they are absent from committed files and browser-visible code.
- Decide how a session ends. Check sign-out behavior and what happens when a session expires. A hidden menu is no substitute for an expired server-side session.
These decisions give an AI coding tool a smaller, clearer task. For instance, ask it to protect one API route according to your access rules, then inspect the diff before moving to the next route.
Verify access where data changes hands
- Enforce identity on the server. A client-side redirect can improve the interface, but protected reads and writes need server-side checks.
- Check ownership on every private record request. Test whether one signed-in account can read, edit, or delete a record belonging to another.
- Validate inputs before database writes. Confirm required fields, allowed values, and the account associated with each change.
- Test destructive actions separately. Deleting a record or changing a role deserves a direct permission test, not an assumption based on the page that contains its button.
Use two test accounts and try the same requests from each. Record what should be denied as carefully as what should succeed. If generated code changes a database query or permission check, understand that change before deploying it.
For the rest of the release, use this pre-ship checklist for reviewing AI-generated code.
Check the failure paths before inviting users
- Try an unsigned request to a protected endpoint. It should fail without relying on what the page displays.
- Try a signed-in request for another account's resource. The server should deny it even when the request is made directly.
- Check error messages and logs. They should help you debug without exposing tokens, secrets, or private records.
- Keep a recovery path. Back up data before changing authentication or authorization code, and know how to roll back a faulty change.
A passing happy-path test tells you that sign-in works. The denied requests tell you whether the boundary holds. Recheck those paths whenever you change account IDs, database queries, or route protection.
Leave a record for the next change
Write down the access rules you tested, the routes you have not reviewed, and the next security question to resolve. That note makes it harder for a later AI-assisted edit to quietly undo a deliberate boundary.
Track authentication decisions and remaining checks in VibeCrumbs as you work through the app.
