> ## Documentation Index
> Fetch the complete documentation index at: https://docs.37audits.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Sign-In Auditor

> Checks that Google's sign-in screen names your brand, not a technical domain

<Info>
  **Security Auditor**. Checks that the "Sign in with Google" flow is fully set up. Google's account chooser should say "to continue to **your brand**", and not `your-project.firebaseapp.com`, `<ref>.supabase.co` or `<domain>.auth.<region>.amazoncognito.com`. Firebase Auth sites are also checked for an authorized site domain and a working auth handler.
</Info>

<CardGroup cols={2}>
  <Card title="Trust" icon="handshake">
    Visitors see your name at the moment they hand over their Google account.
  </Card>

  <Card title="Working login" icon="right-to-bracket">
    Finds half-finished setups that break the sign-in popup for every visitor.
  </Card>
</CardGroup>

Google's "Choose an account" screen says **"to continue to …"**. When the app's OAuth brand is verified, the text is the app name and logo, such as "37 Audits". When it isn't, Google falls back to the host of the sign-in redirect, which is the identity provider's technical domain: `axecompute---portal.firebaseapp.com` for Firebase Auth, `<ref>.supabase.co` for Supabase Auth, `loginsocial.auth-fips.us-east-1.amazoncognito.com` for Amazon Cognito. Visitors are then asked to trust a host they have never seen, while the address bar shows your site. To many people that looks like phishing.

## Preferences

| Key | Label | Type | Default | Description |
| - | - | - | - | - |
| `signInUrl` | Sign-in page URL | `string` | empty | Optional. The page that shows the Sign in with Google button, when it is not the monitored URL. It can be an absolute `http(s)` URL, even on another host (for example `https://portal.example.com/` for a site at `https://example.com/`), or a path starting with `/` (for example `/login`), resolved against the monitored URL. Empty means the monitored URL. Basic Auth is sent only to the monitored host. |

## How it works

1. **Open the sign-in page in Chromium.** The page is the `signInUrl` preference when it is set, otherwise the monitored URL; an invalid preference ends the audit with `501`. If the site blocks the bot, the audit ends with `590`. If the page doesn't load (timeout, DNS, TLS, a non-2xx answer), it ends with `500`.
2. **Click the Google button.**
   * The auditor first declines the cookie banner with the privacy-preserving choice ("Necessary only", "Reject all", …).
   * It then clicks the first visible button or link whose label names Google: "Continue with Google", "Sign in with Google", "Entrar com Google", or a Google Identity Services button. Links to Google products, such as Google Analytics or Google Maps, are skipped.
   * For an icon-only button, the label is its accessible name (`aria-label`, `title`, `aria-labelledby`, the image's `alt`, the SVG's `title`) or its screen-reader-only text. A textless icon also counts when its `id`, `class` or `data-*` attributes name Google.
   * If no such button shows up within 3 seconds, it clicks one sign-in opener ("Sign in", "Log in", "Get started", …) and looks again.
   * A complete `accounts.google.com/o/oauth2/…` link already in the page is followed without a click.
3. **Capture where it goes.** The auditor records the first request to Google's sign-in pages, from the page, a popup or a redirect hop, and stops it. It works whatever signs the visitor in: Firebase Auth, Supabase Auth, Amazon Cognito, Auth.js, a Next.js Server Action or a backend of the site's own.
4. **Read Google's screen.** The auditor fetches that Google URL once over HTTP and reads the name Google shows after "to continue to", from its `data-app-name` attribute. Nothing else from Google's page is kept; the developer contact email on it is never read.
   * `400` fires when that name is the host of the redirect URI, because that is what Google shows without a verified brand. A brand that looks like a domain, such as "Booking.com", is not flagged.
   * If the click reaches no Google page, or Google's page doesn't name the app, the audit reports `103` and gives no verdict.
5. **Firebase extras.** When the Firebase SDK's popup or iframe shows up in the traffic, the auditor reads its auth domain and API key there.
   * It reads the project's authorized domains with the public Identity Toolkit `getProjectConfig` call the SDK makes, sending the site's origin as `Referer`. If that fails, it reports `102`.
   * If the auth domain is a custom domain, it also requests `https://<authDomain>/__/auth/handler`.
6. **Nothing found.** No Google button: `INFORMATION` (`100`), not applicable and not charged.
7. **Aggregate.** FAIL wins over WARNING, in the order `400`, `401`, `402`. When every rule passes, the audit is `SUCCESS` (`200`), and the message names what Google shows.

## What it audits

Every row maps to one `checkRule*` method and one `CheckCode`, in the order the auditor runs them. CheckCode suffixes use status ranges: `100` information, `200` success, `300–399` warning, `400–499` fail, `500–599` error.

| CheckCode | Status | When it fires | Recommendation | Why it matters |
| - | - | - | - | - |
| <a id="37A-GoogleSignInAuditor-100" />`37A-GoogleSignInAuditor-100` | `INFORMATION` | No "Sign in with Google" button was found on the page, directly or behind a Sign in, Log in or Get started button. Not applicable, not charged. | If the Sign in with Google button is on another page (for example a separate portal such as `https://portal.example.com/`), set it as the Sign-in page URL preference of this auditor. If `{url}` is that page, check that the button's label names Google. | — |
| <a id="37A-GoogleSignInAuditor-103" />`37A-GoogleSignInAuditor-103` | `INFORMATION` | The name on Google's account chooser could not be read: the click sent no request to accounts.google.com, or Google's page did not name the app (a markup change or a bot challenge). | Run the audit again later. If this keeps happening, click the Google button on `{url}` and check that Google's account chooser names your brand. | — |
| <a id="37A-GoogleSignInAuditor-400" />`37A-GoogleSignInAuditor-400` | `FAIL` | Google's account chooser says "continue to `{appName}`", and `{appName}` is the host of the redirect URI: the OAuth brand is not verified. | In Google Cloud Console, open Google Auth Platform > Branding for the OAuth client `{clientId}`: set the app name and logo, add `{site}` as an authorized domain and submit the brand for verification, so Google shows your name instead of `{appName}`. Alternatively, put your own domain on the redirect: a Firebase `authDomain` on your site, a Supabase custom domain, or a Cognito custom domain, with its callback URL added to the OAuth client. | Visitors see an unfamiliar technical domain at the moment they are asked to trust your site with their Google account. Many stop there, and it looks like phishing. |
| <a id="37A-GoogleSignInAuditor-102" />`37A-GoogleSignInAuditor-102` | `INFORMATION` | The authorized domains of Firebase project `{projectId}` could not be read (for example, an invalid or restricted API key). | Check that the Firebase API key `{apiKeyMasked}` is valid and allowed from `{origin}`, then run the audit again. | — |
| <a id="37A-GoogleSignInAuditor-401" />`37A-GoogleSignInAuditor-401` | `FAIL` | The audited host is not one of the Firebase project's authorized domains. Like the Firebase SDK, an entry also covers its subdomains, and an IP entry matches only itself. | Add `{host}` under Firebase Console > Authentication > Settings > Authorized domains of project `{projectId}`. | Sign in with Google fails on this site with an unauthorized-domain error, so visitors cannot log in at all. |
| <a id="37A-GoogleSignInAuditor-402" />`37A-GoogleSignInAuditor-402` | `FAIL` | A custom Firebase `authDomain` answers 404, 5xx or a network error at `/__/auth/handler`. A 403 or 429 there is treated as a bot wall and does not fire. | Proxy `https://{authDomain}/__/auth/*` to `https://{projectId}.firebaseapp.com/__/auth/*`, or connect `{authDomain}` in Firebase Hosting, so the sign-in popup can finish. | The sign-in popup opens on a page that does not exist, so Google sign-in breaks for every visitor. |
| <a id="37A-GoogleSignInAuditor-300" />`37A-GoogleSignInAuditor-300` | `WARNING` | The Firebase project's authorized domains include `localhost` or an IP address. | Remove `{devDomains}` from the authorized domains of Firebase project `{projectId}`, or move development to a separate Firebase project. | Leftover development hosts let pages outside your site start a sign-in flow with your project, which widens the room for account phishing. |
| <a id="37A-GoogleSignInAuditor-200" />`37A-GoogleSignInAuditor-200` | `SUCCESS` | All rules passed. The message quotes what Google's screen says, for example "continue to 37 Audits" (Supabase Auth). | — | — |
| <a id="37A-GoogleSignInAuditor-500" />`37A-GoogleSignInAuditor-500` | `ERROR` | The sign-in page could not be loaded in Chromium (timeout, DNS, TLS, or a non-2xx answer other than a block). | Make `{url}` reachable over HTTP(S) and re-run the audit. Last error was `{error}`. | — |
| <a id="37A-GoogleSignInAuditor-501" />`37A-GoogleSignInAuditor-501` | `ERROR` | The `signInUrl` preference is neither an absolute `http(s)` URL nor a path starting with `/`. | Set the Sign-in page URL of `{url}` to the page that shows the Google button, for example `https://portal.example.com/login` or `/login`, or leave it empty to audit `{url}`. | — |
| <a id="37A-GoogleSignInAuditor-590" />`37A-GoogleSignInAuditor-590` | `ERROR` | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See [https://www.37audits.com/bot](https://www.37audits.com/bot). | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |

## Output documentation

| Status | Description | Test logic |
| - | - | - |
| **SUCCESS** | Google names your brand and sign-in works | Google's screen shows a name that is not the redirect host; for Firebase, the site is authorized and a custom handler answers (`200`). |
| **WARNING** | Sign-in works, but the Firebase project is loosely configured | Development hosts in the authorized domains (`300`). |
| **FAIL** | Sign-in shows a technical domain or is broken | Google names the redirect host (`400`); site not an authorized Firebase domain (`401`); custom Firebase handler missing (`402`). |
| **ERROR** | The auditor could not read the page | Fetch failure or non-2xx answer (`500`); invalid `signInUrl` preference (`501`); site blocked 37AuditsBot (`590`). |
| **INFORMATION** | Nothing to audit, or a part could not be checked | No Google button (`100`); Firebase authorized domains unreadable (`102`); Google's screen unreadable (`103`). |

## Risks and considerations

### Why the name on the account chooser matters

* The account chooser is where a visitor decides to hand their Google identity to your site. A name they do not recognize at that moment is the classic sign of a phishing page.
* Verifying the OAuth brand is the cheapest fix. Set the app name, logo, home page and privacy policy under Google Auth Platform > Branding, add your domain as an authorized domain, and submit the brand for verification.

### Putting your own domain on the redirect

* Changing the redirect host also changes the fallback name, and it hides the provider from the address bar during sign-in.
* **Firebase:** follow "Best practices for using signInWithRedirect". On Firebase Hosting, set `authDomain` to the site's own domain. Otherwise, reverse-proxy `/__/auth/*` to `<project>.firebaseapp.com`.
* **Supabase:** custom domains are a paid add-on (Project Settings > Custom Domains). Point the client at the custom domain.
* **Cognito:** give the user pool a custom domain and set it as the Amplify `oauth.domain`.
* In every case, add the new callback URL to the authorized redirect URIs of the Google OAuth client first. Otherwise Google answers `redirect_uri_mismatch`.

### What this auditor does not check

* The Google button is found by its label or accessible name. An icon with no name and no Google `id`/`class`/`data-*` attribute, or a sign-in flow more than one step deep, ends in `100`. Point the `signInUrl` preference at the page that shows the button.
* The audit clicks the cookie banner's decline button and, when needed, one Sign in, Log in or Get started button on the site. It never types anything or signs in.
* Some bot walls let headless Chromium through and some don't. A blocked sign-in page ends in `590`; allow 37AuditsBot to audit it.
* Google's `data-app-name` attribute is internal markup that Google can change. If it disappears, the audit reports `103` instead of a verdict.
* The Firebase API key is public by design, so finding it is not reported. Messages show it masked.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.