Skip to content

Refactor: DO-11383 store auth token data server-side#633

Merged
krzysztof-causalens merged 32 commits into
masterfrom
codex/opaque-oidc-session
May 22, 2026
Merged

Refactor: DO-11383 store auth token data server-side#633
krzysztof-causalens merged 32 commits into
masterfrom
codex/opaque-oidc-session

Conversation

@krzysztof-causalens
Copy link
Copy Markdown
Collaborator

@krzysztof-causalens krzysztof-causalens commented May 21, 2026

Motivation and Context

Large OIDC group claims can overflow browser cookie limits when auth token data is stored directly in cookies. Some customer IDPs also expose groups through non-standard claim names or string formats, and auth failure paths need to fail clearly instead of looping users through login.

This PR moves browser auth state to a single opaque session cookie, stores the full auth session server-side, and tightens OIDC session refresh, group extraction, userinfo handling, auth error routing, and local QA coverage.

Implementation Description

Auth session creation now stores raw auth tokens, token data, groups, ID tokens, and refresh tokens in the generic server-side auth session store. The browser receives only the opaque dara_session_token; application code continues to use the existing resolved auth context by the time user code runs.

Refresh now runs server-side from the stored refresh token and updates the same session record after a successful refresh. Missing in-memory session entries are treated as expired sessions, terminal refresh failures evict the stored session, and stale cookie-backed opaque handles are rejected directly instead of being decoded as raw JWTs. The old OIDC-only ID token cache and refresh-token cookie path were removed.

OIDC group handling now supports a configurable group claim name, plus list, comma-delimited string, and single-string claim values. Comma-delimited strings are parsed with CSV semantics while preserving the original full string for exact matching. When SSO_USE_USERINFO=true, login and refresh now require userinfo to succeed and log clear provider failure reasons.

Frontend auth error handling now uses an option bag instead of positional booleans. Normal app requests send authentication failures to /login, while authorization, provider, bad-request, and OIDC callback validation failures go to /error to avoid login loops. WebSocket auth recovery can also restart reconnect attempts after server-side HTTP session recovery.

A local OIDC provider test tool was added under tools/local-oidc-provider with controllable profiles for large claims, userinfo, refresh behavior, group formats, non-standard memberOf group claims, logout redirects, and failure cases.

Any new dependencies Introduced

No Dara runtime dependencies. The local QA provider is self-contained under tools/local-oidc-provider and declares its own npm dependencies.

How Has This Been Tested?

  • DARA_TEST_FLAG=True poetry run pytest tests/python/test_oidc_auth.py
  • DARA_TEST_FLAG=True poetry run pytest tests/python/test_auth.py -k 'invalid_cookie_clears_auth_cookies_without_refresh_token or refresh_token_terminal_failure_removes_session or refresh_token_concurrent_requests'
  • DARA_TEST_FLAG=True poetry run pytest tests/python/test_oidc_auth.py -k 'missing_id_token or expired_id_token or idp_error or refresh'
  • pnpm --filter @darajs/core exec vitest --run tests/js/auth.spec.tsx tests/js/websocket-auth-recovery.spec.tsx
  • pnpm --filter @darajs/core exec tsc --noEmit
  • pnpm --filter @darajs/components exec tsc --noEmit
  • pnpm --filter @darajs/core build
  • poetry anthology run lint
  • poetry anthology run format-check
  • QA_OIDC_ISSUER=http://localhost:9101 npm run smoke from tools/local-oidc-provider

Manual browser QA with the demo app and tools/local-oidc-provider covered:

  • Successful default OIDC login/logout with only dara_session_token needed after login.
  • Large group claims via huge-groups, verifying opaque sessions avoid cookie overflow.
  • Group claim formats via groups-string, single-group-string, missing group, and missing group claim profiles.
  • Non-standard group claim name via SSO_GROUP_CLAIM_NAME=memberOf and the member-of-groups profile.
  • Server-side refresh paths via short-expiry, refresh-reuses-token, refresh-loses-group, and no-refresh-token profiles.
  • Userinfo paths with SSO_USE_USERINFO=true: allowed userinfo groups, denied userinfo groups, and userinfo sub mismatch.
  • OIDC callback/provider failure paths: missing ID token, expired ID token, IDP errors, and retry/error routing without login loops.

PR Checklist:

  • I have implemented all requirements? (see JIRA, project documentation).
  • I am not affecting someone else's work, If I am, they are included as a reviewer.
  • I have added relevant tests (unit, integration or regression).
  • I have added comments to all the bits that are hard to follow.
  • I have added/updated Documentation.
  • I have added/updated the changelog for the relevant package.

Screenshots (if appropriate):

N/A

@krzysztof-causalens krzysztof-causalens self-assigned this May 21, 2026
@krzysztof-causalens
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2467d3349d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/dara-core/dara/core/auth/session_store.py
@krzysztof-causalens krzysztof-causalens changed the title Refactor: Store auth token data server-side Refactor: DO-11383 store auth token data server-side May 21, 2026
@krzysztof-causalens
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a43cdb5804

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/dara-core/dara/core/auth/routes.py
Comment thread packages/dara-core/js/api/http.tsx
@krzysztof-causalens krzysztof-causalens marked this pull request as ready for review May 22, 2026 11:52
Copy link
Copy Markdown
Contributor

@sam-causalens sam-causalens left a comment

Choose a reason for hiding this comment

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

This looks great Krys, thanks 🙏

@krzysztof-causalens krzysztof-causalens merged commit cae0686 into master May 22, 2026
23 of 25 checks passed
@krzysztof-causalens krzysztof-causalens deleted the codex/opaque-oidc-session branch May 22, 2026 14:16
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