-
Notifications
You must be signed in to change notification settings - Fork 1k
Add self-serve SSO docs #3349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add self-serve SSO docs #3349
Changes from all commits
e75b5d5
fa49e5e
57ab393
4e8ae31
e4a322d
2f6c867
1f7d8da
e52d47e
8372ad9
66ff972
dd2ce59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| --- | ||
| title: Self-serve SSO | ||
| description: Learn how to let your customers' IT admins configure their own enterprise SSO connections from inside your application. | ||
| --- | ||
|
|
||
| By default, enterprise SSO connections are configured by your team inside the Clerk Dashboard. For every enterprise customer that needs SSO, someone on your side has to create the connection, exchange metadata with the customer's IT admin, test the connection, and activate it. As your enterprise motion scales, this becomes a bottleneck. | ||
|
|
||
| Self-serve SSO lets you delegate that configuration directly to your customers' IT admins by embedding the [`<ConfigureSSO />`](/docs/reference/components/authentication/configure-sso) component inside your own application. The IT admin signs into your app with their Clerk account and uses the component to handle all identity provider (IdP) specific setup end-to-end — choosing an IdP, verifying the domain, exchanging metadata, and testing the connection — without ever touching the Clerk Dashboard. | ||
|
|
||
| `<ConfigureSSO />` works whether or not your application uses [Clerk Organizations](/docs/guides/organizations/overview): | ||
|
|
||
| - **With Clerk Organizations** — the connection is attached to the IT admin's active Organization. | ||
| - **Without Clerk Organizations** — the connection is attached to an email domain at the application level. No Organization is required. | ||
|
|
||
| > [!NOTE] | ||
| > In its current implementation, `<ConfigureSSO />` is the only way to use self-serve SSO, and it requires an active Clerk session. The IT admin must have a Clerk user account in your application and be signed in to use the flow. It currently only supports Okta and custom SAML. | ||
|
|
||
| ## Enable self-serve SSO | ||
|
|
||
| You must enable self-serve SSO at the instance level before the `<ConfigureSSO />` component will render. | ||
|
|
||
| 1. In the Clerk Dashboard, navigate to the [**SSO connections**](https://dashboard.clerk.com/~/user-authentication/sso-connections) page. | ||
| 1. Open the **Self-serve** tab. | ||
| 1. Toggle **Self-serve SSO** on. | ||
|
|
||
| If self-serve SSO is disabled, mounting `<ConfigureSSO />` in development will throw a runtime error to surface the misconfiguration. In production, it will simply not render. | ||
|
|
||
| ## Requirements | ||
|
|
||
| To render `<ConfigureSSO />`, the following must be true: | ||
|
|
||
| - Self-serve SSO is enabled in the Clerk Dashboard (see above). | ||
| - The **Email address** identifier is enabled on your instance. The component uses the user's primary email address to derive and verify the domain being claimed. | ||
| - The IT admin is signed in with a Clerk user account in your application. The component reads the active Clerk session and does not currently support unauthenticated, token-based access. | ||
|
|
||
| If you use Clerk Organizations and want to scope a connection to an Organization, the signed-in user must have the `org:sys_enterprise_connections` system permission for that Organization. This permission ships with the default **Admin** role; if you've defined custom roles, add it to any role that should be able to manage enterprise connections. For more information, refer to the [roles and permissions guide](/docs/guides/organizations/control-access/roles-and-permissions). | ||
|
|
||
| ## How the flow works | ||
|
|
||
| When the IT admin opens a page that renders `<ConfigureSSO />`, they are guided through a wizard with the following stages: | ||
|
|
||
| 1. **Verify domain** — the component verifies that the user controls the email domain they're claiming. If the user doesn't have a primary email address yet, they're prompted to add one first. | ||
| 1. **Configure** — the user selects an IdP and provides the protocol-specific configuration. IdP setup instructions are embedded inline, so you don't need to author or maintain your own walkthroughs. | ||
| 1. **Test** — the user runs a test sign-in to confirm the connection works end-to-end. | ||
| 1. **Confirmation** — once the test passes, you can review and enable the connection. | ||
|
|
||
| ## Embed the component | ||
|
|
||
| The following example shows the minimal integration in a Next.js App Router app. The component is imported from `@clerk/nextjs/experimental` because it's still in early access. | ||
|
|
||
| ```tsx {{ filename: 'app/sso-setup/page.tsx' }} | ||
| import { ConfigureSSO } from '@clerk/nextjs/experimental' | ||
|
|
||
| export default function SSOSetupPage() { | ||
| return <ConfigureSSO /> | ||
| } | ||
| ``` | ||
|
|
||
| Wrap the page in your usual route protection (for example, [`auth.protect()`](/docs/reference/nextjs/app-router/auth#auth-protect)) so that only signed-in users can reach it. | ||
|
|
||
| For full prop and SDK reference, see the [`<ConfigureSSO />` component documentation](/docs/reference/components/authentication/configure-sso). | ||
|
|
||
| ## What's next | ||
|
|
||
| Once a connection is created via `<ConfigureSSO />`, it behaves like any other Clerk enterprise connection. Users with matching email addresses can sign in via the configured IdP. To learn more, refer to: | ||
|
|
||
| - [Authentication flows](/docs/guides/configure/auth-strategies/enterprise-connections/authentication-flows) | ||
| - [Account linking](/docs/guides/configure/auth-strategies/enterprise-connections/account-linking) | ||
| - [Just-in-Time (JIT) provisioning](/docs/guides/configure/auth-strategies/enterprise-connections/jit-provisioning) | ||
| - [Directory Sync (SCIM)](/docs/guides/configure/auth-strategies/enterprise-connections/directory-sync) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,213 @@ | ||
| --- | ||
| title: '`<ConfigureSSO />` component' | ||
| description: Clerk's <ConfigureSSO /> component renders a self-serve UI that lets your customers' IT admins configure their own enterprise SSO connections from inside your application. | ||
| sdk: astro, nextjs, react, tanstack-react-start, vue, js-frontend | ||
| --- | ||
|
|
||
| The `<ConfigureSSO />` component renders a UI with instructions that allows end-users, typically the IT admin at one of your enterprise customers, configure single sign-on directly from your application. | ||
|
|
||
| The wizard walks the user through selecting an Identity Provider (IdP), verifying their email domain, supplying the protocol-specific configuration (with IdP setup instructions embedded inline), running a test sign-in, and activating the connection. | ||
|
|
||
| `When Organizations are enabled, the connection is attached to the user's active Organization, otherwise it's attached to the email domain at the instance level. | ||
|
|
||
| To learn how the broader self-serve SSO feature works and how to enable it in the Clerk Dashboard, see the [self-serve SSO guide](/docs/guides/configure/auth-strategies/enterprise-connections/self-serve-sso). | ||
|
|
||
| > [!NOTE] | ||
| > In its current implementation, `<ConfigureSSO />` is the only way to use self-serve SSO, and it requires an active Clerk session. The IT admin must have a Clerk user account in your application and be signed in to use the flow. It currently only supports Okta and custom SAML. | ||
|
|
||
| ## Requirements | ||
|
|
||
| `<ConfigureSSO />` will only render when all of the following are true: | ||
|
|
||
| - Self-serve SSO is enabled for your instance. See the [self-serve SSO guide](/docs/guides/configure/auth-strategies/enterprise-connections/self-serve-sso#enable-self-serve-sso) for instructions. | ||
| - The **Email address** identifier is enabled on your instance. | ||
| - The component is rendered to a signed-in user. | ||
|
|
||
| If any of these conditions are not met, the component will throw a runtime error in development and will not render in production. | ||
|
|
||
| If you use Clerk Organizations, the signed-in user must also have the `org:sys_enterprise_connections` system permission in their active Organization to manage enterprise connections. The permission ships with the default **Admin** role. | ||
|
|
||
| <If notSdk="js-frontend"> | ||
| ## Example | ||
|
|
||
| The following example includes a basic implementation of the `<ConfigureSSO />` component. You can use this as a starting point for your own implementation. | ||
|
|
||
| Because `<ConfigureSSO />` is experimental, it must be imported from the `experimental` subpath of your SDK. | ||
|
|
||
| <If sdk="nextjs"> | ||
| ```tsx {{ filename: 'app/sso-setup/page.tsx' }} | ||
| import { ConfigureSSO } from '@clerk/nextjs/experimental' | ||
|
|
||
| export default function SSOSetupPage() { | ||
| return <ConfigureSSO /> | ||
| } | ||
| ``` | ||
| </If> | ||
|
|
||
| <If sdk="react"> | ||
| ```tsx {{ filename: 'src/sso-setup.tsx' }} | ||
| import { ConfigureSSO } from '@clerk/clerk-react/experimental' | ||
|
|
||
| export default function SSOSetupPage() { | ||
| return <ConfigureSSO /> | ||
| } | ||
| ``` | ||
| </If> | ||
|
|
||
| <If sdk="tanstack-react-start"> | ||
| ```tsx {{ filename: 'src/routes/sso-setup.tsx' }} | ||
| import { ConfigureSSO } from '@clerk/tanstack-react-start/experimental' | ||
| import { createFileRoute } from '@tanstack/react-router' | ||
|
|
||
| export const Route = createFileRoute('/sso-setup')({ | ||
| component: SSOSetupPage, | ||
| }) | ||
|
|
||
| function SSOSetupPage() { | ||
| return <ConfigureSSO /> | ||
| } | ||
| ``` | ||
| </If> | ||
|
|
||
| <If sdk="astro"> | ||
| ```astro {{ filename: 'src/pages/sso-setup.astro' }} | ||
| --- | ||
| import { __experimental_ConfigureSSO as ConfigureSSO } from '@clerk/astro/components' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll remove the |
||
| --- | ||
|
|
||
| <ConfigureSSO /> | ||
| ``` | ||
| </If> | ||
|
|
||
| <If sdk="vue"> | ||
| ```vue {{ filename: 'pages/sso-setup.vue' }} | ||
| <script setup lang="ts"> | ||
| import { ConfigureSSO } from '@clerk/vue/experimental' | ||
| </script> | ||
|
|
||
| <template> | ||
| <ConfigureSSO /> | ||
| </template> | ||
| ``` | ||
| </If> | ||
| </If> | ||
|
|
||
| <If sdk="js-frontend"> | ||
| ## Usage with JavaScript | ||
|
|
||
| The following methods on an instance of the [`Clerk`](/docs/reference/objects/clerk) class are used to render and control the `<ConfigureSSO />` component: | ||
|
|
||
| - `__experimental_mountConfigureSSO()` | ||
| - `__experimental_unmountConfigureSSO()` | ||
|
|
||
| The following examples assume that you've followed the [quickstart](/docs/js-frontend/getting-started/quickstart) to add Clerk to your JavaScript app. | ||
|
|
||
| ### <code>mountConfigureSSO()</code> | ||
|
|
||
| Render the `<ConfigureSSO />` component to an HTML `<div>` element. | ||
|
|
||
| ```typescript | ||
| function __experimental_mountConfigureSSO(node: HTMLDivElement, props?: ConfigureSSOProps): void | ||
| ``` | ||
|
|
||
| #### <code>mountConfigureSSO()</code> params | ||
|
|
||
| <Properties> | ||
| - `node` | ||
| - [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) | ||
|
|
||
| The container `<div>` element used to render the `<ConfigureSSO />` component. | ||
|
|
||
| --- | ||
|
|
||
| - `props?` | ||
| - [`ConfigureSSOProps`](#properties) | ||
|
|
||
| The properties to pass to the `<ConfigureSSO />` component. | ||
| </Properties> | ||
|
|
||
| #### <code>mountConfigureSSO()</code> usage | ||
|
|
||
| ```js {{ filename: 'main.js', mark: [15] }} | ||
| import { Clerk } from '@clerk/clerk-js' | ||
|
|
||
| // Initialize Clerk with your Clerk Publishable Key | ||
| const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY | ||
|
|
||
| const clerk = new Clerk(clerkPubKey) | ||
| await clerk.load() | ||
|
|
||
| document.getElementById('app').innerHTML = ` | ||
| <div id="configure-sso"></div> | ||
| ` | ||
|
|
||
| const configureSSODiv = document.getElementById('configure-sso') | ||
|
|
||
| clerk.__experimental_mountConfigureSSO(configureSSODiv) | ||
| ``` | ||
|
|
||
| ### <code>unmountConfigureSSO()</code> | ||
|
|
||
| Unmount and run cleanup on an existing `<ConfigureSSO />` component instance. | ||
|
|
||
| ```typescript | ||
| function __experimental_unmountConfigureSSO(node: HTMLDivElement): void | ||
| ``` | ||
|
|
||
| #### <code>ConfigureSSO()</code> params | ||
|
|
||
| <Properties> | ||
| - `node` | ||
| - [`HTMLDivElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLDivElement) | ||
|
|
||
| The container `<div>` element with a rendered `<ConfigureSSO />` component instance. | ||
| </Properties> | ||
|
|
||
| #### <code>unmountConfigureSSO()</code> usage | ||
|
|
||
| ```js {{ filename: 'main.js', mark: [19] }} | ||
| import { Clerk } from '@clerk/clerk-js' | ||
|
|
||
| // Initialize Clerk with your Clerk Publishable Key | ||
| const clerkPubKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY | ||
|
|
||
| const clerk = new Clerk(clerkPubKey) | ||
| await clerk.load() | ||
|
|
||
| document.getElementById('app').innerHTML = ` | ||
| <div id="configure-sso"></div> | ||
| ` | ||
|
|
||
| const configureSSODiv = document.getElementById('configure-sso') | ||
|
|
||
| clerk.__experimental_mountConfigureSSO(configureSSODiv) | ||
|
|
||
| // ... | ||
|
|
||
| clerk.__experimental_unmountConfigureSSO(configureSSODiv) | ||
| ``` | ||
| </If> | ||
|
|
||
| ## Properties | ||
|
|
||
| All props are optional. | ||
|
|
||
| <Properties> | ||
| - `appearance?` | ||
| - <code>[Appearance](/docs/guides/customizing-clerk/appearance-prop/overview) | undefined</code> | ||
|
|
||
| An object to style the component. Overrides and merges with the global `appearance` prop on `<ClerkProvider>` (if one is provided). Will only affect [Clerk components](/docs/reference/components/overview) and not [Account Portal](/docs/guides/account-portal/overview) pages. | ||
|
|
||
| <If notSdk="js-frontend"> | ||
| --- | ||
|
|
||
| - `fallback?` | ||
| - `ReactNode` | ||
|
|
||
| An element to be rendered while the component is mounting. | ||
| </If> | ||
| </Properties> | ||
|
|
||
| ## Customization | ||
|
|
||
| To learn how to customize Clerk components, see the [appearance prop documentation](/docs/guides/customizing-clerk/appearance-prop/overview). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| title: '`OAuthConsentInfo`' | ||
| description: An interface that represents OAuth consent information. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this added due to a bad git rebase?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this looks like it's from this PR |
||
| sdk: js-frontend, astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start, nuxt, vue | ||
| --- | ||
|
|
||
| <Typedoc src="shared/o-auth-consent-info" /> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| --- | ||
| title: '`OAuthConsentScope`' | ||
| description: An interface that represents an OAuth consent scope. | ||
| sdk: js-frontend, astro, chrome-extension, expo, nextjs, react, react-router, tanstack-react-start, nuxt, vue | ||
| --- | ||
|
|
||
| <Typedoc src="shared/o-auth-consent-scope" /> |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this due to the Okta UI changes? They recently updated the UI for attribute statements and our copy here was using the "legacy" UI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, this is the new ui changes. using expressions instead of legacy ui
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e75b5d5 ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should also update self-serve sso to use these instructions too 👀