From a0332f378ee8ea2699365bf94a8835436d59b058 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 13 Jul 2026 14:10:05 +0200 Subject: [PATCH 1/2] docs: add Google Cloud Console onboarding section at GOOGLE_OIDC_ONBOARDING.md Document the Console half of onboarding: project setup, OAuth consent screen (user type, non-sensitive scopes, publishing status), OAuth client creation (redirect URI belongs to the client/BFF, never OBP-API), and how the resulting client ID feeds oauth2.google.allowed_audiences. Notes the client secret stays with the BFF and cross-references the (azp, iss) one-client-per-app rationale in OAUTH2_IDENTITY_PROVIDERS.md. --- GOOGLE_OIDC_ONBOARDING.md | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/GOOGLE_OIDC_ONBOARDING.md b/GOOGLE_OIDC_ONBOARDING.md index 5b8a395871..3f0c0b1b87 100644 --- a/GOOGLE_OIDC_ONBOARDING.md +++ b/GOOGLE_OIDC_ONBOARDING.md @@ -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`, From 03820be6e7945ac312680f027fba9509087ae727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Mili=C4=87?= Date: Mon, 13 Jul 2026 14:15:58 +0200 Subject: [PATCH 2/2] docs: move OAuth2/OIDC identity-provider docs into docs/IdP/ OAUTH2_IDENTITY_PROVIDERS.md -> docs/IdP/, GOOGLE_OIDC_ONBOARDING.md -> docs/IdP/Google/ (provider-specific runbooks get a subfolder per IdP). Update the cross-references: the Google doc now points at ../OAUTH2_IDENTITY_PROVIDERS.md and the OAuth2ConsumerResolutionTest header comment at docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md. --- .../IdP/Google/GOOGLE_OIDC_ONBOARDING.md | 6 +++--- .../IdP/OAUTH2_IDENTITY_PROVIDERS.md | 0 .../test/scala/code/api/OAuth2ConsumerResolutionTest.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename GOOGLE_OIDC_ONBOARDING.md => docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md (97%) rename OAUTH2_IDENTITY_PROVIDERS.md => docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md (100%) diff --git a/GOOGLE_OIDC_ONBOARDING.md b/docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md similarity index 97% rename from GOOGLE_OIDC_ONBOARDING.md rename to docs/IdP/Google/GOOGLE_OIDC_ONBOARDING.md index 3f0c0b1b87..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. --- @@ -65,7 +65,7 @@ Google Cloud Console, once per client app (Explorer, Manager, ...): 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 +`../OAUTH2_IDENTITY_PROVIDERS.md` for why sharing one ID across apps weakens the `(azp, iss)` consumer granularity. ## Required props @@ -164,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