How to Add Authentication With Claude Code (Without Shipping a Hole)

David IyaDavid Iya August 18, 2026 10 min read
A heavy brass door lock and a single key resting on a clean walnut desk beside a closed laptop
Original image, Claude Code Club

How to Add Authentication With Claude Code - The Short Version

Adding authentication with Claude Code is a three-part job: choose a managed auth provider, have the agent wire the sign-up and sign-in flow into your app, and then run a dedicated review pass that checks the server actually enforces the rules. The first two parts take an afternoon. The third part is the one people skip, and it is the one that decides whether you shipped a login or a decoration.

Be specific about the provider before you start. Tell the agent which auth service you are using, which framework you are on, and whether you want email and password, social sign-in, or magic links. A vague request produces a plausible custom implementation, and a custom auth implementation is the last thing you want on a project you are going to hand to a client.

The Real Risk - The Login Works and the Server Does Not Care

The classic AI-built auth bug is that everything you can see works perfectly. You sign up, you sign in, you get redirected to the dashboard, the wrong password gets rejected. And behind that, the API route that returns the data will happily return it to anyone who calls it directly, because nothing on the server ever checks who is asking.

This happens for an understandable reason. You asked for a login. The agent built a login. The login is the visible part, and the visible part is what got described, demonstrated, and approved. The invisible part - every server route independently refusing requests that do not carry a valid session - was never in the request, so it was never in the build.

The Auth Gate Checklist - Three Gates You Have to Close

The Auth Gate Checklist is how we structure the review pass. There are exactly three gates between a stranger and your data, they are checked in order, and every one of them has to live on the server. If any gate is enforced only in the browser, it is not a gate, it is a suggestion.

  1. Identity - who is this? Sign-up, sign-in, sign-out, password reset, and email verification. Handled by your auth provider, not by you.
  2. Session - are they still who they said they were? The token or cookie that proves identity on every subsequent request, stored somewhere a script on another site cannot read, and verified on the server before anything else happens.
  3. Authorization - are they allowed to do this specific thing to this specific record? This is the gate that gets forgotten. A valid session proves you are a user. It does not prove you are allowed to read invoice number 412.

Give the agent the checklist explicitly. Ask it to walk each server route and tell you which of the three gates that route enforces and where in the code the check happens. Routes that cannot answer are your bug list, and you will usually get one.

Gate One - Identity, and Why You Use a Provider

Use a managed authentication provider. The reason is not that authentication is hard to write, it is that authentication is hard to keep correct over years while you are busy doing other things. Password hashing standards move, token handling has sharp edges, and account recovery is a whole security surface on its own. A provider absorbs all of that and keeps absorbing it after you have stopped thinking about the project.

When you brief Claude Code, name the provider and the framework in the same sentence, and say which flows you want. Something like: wire up this specific auth provider in this specific framework, with email sign-in and Google sign-in, protected routes, and a sign-out that clears the session. Specificity here is the difference between the agent following a documented integration path and the agent inventing one.

Gate Two - Session Handling, Where the Sharp Edges Are

The session gate is where a good-looking build most often goes wrong, because the mistakes are invisible in the browser. The app works. It just also works for people it should not.

  • Verify on the server, on every request. Not once at login, not in a layout component, not in the router. Every server route that touches private data checks the session itself.
  • Do not keep tokens where another script can read them. Prefer the httpOnly cookie your provider offers over anything the page's own JavaScript can reach.
  • Make sign-out actually end the session server-side. Clearing local state and redirecting to the home page looks identical to the user and is not the same thing.
  • Check expiry and refresh properly. A session that never expires is a permanent key handed to whoever eventually gets a copy.
  • Keep secrets out of the client bundle. Anything shipped to the browser is public, no matter what it is named.

The test is blunt and it takes two minutes. Sign out, then call a protected API route directly with no session at all. You should get a refusal. If you get data, the gate is not there, whatever the login screen suggested.

Gate Three - Authorization, the One Everyone Forgets

Authorization answers a narrower question than authentication: not are you a real user, but are you allowed to touch this record. Being signed in is not permission. On most small builds this is the gate that is simply missing, because the app was built and tested by one person who only ever had their own data in front of them.

The failure looks like this. A route fetches an item by the identifier in the URL, checks that a valid session exists, and returns the item. Any signed-in user can change the number in the URL and read somebody else's record. The session check passed, so it feels secure. Nothing checked ownership.

  1. Every fetch of a single record filters by the current user's identifier as well as the record identifier, in the query itself.
  2. Every write checks ownership before it writes, not after.
  3. Role checks live on the server. A hidden admin button is not an access control, it is a hidden button.
  4. If your database supports row-level security, turn it on and treat it as the backstop, not as the only check.

The Review Pass - Make the Agent Attack Its Own Build

Run the security review as a separate task in a fresh session, not as the last line of the build request. In the build session the agent has spent an hour establishing that the work is going well, and asking it to critique that same work in the same breath gets you a summary rather than an audit. A clean session reading the code cold is a genuinely different reviewer.

Give it a specific brief. Ask it to list every server route, state which of the three gates each one enforces and on which line, and flag every route that returns data without verifying both session and ownership. A list with line numbers is checkable. A paragraph saying the authentication looks solid is not.

  1. Call a protected route with no session. Expect a refusal.
  2. Call it with a second user's session and someone else's record identifier. Expect a refusal.
  3. Sign out, press back, and try to use the page you were on. Expect a refusal.
  4. Search the client bundle for anything that looks like a secret. Expect nothing.
  5. Only after all four behave, call it done.

This is the same discipline as any other agent output, which we go into in [how to review Claude Code output before you ship](/blog/review-claude-code-output-before-you-ship). Auth is just the place where skipping it costs the most.

Where This Fits in a Client Build

If you are building for someone else, authentication is a line item with a review attached, not a checkbox on the feature list. Scope it that way out loud. The build is an afternoon and the review pass is its own block of time, and saying so up front is much easier than explaining afterwards why the audit was not included.

It also pairs with the other thing clients quietly assume is handled: payments. If your build has both a login and a checkout, they are the two places where being approximately right is not good enough. We covered the other half in [adding Stripe payments with Claude Code](/blog/add-stripe-payments-to-claude-code).

Free Claude Code drops, straight to your inbox

Short, practical drops on skills, MCP, agents, prompts, and more. No spam, unsubscribe anytime.

Frequently asked questions

Can Claude Code build a complete authentication system?

It can produce a working sign-up, sign-in and protected-route setup quickly, especially when you point it at a managed auth provider and name your framework. What it will not reliably do on its own is enforce ownership checks on every record and refuse unauthenticated requests at every server route, because those parts are invisible in the browser and therefore rarely part of the request you made. Build with the agent, then review against the three gates.

Should I let Claude Code write custom auth instead of using a provider?

No, for the same reason you would not hand-roll it yourself. Authentication is not hard to write once, it is hard to keep correct for years as standards shift and edge cases surface, and account recovery alone is a security surface most small projects get wrong. A managed provider makes those problems someone else's ongoing job, which is exactly what you want on a build you will not be staring at every week.

How do I test that my authentication actually works?

Sign out and call a protected API route directly with no session, then create a second account and try to read the first account's records while signed in as the second. Those two tests catch the overwhelming majority of real holes in small builds. If both are refused by the server and no secrets appear in your client bundle, you are in decent shape.

What is the difference between authentication and authorization?

Authentication establishes who someone is, authorization decides what that person is allowed to do. A valid session proves a user is signed in; it says nothing about whether they may read a particular invoice or delete a particular project. Most small-build security bugs are authorization bugs sitting behind working authentication, which is why the checklist treats them as two separate gates.

Is it safe to store an auth token in local storage?

Prefer the httpOnly cookie your provider offers, because anything the page's own JavaScript can read can also be read by a script that gets injected into your page. It is not that local storage is guaranteed to be exploited, it is that the cookie option costs you nothing and removes a category of risk. Take the free win.

Last reviewed by David Iya on August 18, 2026

David Iya

Written by

David Iya

Forbes 30 Under 30 · Y Combinator

Keep reading

Claude CodeWorkflows

Why Is Claude Code Slow? The Real Causes and How to Speed It Up

Claude Code is usually slow for one of three reasons: the context you are sending is too big, the tools it is running are the actual bottleneck, or you picked a heavier model than the task needs. Here is the Slow Loop Audit I run to find which one it is in about five minutes.

David Iya 9 min
Read article

Ready to build it yourself?

Join Claude Code Club, the #1 community for learning claude code, for $9/month.

← Back to the blog