Skip to content

Replace keycloak-js with generic OIDC client#69

Merged
alukach merged 22 commits into
mainfrom
feature/oidc-migration
Apr 28, 2026
Merged

Replace keycloak-js with generic OIDC client#69
alukach merged 22 commits into
mainfrom
feature/oidc-migration

Conversation

@alukach
Copy link
Copy Markdown
Member

@alukach alukach commented Apr 23, 2026

What I'm changing

This PR generalizes our Auth tooling to work with any OIDC provider, rather than just Keycloak.

This is a result of me receiving CORS errors when we were attempting to fetch the profile from the Keycloak /account endpoint. I think realized that all of the details regarding a user's account were already present in the ID Token returned upon login, thus meaning that we don't actually need to fetch from the /account endpoint. Furthermore, it became apparent that there was nothing Keycloak specific about the auth tooling that we had (Keycloak is, afterall, an OIDC provider) so we could generalize this tooling to support any other OIDC provider.

How I did it

I leaned on Claude to implement this. While this PR touches many files, the bulk of the affected logic is in packages/client/src/auth/Context.tsx and everything else is simply adapting to new names.

Claude PR details

Summary

  • Swap keycloak-js for react-oidc-context + oidc-client-ts so the app works with any OIDC IdP (Keycloak, Auth0, Cognito, Okta, Entra, Google, …). Profile data now comes from the parsed ID token — no more /realms/<realm>/account call, which fixes the CORS error that surfaced on the EOEPCA dev Keycloak.
  • Introduce REACT_APP_OIDC_AUTHORITY and REACT_APP_OIDC_CLIENT_ID as the new config interface. The legacy REACT_APP_KEYCLOAK_{URL,REALM,CLIENT_ID} vars keep working via a shim in resolveAuthConfig() that derives authority = "<url>/realms/<realm>" and logs one console.warn pointing operators at the migration docs.
  • Docker entrypoint, Helm chart, .env.example, root + client READMEs all updated. Helm values.yaml accepts both oidc.authority (new) and legacy oidc.providerUrl+oidc.realm; templates always emit the new env vars, verified via helm template in both configurations.

Test plan

  • Unit tests: resolveAuthConfig covers env precedence, shim derivation, trailing-slash normalization, partial-config, and empty-string handling (7 tests, all passing)
  • Typecheck clean on all touched files (pre-existing ItemList TS2307 errors are unrelated to this PR)
  • Manual login flow against live EOEPCA Keycloak with legacy env vars: deprecation warning in console, no /account CORS error, login/logout round-trip works, Authorization: Bearer … sent on protected STAC API calls
  • Manual login flow with new REACT_APP_OIDC_* env vars: no deprecation warning, identical behavior
  • Helm helm template rendered with oidc.authority+oidc.clientId and with legacy oidc.providerUrl+oidc.realm+oidc.clientId; both emit expected REACT_APP_OIDC_* env vars

Follow-ups (intentionally out of scope)

  • Multi-tab logout behavior with localStorage-backed token store — file as a separate issue for tracking.
  • README hints for non-Keycloak authority URLs (Auth0, Cognito, etc.) — minor doc nit.
  • STAC_API trailing-slash URL-joining bug discovered during manual verification — pre-existing on main, separate PR.

See the implementation plan at docs/plans/2026-04-23-oidc-migration.md for the full story.

🤖 Generated with Claude Code

Important

This PR includes breaking changes with regards to the environment variables used to construct authentication. I initially assumed we would want a plan to support existing deployments by deprecating the Keycloak tooling and using a shim, but I chose to remove that (cc132ea) in favor of a simpler system given how few deployments exist at this time (I am assuming).

alukach and others added 22 commits April 23, 2026 11:35
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ample

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the backwards-compatibility layer added for REACT_APP_KEYCLOAK_*
vars. Operators must now use REACT_APP_OIDC_AUTHORITY and
REACT_APP_OIDC_CLIENT_ID directly. The Helm chart no longer accepts
oidc.providerUrl + oidc.realm; use oidc.authority instead.

Revert this commit to restore the deprecation shim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alukach alukach requested a review from danielfdsilva April 23, 2026 20:45
Copy link
Copy Markdown
Member

@danielfdsilva danielfdsilva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks nice and cleaner.

Did not do a local test, but went through the code

@alukach alukach merged commit c63c760 into main Apr 28, 2026
4 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.

2 participants