Skip to content

feat(auth): multi-IdP config.json + login provider picker (phase 1)#4

Merged
BorisTyshkevich merged 1 commit into
mainfrom
feat/multi-idp-config
Jun 20, 2026
Merged

feat(auth): multi-IdP config.json + login provider picker (phase 1)#4
BorisTyshkevich merged 1 commit into
mainfrom
feat/multi-idp-config

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

Phase 1 of multi-IdP support: config.json can list several OAuth providers, and the login screen shows one button per IdP. Fully backward-compatible and opt-in.

Config shape

{ "idps": [
    { "id": "google", "label": "Google",   "issuer": "https://accounts.google.com", "client_id": "" },
    { "id": "acme",   "label": "Acme SSO", "issuer": "https://acme.auth0.com",      "client_id": "", "client_secret": "" }
  ] }

A bare single object (today's format) is treated as a one-IdP list — otel/antalya configs are unchanged. Per-entry id/label are optional (default: issuer host).

Changes

  • oauth-config.js: split loadOAuthConfigloadConfigDoc (fetch + normalize a list, or wrap a bare object) + resolveIdp (per-IdP OIDC discovery). oauth.js untouched.
  • app.js: resolveConfig resolves the selected IdP; the choice persists as oauth_idp in sessionStorage (survives the OAuth redirect, like oauth_state) and drives token exchange / refresh / per-IdP bearer+ch_auth. Adds login(idpId), selectIdp, loadIdps; signOut clears the selection.
  • login.js: one "Sign in with …" button per IdP when >1 (async-loaded; falls back to the single button for 1 IdP or a load failure).
  • ClickHouse side: no change — CH already validates each inbound JWT against the token_processor matching its iss, so offering several IdPs needs no extra CH wiring.
  • Docs: config.json.example + README "Configuring OAuth → Multiple IdPs".

Verification

  • In-browser (built bundle): a 3-IdP config renders "Sign in with Google / Acme SSO / Keycloak"; single-IdP shows the lone button (regression).
  • npm test → 360 pass; oauth-config.js + login.js at 100%, app.js within its gate.

Phase 2 (auto-generating config.json from ClickHouse token_processors) builds on this list shape.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef

config.json may now list several OAuth IdPs; the login screen shows one button
per provider ("Sign in with <label>"). A bare single object is still accepted
(treated as a one-IdP list), so existing otel/antalya configs are unchanged.

- oauth-config.js: split loadOAuthConfig into loadConfigDoc (fetch + normalize a
  list, or wrap a bare object; id/label default to the issuer host) and
  resolveIdp (per-IdP OIDC discovery). oauth.js untouched.
- app.js: resolveConfig resolves the *selected* IdP; the choice persists as
  `oauth_idp` in sessionStorage (survives the OAuth redirect like oauth_state),
  driving token exchange/refresh and per-IdP bearer/ch_auth. login(idpId),
  selectIdp, loadIdps; signOut clears the selection.
- login.js: one button per IdP when >1 (async-loaded; single fallback on 1 or
  load failure). CH side needs no change — it validates each JWT against the
  token_processor matching its `iss`.

Docs: config.json.example + README document the list shape. Verified in-browser:
3-IdP picker renders; single-IdP regression intact. 360 tests pass;
oauth-config/login at 100%, app.js within gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QennTvGKAtJZrv9EpQagef
@BorisTyshkevich BorisTyshkevich merged commit fffca86 into main Jun 20, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant