diff --git a/GOOGLE_OIDC_ONBOARDING.md b/docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md similarity index 70% rename from GOOGLE_OIDC_ONBOARDING.md rename to docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md index 5b8a395871..844facb096 100644 --- a/GOOGLE_OIDC_ONBOARDING.md +++ b/docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md @@ -6,7 +6,7 @@ backend half; the client/BFF half (running the actual Google login) is covered by `docs/GOOGLE_OIDC_ONBOARDING.md` in the API-Explorer-II repo. For the **why** behind these controls (public vs. operator-controlled IdPs, -the threat model), read `OAUTH2_IDENTITY_PROVIDERS.md` first — this file is the +the threat model), read `../OAUTH2_IDENTITY_PROVIDERS.md` first — this file is the step-by-step runbook. --- @@ -28,6 +28,46 @@ is hard-coded with: So onboarding is **configuration only** — no code change. +## Google Cloud Console onboarding (getting a client ID) + +Before configuring OBP-API you need a Google OAuth **client ID** — that is the +value that goes into `oauth2.google.allowed_audiences`. It is created in the +Google Cloud Console, once per client app (Explorer, Manager, ...): + +1. **Create / pick a project** — , project + selector → *New Project* (or reuse an existing one). No Google APIs need to + be enabled for plain OIDC sign-in. +2. **Configure the OAuth consent screen** — *APIs & Services → OAuth consent + screen* (branding): + - User type: **External** (any Google account) or **Internal** (only your + Google Workspace org — a cheap allowlist if all users share one org). + - App name, support email, developer contact — what users see on the + Google login prompt. + - Scopes: `openid`, `email`, `profile` are enough; they are non-sensitive, + so **no Google verification review is needed**. + - While *Publishing status* is **Testing**, only explicitly added test + users can log in; switch to **In production** to open it up. +3. **Create the OAuth client** — *APIs & Services → Credentials → Create + Credentials → OAuth client ID*: + - Application type: **Web application**. + - **Authorized redirect URIs**: the *client/BFF's* callback URL (e.g. the + Explorer II BFF's `/auth/google/callback`) — **not** an OBP-API URL. + OBP-API never appears in the Google flow; it only receives the resulting + id_token as a Bearer. The exact URI is documented in the client repo + (API-Explorer-II `docs/GOOGLE_OIDC_ONBOARDING.md`). + - **Authorized JavaScript origins**: the client's origin(s), if it uses a + browser-side flow. +4. **Copy the client ID** — it looks like + `1234567890-abc123.apps.googleusercontent.com`. This is the token's + `aud`/`azp`, and the value you list in `oauth2.google.allowed_audiences` + below. The **client secret** stays with the client/BFF; OBP-API never + needs it (signature verification uses Google's public JWKS). + +Repeat step 3 for each app that should sign in via Google, and list every +resulting client ID in the audience allowlist. One client ID per app — see +`../OAUTH2_IDENTITY_PROVIDERS.md` for why sharing one ID across apps weakens the +`(azp, iss)` consumer granularity. + ## Required props Edit your `props` file (in `obp-api/src/main/resources/props/sample.props.template`, @@ -124,7 +164,7 @@ curl -s http://localhost:8080/obp/v5.1.0/users/current \ --- -**Related:** `OAUTH2_IDENTITY_PROVIDERS.md` (trust model & security rationale), +**Related:** `../OAUTH2_IDENTITY_PROVIDERS.md` (trust model & security rationale), `obp-api/src/main/scala/code/api/OAuth2.scala` (`object Google`), `obp-api/src/main/resources/props/sample.props.template` (OAuth2 section), API-Explorer-II `docs/GOOGLE_OIDC_ONBOARDING.md` (client/BFF side). diff --git a/OAUTH2_IDENTITY_PROVIDERS.md b/docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md similarity index 100% rename from OAUTH2_IDENTITY_PROVIDERS.md rename to docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md diff --git a/obp-api/src/test/scala/code/api/OAuth2ConsumerResolutionTest.scala b/obp-api/src/test/scala/code/api/OAuth2ConsumerResolutionTest.scala index 24631ca260..e9f68b3c35 100644 --- a/obp-api/src/test/scala/code/api/OAuth2ConsumerResolutionTest.scala +++ b/obp-api/src/test/scala/code/api/OAuth2ConsumerResolutionTest.scala @@ -16,7 +16,7 @@ import java.net.URI * Executable specification of how OAuth2/OIDC id_tokens are resolved to Consumers * (OAuth2Login.OAuth2Util.getOrCreateConsumer -> MappedConsumersProvider.getOrCreateConsumer). * - * The contract under test (see OAUTH2_IDENTITY_PROVIDERS.md, "Google client ID policy"): + * The contract under test (see docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md, "Google client ID policy"): * - granularity is one Consumer per (azp, iss) — per OAuth client per issuer, NOT per user; * the sub claim is stored on the Consumer but is not part of the lookup key * - a pre-registered Consumer whose key equals the OAuth2 client ID takes priority over