Repository navigation
feat(identity): cut the internal pool over from GoogleSAML to Google - #172
Closed
Alexanderamiri wants to merge 3 commits into
Closed
Alexanderamiri wants to merge 3 commits into
Alexanderamiri wants to merge 3 commits into
Conversation
…ct_account app-auth-sync gives every client it manages (including login-N slot clients) a managed-login branding style with Cognito's defaults, only when it has none, and deletes it with the client; reconcile backfills existing clients. The role may create/describe/delete styles on the two pools only. Prepares the internal pool domain for managed login, which forwards prompt=select_account to Google (the classic hosted UI ignores it): - internal_managed_login_version (default 1, unchanged) gates the switch - the Google provider's authorize_url is plain: Cognito dropped the query string, which left a perpetual plan diff - ALB sign-in rules on the internal pool send prompt=select_account - apps get COGNITO_EXTRA_AUTH_PARAMS=prompt=select_account (internal pool) - auth-doctor sends the same parameters in its authorize probe Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Managed login forwards prompt=select_account to Google, so heroes get the account chooser. Every app client has a branding style from app-auth-sync (previous change), which managed login needs to show a sign-in page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
internal_identity_providers = ["Google"]: every internal app client and auth-claims' FEDERATED_IDENTITY_PROVIDERS move to the Google OIDC provider, which shows Google's account chooser on managed login. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Terraform Plan🚧 Changes detected — Plan: 0 to add, 4 to change, 0 to destroy. Plan outputLLM ReviewRisk: 🟡 MEDIUM Plan updates 4 existing resources in place (0 add, 0 destroy): a Cognito domain managed-login version bump, a Lambda identity-provider env var change, an IAM policy gaining managed-login branding permissions, and a Lambda code/env update.
|
Alexanderamiri
force-pushed
the
feat/cognito-managed-login-v2
branch
from
October 29, 2026 22:05
89e780b to
cb6a0f4
Compare
Alexanderamiri
added a commit
that referenced
this pull request
Oct 30, 2026
…#174) ## Why Before cutting the internal pool over from `GoogleSAML` to the `Google` IdP (#172) we need to know whether managed login forwards `prompt=select_account` from `/oauth2/authorize` to Google. No client lists `Google`, so the redirect cannot be probed today. ## What - **app-auth-sync:** requests owned by team `platform` (`/javabin/apps/platform/...`; `platform` is excluded from registered teams, so only the platform's own Terraform can write there) may set `identity_providers` to override the pool's IdP list. Each IdP must exist in the pool (else status `error`, client untouched). The internal pool never allows `COGNITO`. Any other team's request with the field is `invalid`. - **identity module:** `aws_ssm_parameter.idp_probe_auth` writes `/javabin/apps/platform/idp-probe/auth`. app-auth-sync turns it into client `platform-idp-probe` with a managed-login branding style, like any app client. The client lists `var.internal_idp_probe_identity_providers` (default `["Google"]`). It is created only once the Google IdP exists, and `[]` removes it. - The probe can't be used to sign in: it is a public client with no secret, code flow, callback `https://localhost/idp-probe`, scopes `openid email`, and allowed group `idp-probe-nobody`, which does not exist. auth-claims refuses every token, and the domain check applies as well. - **Docs:** the probe command is in `docs/cognito-google-setup.md` step 3, and the override is described in `docs/lambda-functions.md`. ## How verified - `python3 -m unittest discover -s terraform/lambda-src/tests`: 219 OK. New tests cover the platform override with a branding style, app clients keeping the pool list, other teams being refused, an IdP missing from the pool, and COGNITO/empty/malformed lists. - `python3 -m unittest discover -s scripts/tests`: OK. - `terraform fmt -check -recursive terraform` and `terraform validate`: OK. ## Rollout Merge, then apply. The plan should only create the SSM parameter and update the app-auth-sync Lambda code, with no Cognito pool, domain or client replacement. The Create event, plus the post-apply reconcile, creates the client and its style. Then run the probe from the docs. No app client changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
4 of 8 tasks
Alexanderamiri
added a commit
that referenced
this pull request
Oct 30, 2026
…175) Replaces #172 (auto-closed when its base branch was deleted). Rebased onto main: #170, #173 (managed login) and #174 (IdP probe client) are merged and applied. ## Why GoogleSAML has no account chooser. A browser signed in to a personal Google account hits a dead-end `403 app_not_configured_for_user` (#157). The Google provider on managed login can show Google's account chooser, but only if `prompt=select_account` reaches Google. **DRAFT: do not merge until the checklist below is done.** ## Probe result (2026-10-30, `platform-idp-probe`, client `75ejr2cdi133ictvip1mc32nr3`, lists only `Google`) Each request got a 302 straight to `accounts.google.com/o/oauth2/v2/auth`. Results were the same on repeated runs: | `/oauth2/authorize` extra params | `prompt` in Google URL | `hd` in Google URL | |---|---|---| | `prompt=select_account` | **absent** | absent | | `prompt=select_account&identity_provider=Google` | `prompt=select_account` | absent | | `identity_provider=Google` | absent | absent | | none | absent | absent | | `prompt=select_account&identity_provider=Google&hd=java.no` | `prompt=select_account` | absent | Managed login forwards `prompt` only when the request names the IdP. On the single-IdP auto-redirect it drops it. `hd` is never forwarded. Domain enforcement relies on the Internal consent screen and auth-claims, as designed. The generic OIDC IdP fallback is **not needed**: the Google-type IdP does get `prompt`, the request just has to include `identity_provider`. So this PR adds that fix instead of the fallback. ## What - `internal_identity_providers` default changes from `["GoogleSAML"]` to `["Google"]`. One list feeds every internal app client (app-auth-sync) and auth-claims' `FEDERATED_IDENTITY_PROVIDERS`. - **ALB sign-in** (`terraform/modules/service-routing`): internal-pool rules now send `identity_provider=<client's IdP>` next to `prompt=select_account`. The IdP is read from the client's `cognito-client-identity-provider` parameter, which app-auth-sync writes, so it is never hardcoded and follows the cutover. Adds a `identity_provider_parameter_name` output to `cognito-app-client`. - **Apps:** `docs/app-yaml-reference.md` "Account chooser" now says to send `identity_provider=$COGNITO_IDENTITY_PROVIDER` together with `COGNITO_EXTRA_AUTH_PARAMS`. The generate-modules comment and `docs/cognito-google-setup.md` step 3 record the probe result. ## How verified - `python3 -m unittest discover -s scripts/tests`: OK. `python3 -m unittest discover -s terraform/lambda-src/tests`: 219 OK. - `terraform fmt -check -recursive terraform` and `terraform validate` on `service-routing`. - Expected platform plan: the app-auth-sync and auth-claims Lambda environments are updated in place. No Cognito pool, domain or client is replaced (Terraform manages no clients). After apply, the CI reconcile switches every internal client to `Google` and rewrites `cognito-client-identity-provider`, which restarts each auth app (app-secret-rollout). - The service-routing change reaches app repos on their next deploy. Before the cutover it sends `identity_provider=GoogleSAML`, which matches today's auto-redirect. ## Rollout: pre-cutover checklist - [x] #170 applied, every internal client has a branding style (app-auth-sync) - [x] #173 applied: the internal domain is on managed login - [ ] Internal-pool lockdown (#166) is live: `REQUIRED_EMAIL_DOMAIN`, no self sign-up, no `COGNITO` on internal clients - [x] `/javabin/platform/google-oauth/internal/{client-id,client-secret}` exist (the `Google` IdP is in the pool) - [x] Probe passes when `identity_provider` is sent (table above) - [ ] Apps that use ALB sign-in redeploy with this service-routing version - [ ] frosting and any other SPA/backend send `prompt=select_account` **and** `identity_provider=$COGNITO_IDENTITY_PROVIDER`. `prompt` alone is dropped - [ ] Apps keyed by `sub` (check cupcake/frosting) can handle a new `sub` per user. Google users are `Google_<sub>` with a new `sub`. The platform keys on email ## Rollout: after merge 1. `python3 scripts/auth-doctor.py --app-yaml <app>/app.yaml` for each auth app. Expect a redirect to `accounts.google.com` with `prompt=select_account`. auth-doctor sends `identity_provider` like a correct app, so also check that the app itself sends it. 2. Sign in once with a personal Gmail account active in the browser. Google must show the account chooser. 3. A week later, delete the 4 `GoogleSAML_*` users, the `GoogleSAML` provider and the Google Admin SAML app (`docs/cognito-google-setup.md`, "Decommission"). Rollback: revert to `["GoogleSAML"]` (GoogleSAML still exists until decommission). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
GoogleSAML has no account chooser: a browser signed in to a personal Google account hits a dead-end
403 app_not_configured_for_user(#157). With the Google OIDC provider on managed login, theprompt=select_accountthat apps and the ALB send (#170) reaches Google. Stacked on #171. DRAFT: do not merge until the checklist below is done.What
internal_identity_providersdefault["GoogleSAML"]→["Google"]. One list feeds every internal app client (app-auth-sync) and auth-claims'FEDERATED_IDENTITY_PROVIDERS.How verified
terraform fmt -check -recursive terraformGoogleand rewritescognito-client-identity-provider, which restarts each auth app (app-secret-rollout).Rollout: pre-cutover checklist
docs/cognito-google-setup.mdstep 3)describe-user-pool-domain --domain javabin-internal→ManagedLoginVersion: 2), and cupcake sign-in still works on GoogleSAMLREQUIRED_EMAIL_DOMAIN, no self sign-up, noCOGNITOon internal clients/javabin/platform/google-oauth/internal/{client-id,client-secret}exist (theGoogleIdP is in the pool)prompt: 'select_account'(javaBin/frosting PR), and any other SPA/backend sendsCOGNITO_EXTRA_AUTH_PARAMSsub(check cupcake/frosting) can handle a newsubper user: Google users areGoogle_<sub>with a newsub. The platform keys on emailGoogle:prompt droppedeven on managed login, the Google-type provider does not getprompt: switch to anOIDC-type provider before cutting overRollout: after merge
python3 scripts/auth-doctor.py --app-yaml <app>/app.yamlfor each auth app. Expect a redirect toaccounts.google.comwithprompt=select_account.GoogleSAML_*users, theGoogleSAMLprovider and the Google Admin SAML app (docs/cognito-google-setup.md, "Decommission").Rollback: revert to
["GoogleSAML"](GoogleSAML still exists until decommission).🤖 Generated with Claude Code