Skip to content

feat(platform): unified enterprise SSO + provisioning (OIDC/OAuth2/SAML/SCIM)#1936

Merged
yannickmonney merged 6 commits into
mainfrom
feat/enterprise-sso
Jun 23, 2026
Merged

feat(platform): unified enterprise SSO + provisioning (OIDC/OAuth2/SAML/SCIM)#1936
yannickmonney merged 6 commits into
mainfrom
feat/enterprise-sso

Conversation

@yannickmonney

Copy link
Copy Markdown
Contributor

Unified Enterprise SSO + Provisioning

Replaces the legacy sso_providers module with one unified enterprise_sso
integration — a single connection per org carrying protocol-discriminated
OIDC / OAuth2 / Microsoft Entra / SAML 2.0 sign-in plus SCIM 2.0
provisioning for users and groups
, behind one adapter-free provisioning
policy (role mapping + group→team sync).

Highlights

  • Backend (convex/enterprise_sso/): ported OIDC/OAuth2/Entra adapters + login flow; new OAuth2 adapter; SAML 2.0 (node-saml node action, SP metadata, IdP- and SP-initiated flows, signed/encrypted assertion validation); SCIM Users+Groups with soft-disable and org-from-token; shared provisioning orchestrator.
  • Data: ssoConnections + ssoProvisioningLinks tables; reversible migration 0.2.85/04 carrying existing ssoProviders rows across; legacy module + duplicate SSO settings UI removed; login / trusted-headers / Entra-matcher repointed.
  • Frontend: dedicated Enterprise SSO settings page in its own feature folder, with a per-provider Setup Guide (Microsoft / Google / OIDC / SAML); i18n en/de/fr.
  • Mocks / docs: OpenAPI IdP mock in lib/mocks for offline SSO e2e (+ @tale/mockslib/mocks reference updates); docs/{en,de,fr}/platform/admin/enterprise-sso.

Tests

~230 green: SCIM HTTP (auth/isolation/discovery), mappers, provisioning policy, migration up/down, frontend a11y (all protocols), mock contract, docs structural. tsc + type-aware lint clean; migrations:check OK.

Caveats

  • Live sign-in against a real IdP can't run in CI (covered via the OpenAPI IdP mock, fixture-based SAML attribute mapping, and the node-action seam) — flagged for live QA.
  • Passkey/2FA are Better Auth's own endpoints (not third-party APIs), so they're driven by e2e helpers rather than the gateway mock.

Note on scope

Per request, this PR also bundles other uncommitted working-tree changes present on the branch (CLI dev-mode rework, docs, UI, scripts) beyond the SSO feature.

…ML/SCIM)

Replace the legacy `sso_providers` module with one unified `enterprise_sso`
integration: a single connection per org carrying protocol-discriminated
sign-in (OIDC, OAuth2, Microsoft Entra, SAML 2.0) plus SCIM 2.0 provisioning
for users AND groups, with a shared role-mapping + group-to-team policy.

- Backend: ported OIDC/OAuth2/Entra adapters + login flow; new OAuth2 adapter;
  SAML 2.0 (node-saml node action, SP metadata, IdP- and SP-initiated flows,
  signed/encrypted assertion validation); SCIM Users+Groups (soft-disable,
  org-from-token); adapter-free provisioning orchestrator.
- Data: `ssoConnections` + `ssoProvisioningLinks` tables; reversible migration
  0.2.85/04 carrying `ssoProviders` across; legacy module + duplicate SSO UI
  removed; login / trusted-headers / entra-matcher repointed.
- Frontend: dedicated "Enterprise SSO" settings page in its own feature folder
  with a per-provider setup guide (Microsoft/Google/OIDC/SAML); i18n en/de/fr.
- Mocks/docs/tests: OpenAPI IdP mock in lib/mocks (+ @tale/mocks -> lib/mocks
  reference updates); docs/{en,de,fr}/platform/admin/enterprise-sso; ~90 unit/
  integration tests (SCIM HTTP, mappers, provisioning, migration up/down,
  a11y, mock contract).

Note: this commit also bundles other uncommitted working-tree changes present
on the branch (CLI dev-mode rework, docs, UI, scripts) at the maintainer's
request.
@@ -0,0 +1,116 @@
'use node';
…hema snapshot

- Un-export internal-only members in lib/shared/schemas/enterprise_sso.ts
  (view sub-schemas/types used only to build SsoConnectionView) — knip clean.
- Un-export internal helpers in lib/shared/config/config_fingerprint.ts
  (stripAnnotations/canonical/ConfigVerdict/ConfigSchemaChange) — knip clean.
- Refresh convex/migrations/schema.snapshot.json baseline to record the new
  ssoConnections/ssoProvisioningLinks tables and the bundled sandbox field
  rename (bifrostKeyId -> llmGatewayKeyId on ephemeral session tables).
…eleased)

The v0.2.85 release was tagged today and already shipped v0_2_85/01-03; a
migration added now belongs in the next unreleased version. Move
04_enterprise_sso_unify -> v0_2_86/01_enterprise_sso_unify (id/semver/numericId
updated, down floor 0.2.84 -> 0.2.85) and repoint the registry import.
Ledger is per-migration-id so application is unaffected; this keeps the
folder=next-unreleased-version convention correct.
@@ -0,0 +1,402 @@
'use node';
@@ -0,0 +1,101 @@
'use node';
@@ -0,0 +1,196 @@
'use node';
@@ -0,0 +1,66 @@
'use node';
@@ -0,0 +1,62 @@
'use node';
export type SsoConnectionSecrets = z.infer<typeof ssoConnectionSecretsSchema>;

/** Effective, defaulted connection used when the org has no `connection.json`. */
function emptySsoConnectionFile(): SsoConnectionFile {
@yannickmonney yannickmonney merged commit b418075 into main Jun 23, 2026
74 of 76 checks passed
@yannickmonney yannickmonney deleted the feat/enterprise-sso branch June 23, 2026 10:35
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