---
name: google-cloud-console-oauth
description: The shared Google Cloud Console / Google Auth Platform mechanics behind every Google OAuth2 registration — creating the project, configuring the consent app, creating a Web application client, redirect-URI rules, scope tiers and declaration, the one-time client secret, Testing vs In production, verification and the restricted-scope security assessment. Read this first when registering any Google OAuth client; the product skills (Google APIs, Google Ads, Google Business Profile, Google Drive) build on it and cover only what is specific to their API. Use directly when the task is a plain Google OAuth client with no particular Google product named.
---

# Google Cloud Console — shared OAuth2 registration mechanics

Everything common to registering an OAuth 2.0 client for **any** Google API: the project, the Google Auth Platform
app, the Web application client, redirect URIs, scope tiers, the secret, publishing status, and verification.

The product skills — Google APIs, Google Ads, Google Business Profile, Google Drive — assume this file and cover only
what their API adds on top (a developer token, an access-request form, a restricted-scope decision). **Read this
first, then the product skill.** If you are registering a plain Google OAuth client with no particular product in
play, this file is the whole job.

**Some products have a second console.** Google Ads (manager account, Terms signature, API Center) and Google Business
Profile (an access-request form) gate access outside the Cloud Console entirely. Where the product skill says so, a
finished Cloud project is only half the credential.

Three things here are expensive to get wrong, and none fail at registration time. **The client secret is shown exactly
once.** **An app left in `Testing` issues refresh tokens that expire in seven days**, which looks like a working
integration for a week and then a mass outage. And **every scope must be declared on the Data Access page**, because
an authorize URL requesting an undeclared scope drops the user onto the unverified-app warning screen even if the app
is otherwise verified.

## Inputs to collect before you start

Ask in one batch. Never invent.

| Input | Notes |
| --- | --- |
| **App name**, user support email, developer contact email | Shown on the consent screen and used by the review team (§3) |
| **Logo** (PNG, square), homepage URL, privacy policy URL, terms URL | Required for publishing and verification (§3, §7) |
| **Which Google account / Cloud organization owns the project** | Decides whether `Internal` is even available (§2) |
| **Redirect URIs** | Every callback host the platform serves (§4) |
| **Scope set** | Exactly what the caller requests — the product skill supplies this (§5) |
| **Audience: internal-only or external customers?** | Changes verification, caps and token lifetime (§3, §7) |
| **New app, or an edit to an existing client?** | A new client ID re-authorizes every customer (§1) |

## Quick Start

1. Confirm a **new client** is needed — existing connections are bound to the current client ID (§1).
2. Sign in, pick or create the Cloud project, and enable the APIs the scopes belong to (§2).
3. Configure the app on the **Google Auth Platform**: Branding, then Audience (§3).
4. Create an OAuth client of type **Web application** — the only common type yielding a usable client secret (§3).
5. Add **every** redirect URI, exactly (§4).
6. Declare every scope on **Data Access**, and request no more than that (§5).
7. **Copy the client secret at creation.** It is never shown in full again (§6).
8. Decide Testing vs In production, and start verification if external (§7).
9. Run a real authorize → callback → refresh round trip from an account that is *not* the project owner (§8).
10. Hand the credentials over — never commit them (§9).

## Platform state (verified 2026-09-20 — re-verify before trusting)

- **The OAuth consent screen is now the "Google Auth Platform."** The console menu item is **Google Auth Platform**,
  split across six pages: **Overview**, **Branding**, **Audience**, **Clients**, **Data Access**, and **Verification
  Center**. Runbooks saying "APIs & Services → OAuth consent screen" describe a single page that no longer exists —
  the settings survived, they moved. Entry point `https://console.cloud.google.com/auth/overview`; clients at
  `https://console.cloud.google.com/auth/clients`.
- **Client secrets are hashed.** The full secret can be viewed and downloaded **only once, at creation**; afterwards
  the console shows the last four characters for identification only. There is no reveal and no second download — the
  recovery path is to create an *additional* secret and disable the old one (§6).
- **Idle and deleted clients are reclaimed.** A client unused for six months is deleted automatically. A deleted
  client is recoverable from the deleted-credentials view for 30 days, then permanently gone.
- **Config changes propagate slowly.** OAuth settings changes can take five minutes to a few hours to take effect. A
  redirect URI that "does not work" immediately after being added is often just not live yet.
- **Restricted scopes require an annual security assessment** under the App Defense Alliance **CASA** framework (§7).

If the console does not look like this, stop and report what you actually see rather than clicking on.

## 1. Decide: reuse the existing client, or create a new one

A new OAuth client means a **new client ID, and every existing customer connection is bound to the old one** — every
customer re-authorizes. Reuse the existing client for: adding a redirect URI, adding or removing a scope, publishing
the app, submitting for verification, or rotating a compromised secret (rotation keeps the client ID; see §6).

Create a **new** client only when the user explicitly wants one: a separate app for a different product, a different
audience (internal vs external), or a deliberate replacement of a compromised client. Say which path you are taking
before touching anything.

Note the asymmetry: **scopes, branding, audience and verification belong to the app/project**, while **redirect URIs
and the secret belong to the client**. Several clients in one project share one consent screen, one verification
state, and one declared scope list. That is usually what you want; it also means a scope added for one client is
requestable by all of them and shows up in the same review.

## 2. Account, organization, and project

- **Sign in / console** — `https://console.cloud.google.com`. Any Google Account can create a project; a Workspace
  account is needed for the `Internal` audience (§3).
- **Create or pick a project.** Prefer a dedicated project for the integration. Verification, scopes and the consent
  screen are project-wide, and a shared project drags unrelated scopes into the review.
- **If the owner has a Google Workspace organization, create the project inside that organization resource.** Google
  recommends this for Workspace developers, and it is what makes `Internal` selectable.
- **Enable the APIs the scopes belong to.** Scopes for APIs that are not enabled do not appear in the Data Access
  picker. Enable them from **APIs & Services → Library**. The product skill says which APIs.
- **Permissions.** Project Owner, or Editor plus the OAuth config rights. A user who can see the project but not edit
  it gets through most of §3 and then fails on Create Client.

Hand control back to the user for anything only a human can do: account creation, billing or organization setup, email
verification, 2FA, accepting terms, and the identity checks Google sometimes inserts. Do not retry a blocked step in a
loop.

**If this session has no browser automation** (the usual case for a CLI or cloud run), do not pretend to click. Hand
the user an exact, ordered click path with the literal values to paste — the redirect URIs from §4 and the scope
strings from the product skill, verbatim — and continue once they report back with the client ID and confirm where
they stored the secret.

## 3. Configure the app and create the client

Work the Google Auth Platform pages in this order; the console asks for the app registration before the client anyway.

**Branding** (`console.cloud.google.com/auth/branding`) — app name, user support email, logo, home page, privacy
policy link, terms link, authorized domains, developer contact email. This is what a customer reads on the consent
screen and what a reviewer checks, so fill it from what the user supplied rather than approximating. Two traps:

- The **app name and logo are only shown to users once the brand is verified**; before that users see the app's domain
  instead. **Branding cannot be edited while a verification is in progress** — finish the text before submitting.
- **Authorized domains** must be domains the owner controls and has verified in Google Search Console. Homepage and
  privacy policy must live on one of them.

**Audience** (`console.cloud.google.com/auth/audience`) — two independent settings, both consequential:

| Setting | Meaning |
| --- | --- |
| **User type: Internal** | Only members of the owning Workspace organization can authorize. No verification, no unverified-app screen, no 100-user cap. Only available when the project sits in an organization. Wrong for a multi-tenant connector serving other companies. |
| **User type: External** | Any Google Account can authorize. What a customer-facing connector needs — and what brings verification (§7). |
| **Publishing status: Testing** | Only listed test users can authorize, **capped at 100 test users**. Authorizations — and their refresh tokens — **expire seven days after consent**, *unless the only scopes requested are a subset of `openid`, `userinfo.email` and `userinfo.profile`* (or their OpenID Connect equivalents). Identity-only apps are exempt; anything requesting one more scope is not. |
| **Publishing status: In production** | Open to any Google Account. Refresh tokens are no longer time-boxed to seven days. |

The seven-day expiry is the single most misdiagnosed Google OAuth symptom. It is not a client bug, not a rotation
policy, and not fixable in code: it is `External` + `Testing`. Publish the app.

**Data Access** (`console.cloud.google.com/auth/scopes`) — see §5. Do this before creating the client if you can; the
declared list is what verification reviews.

**Clients** (`console.cloud.google.com/auth/clients`) — **Create Client**, then pick the application type:

| Type | Gives a client secret? | Use it when |
| --- | --- | --- |
| **Web application** | **Yes** | A server exchanges the code. The type for a hosted connector. |
| Desktop app | Issued, but treated as a public client | Native apps doing a loopback redirect |
| Android / iOS / Chrome extension / UWP | No | Public clients; PKCE instead of a secret |
| TVs and limited-input devices | Device-flow credential | Device code flow only |
| *Service account* (under IAM, not here) | Key file, not an OAuth client secret | Server-to-server, or Workspace domain-wide delegation — **not** a user-authorizes-us flow |

Pick **Web application**. A service account authenticates as itself, not as a customer's user, and cannot let
arbitrary customers connect their own Google accounts. If someone proposes one for a multi-tenant connector, that is a
design conversation, not a console setting.

## 4. Redirect URIs

On the Web application client: **Authorized redirect URIs → Add URI**, one entry per callback host. Get the list from
the platform owner; for Unified.to these are one per data center:

```
https://api.unified.to/oauth/code          # us (default)
https://api-eu.unified.to/oauth/code       # eu
https://api-au.unified.to/oauth/code       # au
https://api-dev.unified.to/oauth/code      # dev
```

Google's matching is unforgiving, and every failure surfaces at connect time, not at save time:

- The `redirect_uri` sent must match a registered URI **exactly** — case-sensitive, including a trailing slash.
  `.../oauth/code` and `.../oauth/code/` are different URIs. Mismatch returns `redirect_uri_mismatch`.
- **No wildcards**, no fragments, no path traversal (`/..`), no userinfo component, no invalid percent-encoding.
- **HTTPS only.** `http://` is rejected except for `localhost`; raw IPs rejected except localhost IPs.
- The host TLD must be on the public suffix list; `googleusercontent.com` and URL shorteners are rejected.
- **Authorized JavaScript origins** are a separate field for browser-side clients. A server-side connector does not
  need them; leave the field empty rather than guessing.
- Changes take **five minutes to a few hours**. Add the URI, then wait before concluding it is broken.
- Testing through Google's **OAuth Playground** needs `https://developers.google.com/oauthplayground` registered as
  its own redirect URI. Remove it before the client goes to production.

## 5. Scope mechanics

The product skill supplies the scope strings. This section is how Google treats them.

Scopes are **space-delimited** in the authorize URL, and each is a full URL (except `openid`, `profile`, `email`).
Two lists must agree:

1. What the **Data Access** page declares.
2. What the authorize URL actually requests.

Requesting an **undeclared** scope shows the unverified-app warning screen — Google states this happens even if the
app is otherwise verified. Declaring scopes you never request is its own problem: it widens the verification review
and invites questions you cannot answer. Keep them equal.

Three tiers, and the console labels each scope for you:

| Tier | Examples | Cost |
| --- | --- | --- |
| **Non-sensitive** | `openid`, `profile`, `email`, `.../auth/userinfo.email`, `.../auth/userinfo.profile` | None |
| **Sensitive** | Calendar, Contacts/People, Sheets, Docs scopes | App verification: brand check + demo video + justification |
| **Restricted** | Gmail scopes that can read a mailbox, and Drive scopes other than `drive.file` and `drive.appdata` | Verification **plus** an annual CASA security assessment (§7) |

The restricted list is explicit and worth checking against the exact strings you plan to request — `https://mail.google.com/`,
`.../auth/gmail.readonly`, `.../auth/gmail.metadata`, `.../auth/gmail.modify`, `.../auth/gmail.insert`,
`.../auth/gmail.compose`, `.../auth/gmail.settings.basic`, `.../auth/gmail.settings.sharing`, and `.../auth/drive`,
`.../auth/drive.readonly`, `.../auth/drive.metadata`, `.../auth/drive.metadata.readonly`, `.../auth/drive.activity`,
`.../auth/drive.activity.readonly`, `.../auth/drive.scripts`, `.../auth/drive.meet.readonly`.

**Not every Drive scope is restricted.** `drive.file` (files the app created or the user explicitly picked) and
`drive.appdata` (a hidden app-private folder) sit outside the restricted tier. Where a product can live with per-file
access, `drive.file` removes an entire annual assessment from the roadmap — a product decision to raise, not to take.
Gmail's equivalent is narrower but real. Every Gmail scope that can **read** a mailbox is restricted — including
`gmail.readonly` and `gmail.metadata`, so "metadata only" buys nothing. But **`gmail.send` is sensitive, not
restricted**, and `gmail.labels` is non-sensitive: an app that only injects outbound mail escapes the assessment
entirely, at the cost of being unable to read, list, search or thread anything. See the Gmail product skill.

**Meet spans tiers, and Google publishes them in one place** — the Meet REST API authentication guide, not the
restricted-scopes list. `meetings.space.settings` is non-sensitive; `meetings.space.created` and
`meetings.space.readonly` are sensitive; **all Meet Media API scopes are restricted**. Adding a Meet link to an event
needs only the Calendar event scope, but **downloading a recording or transcript reads the file through Drive**, which
pulls in a restricted Drive scope and the assessment with it. See the Meet product skill.

**The restricted list below is not exhaustive for every API.** It is Google's Cloud restricted-scopes list, which does
not mention Meet at all — yet the Meet Media API scopes are restricted per that API's own page. Check the product
API's own auth page as well as this list before concluding a scope is cheap.

**A product API's own scope is often cheap; the scope that *finds* the data is what costs.** Docs, Sheets and Slides
each address a file by ID and cannot list or search — discovery comes from Drive. So a sensitive-tier product API
becomes a restricted-tier project the moment `drive.readonly` or `drive` is added for enumeration, while `drive.file`
plus the Picker keeps it sensitive. Check what the product skill says before assuming the product scope sets the tier.

**Proving a scope is "sensitive" is a negative test.** Google publishes an exhaustive *restricted* list but no
exhaustive sensitive list, so the resolution path is: confirm the scope is absent from the restricted list, then read
the tier label the console shows for it on the Data Access page. Do not assert a tier from a doc page's prose.

**The tier of the app is the tier of its most sensitive scope.** One restricted scope moves the whole project into
restricted verification, and adding one later can force an out-of-cycle re-assessment.

### Getting a refresh token at all

Google returns a refresh token **only** when `access_type=offline` was set, and **only on the first authorization**
for that user/client pair. A later authorize without `prompt=consent` returns an access token and silently no refresh
token, because the user was not re-prompted. A connector that reconnects an already-connected account and stores no
refresh token is almost always missing `prompt=consent`.

Other refresh-token rules worth knowing before you debug one: **100 live refresh tokens per Google Account per client
ID** (the 101st silently invalidates the oldest) and expiry after **six months** of non-use. Individual Google APIs
add their own invalidation rules on top — the product skill says which.

## 6. Capture the credentials

At **Create**, the console shows the client ID and client secret and offers a JSON download. **This is the only time
the full secret exists outside Google.** Copy or download it immediately, into a secret manager. Afterwards the
console shows only the last four characters, because the secret is stored hashed.

Capture:

- **Client ID** (ends in `.apps.googleusercontent.com`) and **client secret**
- **Project ID / number** and the owning account or organization
- **Authorize URL** `https://accounts.google.com/o/oauth2/v2/auth` and **token URL** `https://oauth2.googleapis.com/token`
- The declared scope list, verbatim
- Audience (Internal/External) and publishing status (Testing / In production)

**Rotation is add-then-disable, not replace.** Because secrets cannot be re-read: create a second secret on the same
client, deploy it, confirm every environment exchanges and refreshes successfully, then disable the old one. The
client ID and all existing refresh tokens survive — no customer re-authorizes. Disabling the old secret before the
deploy lands breaks every exchange and refresh until the new one is live, so never rotate without a cutover plan and
explicit go-ahead.

Report the secret once so the user can paste it into their secret store, say plainly that it is now in the transcript
and can be rotated, then move on.

## 7. Verification, review, and limits

For an `Internal` app none of this applies — that is its whole appeal and its whole limitation. Everything below is
about `External`.

**The caps.** Two different 100s, often confused:

- `Testing` allows at most **100 test users**, each added by email address, and their grants expire after seven days.
- A published-but-unverified app that triggers the unverified-app screen is capped at **100 new users over the
  project's lifetime**. That cap is not reset by unpublishing and republishing; it is why "we'll verify later" becomes
  a hard stop at customer 101.

**The unverified-app screen.** Until brand and scopes are verified, customers see a warning instead of the app name
and logo and must click through an *Advanced* link. Enterprise security teams routinely stop there. Treat verification
as part of launch, not follow-up.

**What the review asks for** — each layer adds to the last:

1. **Brand** — homepage on a domain verified in Google Search Console and owned by the app's owner, a privacy policy
   on that domain linked from both the homepage and the consent screen, accurate app identity, current contacts.
2. **Sensitive scopes** — a justification for each scope explaining why the narrowest alternative is insufficient, and
   an **unlisted YouTube demo video** showing the end-to-end OAuth grant in English, with the app name on the consent
   screen and the client ID visible in the address bar. Google quotes roughly **3–5 business days** when nothing needs
   clarification. That figure covers this sensitive-scope review only; Google publishes no turnaround for the
   restricted-scope assessment below.
3. **Restricted scopes** — all of the above, plus a **CASA security assessment** through the App Defense Alliance,
   performed by an external assessor against the OWASP ASVS. Google assigns an **assurance level (AL1 or AL2)** by a
   risk-based evaluation of user count, requested scopes and other signals; an app that reaches AL2 stays there in
   later years, and the required level can rise as the user base grows. **All applications must be revalidated every
   year.** Passing produces a Letter of Validation.

   Treat cost and turnaround as unknown until an assessor quotes them. Google does not publish assessor fees or
   assessment timelines, and figures circulating in third-party write-ups are not on any current Google page. Budget
   for a real engagement and get the number from the assessor. Older material calls the levels "Tier 2 / Tier 3";
   the current vocabulary is AL1 / AL2.

**Verification is not the only gate.** Some restricted scopes also carry **eligibility rules**: Google grants them
only to apps in particular categories, so an app outside those categories cannot qualify however complete its
paperwork. Check the product skill before budgeting an assessment for a scope the app can never be granted.

**Exemptions exist beyond `Internal`.** Google documents several cases that do not need the full review — read the
current verification-requirements page rather than assuming; the product skill flags the ones affecting its API.

**Additional (non-core) Google services are a second Workspace switch.** Analytics, YouTube, Blogger and others are
"additional services" a Workspace admin can turn off per organizational unit, independently of the API controls
below. The failure has a different owner and a different remedy — the customer enables the service for that OU. The
product skill says whether its API is one of these.

**Workspace customers can block you regardless.** A customer's Workspace admin controls third-party app access under
*Security → Access and data control → API controls*, and can mark an app trusted, limited or blocked, or block
unconfigured apps wholesale. When exactly one customer cannot connect and everyone else can, check this first — the
fix is theirs: they allowlist the client ID. Note the blast radius when an admin flips that switch the other way:
marking a Google service restricted **revokes existing tokens immediately** for apps the domain does not trust, so a
whole customer can break overnight with no change on your side. A different Workspace failure looks similar but is not this: when the
underlying Google *service* is switched off for the account, calls fail with `403 PERMISSION_DENIED` no matter how the
app is allowlisted. The product skill says whether its API has that mode. Domain-wide delegation is an admin-side pre-authorization path, not a
workaround for a failing user consent.

**Stop and ask** rather than answering on the user's behalf: scope justifications, data-handling and retention claims,
privacy-policy wording, Limited Use attestations, security-questionnaire answers, choice of assessor, and anything
with a dollar figure. A plausible guess in a verification form is worse than a delay.

## 8. Verify end-to-end

Authorizing with the account that owns the project proves very little — it is a test user, an org member, or both.
Test the path a customer takes:

1. Authorize from an account that is **not** the project owner, through the platform's real connect flow. In
   `Testing`, that account must be on the test-user list; if that feels like a blocker, it is the signal to publish.
2. Confirm the token response contains a **`refresh_token`**, not just an `access_token`.
3. Confirm the granted `scope` matches what was requested — Google returns what the user actually approved, which can
   be less when a granular-consent screen let them uncheck something.
4. **Force a refresh** and make a real API call with the refreshed token.
5. Re-run the whole flow on an **already-connected** account and confirm a refresh token comes back again. That is the
   test that catches a missing `prompt=consent`.
6. If the app is still in `Testing`, say so explicitly in the handoff: the connection dies in seven days.

| Symptom | Cause |
| --- | --- |
| `redirect_uri_mismatch` | The sent `redirect_uri` is not character-for-character a registered URI (§4) — check the trailing slash, then propagation |
| `invalid_client` / `unauthorized_client` | Wrong client ID or secret, wrong client type, or a secret disabled during rotation (§6) |
| `access_denied` right after the account picker | App in `Testing` and the account is not a test user, or `Internal` audience and the account is outside the organization (§3) |
| `invalid_scope`, or the unverified-app screen on a verified app | A requested scope is not declared on Data Access (§5) |
| No `refresh_token` in the token response | Missing `access_type=offline`, or a repeat authorization without `prompt=consent` (§5) |
| Every connection dies almost exactly one week after connecting | `External` + `Testing` seven-day grant expiry (§3) |
| Connections die after a quiet six months | Refresh token unused for six months and expired (§5) |
| Oldest connections for one heavy user drop silently | 100 live refresh tokens per account per client ID (§5) |
| Exactly one customer cannot connect | Their Workspace admin's API controls (§7) |
| Signups stop at around 100 total customers | Unverified-app lifetime user cap (§7) |
| `403` with `accessNotConfigured` on the first API call | The API for that scope is not enabled in the project (§2) |
| `403` with `rateLimitExceeded` / `userRateLimitExceeded` | Quota, not authorization. Back off and retry — do not re-authorize. Several Google APIs signal throttling as 403 rather than 429 |

## 9. Hand off — never commit the secret

- **Do not** write the client secret into source control, a test, a fixture, a committed `.env`, a ticket, a PR body,
  or a chat channel. Values go to the user, for a secret store or console. **The downloaded client JSON is the
  secret** — it contains it.
- If a code change is needed (a redirect host, a scope, `access_type` / `prompt` handling), keep it secret-free and
  say what the human must set out of band.
- Close with: app name, project, and owning account/organization; client ID; client type (Web application); where the
  secret was delivered and that it cannot be re-read; the authorize and token endpoints; the exact declared scope
  strings and their tier; audience and publishing status; verification state and what it still needs; and anything
  left for the user to do — especially "publish before real customers connect" if the app is still in `Testing`.

## Stop and ask

Hand back to a human rather than guessing when: the scope set is restricted-tier and nobody has budgeted for a CASA
assessment and its annual renewal; someone asks you to write scope justifications, privacy-policy text,
data-retention claims or security-questionnaire answers; the app needs a new client ID and existing customers would
have to re-authorize; a secret must be rotated on a live integration; `Internal` vs `External` is genuinely open (it
changes the product, not just the console); a customer's Workspace admin has to allowlist the client; or the console
does not match the **Platform state** section above.

## References

- Get started with the Google Auth Platform — https://support.google.com/cloud/answer/15544987?hl=en
- Manage OAuth App Branding — https://support.google.com/cloud/answer/15549049?hl=en
- App Identity & Branding — https://support.google.com/cloud/answer/13804963?hl=en
- Manage App Audience (user type, publishing status, test users) — https://support.google.com/cloud/answer/15549945?hl=en
- Manage OAuth Clients (client types, one-time secret, deletion, propagation) — https://support.google.com/cloud/answer/15549257?hl=en
- Manage App Data Access (declaring scopes) — https://support.google.com/cloud/answer/15549135?hl=en
- Restricted Scopes — the authoritative list — https://support.google.com/cloud/answer/13464325?hl=en
- Verification requirements — https://support.google.com/cloud/answer/13464321?hl=en
- OAuth App Verification Help Center — https://support.google.com/cloud/answer/9110914?hl=en
- Requesting minimum scopes — https://support.google.com/cloud/answer/13807380?hl=en
- Security Assessment (CASA, AL1/AL2) — https://support.google.com/cloud/answer/13465431?hl=en
- Annual Recertification — https://support.google.com/cloud/answer/13463816?hl=en
- Using OAuth 2.0 to Access Google APIs (refresh token expiry rules) — https://developers.google.com/identity/protocols/oauth2
- OAuth 2.0 for Web Server Applications (redirect URI rules, `access_type`, `prompt`) — https://developers.google.com/identity/protocols/oauth2/web-server
- OAuth 2.0 Policies — https://developers.google.com/identity/protocols/oauth2/policies
- OAuth 2.0 Scopes for Google APIs — https://developers.google.com/identity/protocols/oauth2/scopes
- OAuth app state overview (testing / published / verified) — https://developers.google.com/identity/protocols/oauth2/production-readiness/overview
- Brand verification — https://developers.google.com/identity/protocols/oauth2/production-readiness/brand-verification
- Sensitive scope verification (demo video, 3–5 business days) — https://developers.google.com/identity/protocols/oauth2/production-readiness/sensitive-scope-verification
- Restricted scope verification — https://developers.google.com/identity/protocols/oauth2/production-readiness/restricted-scope-verification
- Additional considerations for Google Workspace — https://developers.google.com/identity/protocols/oauth2/production-readiness/google-workspace
- Configure the OAuth consent screen and choose scopes — https://developers.google.com/workspace/guides/configure-oauth-consent
- Control which third-party apps access Google Workspace data (admin API controls) — https://support.google.com/a/answer/7281227?hl=en
