feat(auth): support tenant shared-session SSO - #1493
Conversation
|
CI verification complete for head This run was triggered with |
|
Review-noise cleanup pushed as Removed unrelated import reordering, line wrapping, Express import spacing, and the unrelated OAuth catch typing refactor. The aggregate PR diff now preserves the parent branch style and contains only the SSO-related changes. Official CI tests workflow passed all 13 jobs on the new head: https://github.com/constructive-io/constructive/actions/runs/30506390854 |
c46d4c0 to
cc660c3
Compare
449e691 to
5650fe3
Compare
Caution
This is a stacked PR based on #1303 (
feat/oauth-reorg).Review only the commits and diff above that branch.
Do not merge this PR before #1303.
After #1303 merges, this branch must be rebased onto
mainand the PR base changed tomain.Important
This first SSO implementation supports shared sessions only when
strictAuth=false.It does not change or bypass
authenticate_strict.SSO is limited to APIs resolved by the scoped routing plane to the same CNC
databaseId.Stack and compatibility
cc660c304dcb26300231c5c46bb6ad10844ee46058d6c3503d4b08a616992f4b0a954f962a56d0d6The current constructive-hub DB gitlink (
ffb2c60dfb69a883f3639ba886cb18372330f122) was inspected first but is too old for the rebased CNC contract: it lacks the current scoped-routing/internal-secrets and sessions/auth-settings shape.58d6c350…is the already validated compatible DB revision used by the rebased OAuth branch, so this PR does not restore legacyservices_publicfallbacks or introduce a CNC DB change.What changed
databaseId.resolveRoute, androuteToApiStructure; no copied SQL, default-database fallback, or broad origin allowlist.INVALID_STATEif routing changed.constructive_session; OAuth state/PKCE remain host-only under/auth.Trust and security boundary
This is not a parent-domain suffix allowlist. A cross-origin target must be HTTP(S), contain no URL userinfo, use HTTPS in production, resolve as an API through the configured scoped routing plane, and have the same
databaseIdas the Auth API. Similar or unregistered hosts, non-API routes, missing database IDs, and other tenants are rejected.A parent-domain session cookie is safe only when every subdomain that can receive it is inside the same security boundary and uses HTTPS. Deployments must avoid simultaneous host-only and domain cookies with the same name during migration.
Validation
Passed locally:
pnpm install --frozen-lockfile --offlinepnpm run buildpnpm --filter @constructive-io/oauth test --runInBand— 57 testspnpm --filter @constructive-io/express-context test --runInBand— 17 testspnpm --filter @constructive-io/graphql-server test --runInBand— 154 testspnpm --filter graphql-server-test buildpnpm --filter graphql-server-test test --runInBand __tests__/oauth-scoped-routing.integration.test.ts— 7 tests against local PostgreSQL/MinIOgraphql-server-testsuite — 147 tests / 2 snapshotsgit diff --checkThe complete fake-provider browser golden path remains intentionally in constructive-hub. A follow-up Hub PR must pin this SSO head SHA and constructive-db
58d6c3503d4b08a616992f4b0a954f962a56d0d6.