Loomis
Configuration

Google sign in

From an empty Google Cloud project to a working Google button, with the exact addresses to paste and what each error means.

Two names, GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET, and roughly ten minutes in the Google Cloud console. Both names are read by the deployment, not by the app.

Which of the two Google flows is this

This is sign in: somebody uses their Google account instead of a password, and the installation learns their email address. It is not a Gmail connection and it asks for no access to anybody's mail, files or calendar. The only things requested are the identity claims: who they are and their address.

Before you start, know your two addresses

Have these two in front of you. Every paste below is one of them.

WhatOn a laptopOn a server
The app's address, which is SITE_URLhttp://localhost:3000https://loomis.your-domain.com
The deployment's site URLprinted by npx convex devshown in the Convex dashboard

The deployment's site URL looks like https://quick-fox-1234.convex.site. Both addresses stay usable at the same time, which is what makes local development work against the same Google client.

The walkthrough

Create a project

Go to console.cloud.google.com, open the project picker at the top, choose New project, name it after your product, and create it.

A company that already has a Workspace account can put this project inside that organisation instead, which is a better idea if the product belongs to the company rather than to you personally.

APIs & Services → OAuth consent screen. Four fields matter:

FieldWhat to put
User typeExternal, or Internal if the installation is only for your Workspace
App nameThe name of your product, which is what people see on the consent page
User support emailAn address people can write to if they are confused
Developer contactYour address, for Google to reach you

Save and continue. On the scopes step, the defaults are enough: openid, the email claim and the basic profile claim. All three are non-sensitive, which means no review and no verification delay.

External and still in testing

While the app is in Testing, only the accounts you list as test users can sign in, and the others are refused with a message that says the app is not configured for them. Add yourself and anybody who needs to try it, or press Publish app when you are ready for everybody. Publishing with only these three scopes needs no review.

The client

APIs & Services → Credentials → Create credentials → OAuth client ID, and choose Web application as the type. This is the only type that can hold a redirect address, which is what this flow needs.

Authorized JavaScript origins:

http://localhost:3000
https://loomis.your-domain.com

Authorized redirect URIs, both of them, one per line:

http://localhost:3000/api/auth/callback/google
https://loomis.your-domain.com/api/auth/callback/google
https://quick-fox-1234.convex.site/api/auth/callback/google

Why two callback addresses and not one

The app forwards every authentication request to the deployment, where the account functions live, and either address can be the one Google hands the answer back to depending on which one the request arrived at. Google allows a list here, so the safe answer is to list both. Replace quick-fox-1234 with your own deployment's name, from the address npx convex dev printed.

Copy the two values

The dialog shows the client ID and the client secret. The secret is shown once, and it is the only value in this page that is actually secret. Copy both.

A client secret is not a client ID

The ID ends in .apps.googleusercontent.com and is public. The secret starts with GOCSPX-. They are pasted into two different fields, and swapping them produces a sign-in that redirects correctly and then fails with no useful message.

Set them on the deployment

npx convex env set GOOGLE_CLIENT_ID "1234567890-abcdef.apps.googleusercontent.com"
npx convex env set GOOGLE_CLIENT_SECRET "GOCSPX-your-secret"

Add --prod when you are configuring the production deployment. Set both, in the same environment: the pair is read together and a half-configured provider is treated as unconfigured.

Try it

Open /sign-in, press Google, and pick an account. The consent screen appears, you are returned to the installed app, and you land signed in.

If the installation is set to invite-only in System → Security, a Google sign in for an unknown address is refused after the consent screen, with the reason. That is the policy working, not the provider failing.

When it does not work

Turning it off later

Delete the two names from the deployment's environment and the button goes back to saying the provider is not configured:

npx convex env unset GOOGLE_CLIENT_ID
npx convex env unset GOOGLE_CLIENT_SECRET

Accounts that were created through Google still exist and still have their data. They can be given a password by the person who owns them through the reset flow, as long as mail is configured.