Skip to content

improvement(sso): fix provider lookup, migrate UI to emcn, add enterprise SSO docs#4238

Merged
waleedlatif1 merged 16 commits intostagingfrom
improvement/sso
Apr 20, 2026
Merged

improvement(sso): fix provider lookup, migrate UI to emcn, add enterprise SSO docs#4238
waleedlatif1 merged 16 commits intostagingfrom
improvement/sso

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Fixed MOCK_PROVIDER always blocking real provider data from being displayed
  • Fixed multi-org provider lookup using server-side getUserOrganization (could return wrong org) — now passes organizationId as query param from the active org context
  • Added orgId to Zod schemas in register route so it's no longer stripped before DB insert
  • Fixed SAML callback URL derivation (was using IdP issuer URL instead of getBaseUrl())
  • Fixed mutation error messages always showing "undefined" — now reads error.error || error.details
  • Changed onSuccessonSettled for cache invalidation so it fires on both success and error
  • Extracted showAdvanced from formData into own useState (was leaking UI state into API payload)
  • Added Cancel button in edit mode and disabled Update button when no changes have been made (hasChanges() dirty check)
  • Migrated SSO settings UI to emcn components (FormField, Expandable, toast)
  • Enabled organizationProvisioning in Better Auth SSO plugin so SSO users are auto-added to orgs
  • Added full enterprise SSO docs page with provider guides (Okta, Azure AD, Google Workspace, ADFS), FAQ, and self-hosted setup

Type of Change

  • Bug fix
  • Improvement

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Apr 20, 2026 11:14pm

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 20, 2026

PR Summary

Medium Risk
Touches SSO/auth provisioning, provider registration, and authorization checks; mistakes could break sign-in or expose/mis-associate provider configs across orgs. Changes are localized but impact a security-sensitive area (SSO secrets and org access control).

Overview
Improves enterprise SSO configuration end-to-end: the SSO settings UI now queries providers for the active organization and the /api/auth/sso/providers endpoint enforces org membership/role checks before returning org-scoped providers.

Hardens provider registration and metadata generation: orgId is accepted/validated server-side, OIDC clientSecret is redacted on read and can be preserved on update when the UI submits the redacted marker, and SAML callback/SP metadata now derive from getBaseUrl() (plus generated IDP metadata when not provided). SSO is also configured to auto-provision users into organizations via the auth plugin.

Refactors the SSO settings UI to emcn components with better UX (toasts, cancel/dirty-check, advanced SAML section) and updates docs by adding a dedicated enterprise/sso guide and reorganizing the Enterprise docs navigation.

Reviewed by Cursor Bugbot for commit aeafa27. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 20, 2026

Greptile Summary

This PR closes out a multi-round SSO security hardening cycle while also improving the admin UI and adding enterprise documentation. All previously-flagged issues (org membership guard on both GET and POST routes, OIDC clientSecret redaction, ownership-scoped REDACTED_MARKER lookup, SAML entityID using issuer instead of entryPoint) are now resolved, and several UX bugs (wrong org lookup, undefined error messages, showAdvanced leaking into API payload, broken idpMetadata round-trip on edit) are fixed alongside the emcn UI migration.

Confidence Score: 5/5

Safe to merge — all previously flagged security issues are resolved and the only remaining finding is a minor P2 timing optimization.

All P0/P1 findings from prior rounds (membership guard, secret redaction, ownership-scoped REDACTED_MARKER lookup, SAML entityID) are confirmed fixed. The one new finding is a P2 UX timing issue where the providers query fires once before organizationId is available — harmless due to keepPreviousData and the skeleton loading state, but wasteful.

No files require special attention; sso-settings.tsx has the minor timing note but is otherwise clean.

Important Files Changed

Filename Overview
apps/sim/app/api/auth/sso/providers/route.ts GET route now includes org membership + role guard before returning provider data, and redacts OIDC clientSecret with REDACTED_MARKER before sending to the client. All previously flagged security issues resolved.
apps/sim/app/api/auth/sso/register/route.ts Multiple security fixes: orgId added to Zod schemas, membership guard added for orgId, REDACTED_MARKER lookup scoped by org/userId, SAML callbackUrl uses getBaseUrl(), IdP metadata entityID now correctly uses issuer (not entryPoint). Error response no longer leaks fullError JSON.
apps/sim/ee/sso/components/sso-settings.tsx Significant UI overhaul: migrated to emcn FormField/Expandable/toast, extracted showAdvanced to useState, added Cancel button and hasChanges() dirty-check for Update button, fixed idpMetadata round-trip on edit. Minor: initial fetch fires before organizationId is available.
apps/sim/ee/sso/hooks/sso.ts Hook updated to pass organizationId as query param; onSuccess changed to onSettled so cache invalidation fires on both success and error; error reading fixed to use error.error
apps/sim/lib/auth/auth.ts Enabled organizationProvisioning in the SSO plugin so SSO users are automatically provisioned into the correct org on first login.
packages/db/scripts/register-sso-provider.ts CLI registration script updated to use issuer as entityID in auto-generated IdP metadata XML (matching the fix in the API route), consistent with ADFS/Shibboleth requirements where entityID ≠ entryPoint.
apps/docs/content/docs/en/enterprise/sso.mdx New comprehensive SSO docs page covering OIDC and SAML setup, Okta/Azure AD/Google Workspace/ADFS provider guides, FAQ, and self-hosted instructions.
apps/docs/content/docs/en/enterprise/index.mdx Simplified SSO section to point to the new dedicated SSO docs page instead of duplicating setup instructions inline.
apps/docs/content/docs/en/enterprise/meta.json New meta.json registering the enterprise docs section with index and sso pages.
apps/docs/content/docs/en/meta.json Added enterprise to the docs navigation metadata.

Sequence Diagram

sequenceDiagram
    participant UI as SSO Settings UI
    participant Hook as useSSOProviders / useConfigureSSO
    participant GET as GET /api/auth/sso/providers
    participant POST as POST /api/auth/sso/register
    participant DB as Database (member / ssoProvider)
    participant BA as Better Auth registerSSOProvider

    UI->>Hook: mount with organizationId
    Hook->>GET: GET ?organizationId=orgId
    GET->>DB: verify membership + role (owner/admin)
    DB-->>GET: membership record
    GET->>DB: SELECT ssoProvider WHERE organizationId=orgId
    DB-->>GET: provider row
    GET-->>Hook: providers (clientSecret REDACTED_MARKER)
    Hook-->>UI: render existing provider

    UI->>Hook: handleSubmit (Save / Update)
    Hook->>POST: POST {providerId, orgId, providerType, ...}
    POST->>DB: verify membership + role
    DB-->>POST: membership OK
    alt OIDC + REDACTED_MARKER secret
        POST->>DB: SELECT oidcConfig WHERE providerId AND organizationId
        DB-->>POST: stored clientSecret
    end
    POST->>BA: registerSSOProvider(providerConfig)
    BA-->>POST: {providerId}
    POST-->>Hook: {success: true}
    Hook->>DB: invalidateQueries(ssoKeys.providers())
    Hook-->>UI: toast success / error
Loading

Reviews (12): Last reviewed commit: "fix(sso): use issuer as entityID in auto..." | Re-trigger Greptile

Comment thread apps/sim/app/api/auth/sso/providers/route.ts Outdated
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

Fixed in 6183a98. Added an explicit membership check in providers/route.ts — the route now queries the member table to verify the session user belongs to the requested organizationId before expanding the WHERE clause. Returns 403 immediately if the user is not a member of that org, so SSO secrets (clientSecret, cert) can never be exfiltrated cross-org.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

Fixed in 6183a98. The idpMetadata field is stored as { metadata: string } inside samlConfig, so reading it back as a plain string yielded [object Object]. The fix reads config.idpMetadata?.metadata || config.idpMetadata || '' — handles both the nested object shape (new saves) and any legacy flat-string shape.

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/register/route.ts
Comment thread apps/sim/app/api/auth/sso/register/route.ts
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/providers/route.ts
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread packages/db/scripts/register-sso-provider.ts
Comment thread packages/db/scripts/register-sso-provider.ts Outdated
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/register/route.ts
Comment thread apps/sim/app/api/auth/sso/register/route.ts
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/providers/route.ts Outdated
Comment thread apps/sim/ee/sso/components/sso-settings.tsx
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/register/route.ts
Comment thread apps/sim/app/api/auth/sso/register/route.ts
Comment thread apps/sim/app/api/auth/sso/providers/route.ts Outdated
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/api/auth/sso/register/route.ts Outdated
Comment thread apps/sim/app/api/auth/sso/register/route.ts
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit aeafa27. Configure here.

@waleedlatif1 waleedlatif1 merged commit 0cd14f4 into staging Apr 20, 2026
14 checks passed
@waleedlatif1 waleedlatif1 deleted the improvement/sso branch April 20, 2026 23:45
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