glimfly
security updated

What is OAuth? (how Sign in with Google actually works)

In one sentence:OAuth is a protocol that lets you grant one app limited access to your account on another service (Google, GitHub, etc.) without ever handing that app your password.

What it actually is

OAuth is a protocol that lets you give one app permission to access part of your account on another service, without ever typing your password into that first app. Think of a visitor badge at a partner company’s office: you don’t get handed a master key. The front desk checks your ID, then gives you a badge that opens the lobby and one meeting room, nothing else, and it stops working at 6pm. That badge is roughly what an “access token” is: proof, scoped to specific permissions, that expires.

There’s a detail worth knowing even if you never touch the code: OAuth on its own is about authorization, granting access to data, not about proving who someone is. When you see “Sign in with Google,” an identity layer called OpenID Connect rides on top of OAuth and adds that missing piece: an ID token that actually confirms who the user is, alongside the access token that says what they’re allowed to reach. In practice you’ll rarely need to separate the two, but it’s why “OAuth login” and “OAuth access” can mean slightly different things depending on who’s talking.

Why your AI just did this

Building your own login system means storing passwords safely, hashing them, handling “forgot password” emails, and being liable if that database ever leaks. Most agents route around all of that by wiring up “Sign in with Google” (or GitHub, or Apple) through a library like Supabase Auth, Clerk, Auth.js, or Firebase Auth instead.

To do it, your agent registers your app in that provider’s developer console (Google Cloud Console, GitHub’s OAuth Apps settings), which hands back a Client ID and a Client Secret. Those get stored as environment variables, never typed into a component. The agent also has to set an exact callback URL, the address the provider is allowed to redirect back to once a user approves. When someone clicks the button: your app sends them to Google, Google shows the “allow this app to see your email?” screen, and if they say yes, Google redirects back to that exact callback URL with a short-lived code your server trades for real tokens.

When you’ll run into it

  • Error 400: redirect_uri_mismatch, the callback URL your app sent doesn’t exactly match one registered in the provider’s console (protocol, domain, port, or trailing slash all count)
  • OAuthAccountNotLinked in Auth.js, someone signed up with email and password first, then tried “Sign in with Google” using the same email, and the two accounts aren’t automatically merged
  • Login works fine on localhost and breaks the moment you deploy, because the production callback URL was never added to the provider’s allowed list
  • Supabase saying the redirect URL isn’t in its allow list, or a provider isn’t enabled yet in its dashboard
  • Your agent asking you to go create an OAuth app in Google Cloud Console or GitHub settings and paste back a Client ID and Client Secret

What to check

  • Client ID and Client Secret are stored as environment variables, never hardcoded in a file that could get committed
  • The callback URL registered in the provider’s console matches, character for character, what your app actually sends, for both your local setup and production
  • Requested scopes are the minimum needed. Ask for name and email, not full inbox access, unless the app actually needs it
  • The Client Secret only ever gets used server-side, it should never be reachable from browser code
  • Local and production each have their own callback URL added; deploying doesn’t carry your localhost settings with it

Say it like a dev

Instead of: “hook up Google login” Say: “add Google as an OAuth provider, store the client ID and secret as environment variables”

Instead of: “it’s giving some redirect error” Say: “getting redirect_uri_mismatch, does the callback URL in the provider console match exactly what we’re sending”

Instead of: “make it so people can just log in with their Google account” Say: “wire up OAuth with Google, requesting only the profile and email scopes”

People actually ask

“Is OAuth actually hard to set up, or is it just me?”

It's fiddly, but not because the idea is hard. The concept is simple: your app redirects to Google, Google checks the user, then redirects back with proof. Almost every failure is one exact-match string being wrong (a redirect URL, a Client ID) rather than a logic bug, which is why it feels harder than it is.

“What's actually different between OAuth login and a regular username and password?”

With a password, your app has to store and protect that password itself. With OAuth, your app never sees it. Google (or GitHub, or whoever) checks the user's identity on its own servers and hands your app a token that just says 'this person is verified, here's what they let you see.' Your app is trusting Google's word, not managing a login system of its own.

“Why does my agent need a Client Secret if it's already using an API key somewhere?”

They're two different keys for two different roles. The Client ID is public, it's fine for anyone to see it in your app's code. The Client Secret proves your specific app (not just any app) is the one asking to exchange a login code for a real access token, and it must stay server-side only, exactly like any other secret credential.

Related terms

Checked against

Glim can explain your sessions, live.

The app watches your coding agent and narrates it in plain words. Waitlist is open.

Join the waitlist