All skills
clerk avatar

/clerk-orgs

@47c55cd official
by clerkclerk/skills83 stars
5

Clerk Organizations for B2B and multi-tenant apps - org switching, roles and permissions, verified domains, and enterprise SSO. Use for team workspaces, RBAC, org-scoped routing, member management. Also load this when a project treats teams, workspaces, tenants, or companies as its customers - shared accounts, inviting teammates, per-seat pricing, per-company data isolation - even when the words "organization" or "B2B" are never used.

Use this Skill: https://skilld.dev/gh/clerk/skills/clerk-orgs

This session only. Nothing lands on disk.

referencesenterprise-sso.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Enterprise SSO

Per-organization SAML or OIDC. Configured via Dashboard → Configure → Enterprise Connections or via clerk api -X POST /v1/enterprise_connections (requires a plan with the SAML feature enabled). New users from a matching domain auto-join via JIT Provisioning.

Configuration Flow

  1. Open Dashboard → Configure → Enterprise Connections (or per-org: Organizations → select org → SSO Connections).
  2. Add a SAML or OIDC connection and choose which Organization scopes the connection.
  3. Supply the customer's IdP metadata (SAML) or client credentials (OIDC). Clerk generates an ACS URL + Entity ID for the IdP admin to configure on their end.
  4. Set the domain the connection enforces on (e.g. acme.com). Clerk routes any sign-in with that email domain through the connection.

Each org can have multiple SSO connections (e.g., SAML + OIDC, or SAML for two different IdPs). Each connection covers one domain.

Enterprise SSO ≠ Verified Domains. These are distinct features. A domain used for Enterprise SSO cannot also be a Verified Domain for the same Organization. Use SSO for IdP-mandated auth; use Verified Domains for auto-invite / auto-suggest flows without SSO. See docs/guides/organizations/add-members/sso.mdx and docs/guides/organizations/add-members/verified-domains.mdx.

Permission required to manage: org:sys_domains:manage.

Strategy Name

// Current SDK (Core 3+)
strategy: 'enterprise_sso'

Used in signIn.supportedFirstFactors when building custom sign-in flows.

Core 2 ONLY (skip if current SDK): Uses strategy: 'saml' and user.samlAccounts instead of the Core 3 names.

Accessing SSO Info on the User

provider and protocol metadata live on the nested enterpriseConnection, not directly on the enterprise account. Correct paths:

import { currentUser } from '@clerk/nextjs/server'

const user = await currentUser()
const ssoAccount = user?.enterpriseAccounts?.[0]

if (ssoAccount) {
  // Directly on EnterpriseAccount:
  ssoAccount.emailAddress           // the email used for SSO
  ssoAccount.active                 // boolean — is the account active
  ssoAccount.firstName, ssoAccount.lastName
  ssoAccount.lastAuthenticatedAt    // Date | null

  // Provider metadata lives on the nested EnterpriseAccountConnection:
  const conn = ssoAccount.enterpriseConnection
  conn?.provider    // 'saml_okta' | 'saml_google' | 'saml_microsoft' | 'saml_custom' | 'oauth_<provider>'
  conn?.protocol    // 'saml' | 'oauth'
  conn?.domain      // the verified domain
  conn?.name        // display name of the connection
  conn?.active
}

Common Mistakes

// ❌ Wrong — `provider` is not a field on EnterpriseAccount
ssoAccount.provider

// ✓ Right — `provider` lives on the nested connection
ssoAccount.enterpriseConnection?.provider

enterpriseConnection is null if the connection was deleted after the account was provisioned. Always guard with ?..

Verified Domains (separate feature — short reference)

Verified Domains are a different feature from Enterprise SSO and cannot coexist on the same domain for the same Organization. Short reference:

  • Purpose: auto-invite or auto-suggest users from a matching email domain to join an org, without IdP-mandated SSO.
  • Ownership verification: Clerk sends a verification code to an address at that domain (handled inside the <OrganizationSwitcher /> / <OrganizationProfile /> flow).
  • Enrollment modes: Manual invitation, Automatic invitation, Automatic suggestion.
  • Permission: org:sys_domains:manage.
  • Full reference: docs/guides/organizations/add-members/verified-domains.mdx.

JIT Provisioning (how SSO users auto-join)

When a user signs in via an Enterprise SSO connection scoped to an org, Clerk's Just-in-Time (JIT) Provisioning automatically adds them as a member of that org and assigns the org's Default Role. No invitation is required.

JIT runs on the Enterprise Connection, not on the Verified Domain. The two features enforce different pathways and are mutually exclusive per-domain.

Custom Sign-In Flow with SSO

Typical pattern (Core 3 canonical):

const { signIn } = useSignIn()

const { error } = await signIn.sso({
  strategy: 'enterprise_sso',
  identifier: emailAddress,
  redirectUrl: '/dashboard',                 // where to land on successful sign-in
  redirectCallbackUrl: '/sign-in/callback',  // where to land when additional requirements are needed
})

The identifier is the user's email. Clerk uses the domain to route to the correct Enterprise SSO connection. If no matching connection exists, the sign-in falls back to standard email/password or returns an error.

Core 2 / legacy: signIn.authenticateWithRedirect({ strategy: 'enterprise_sso', identifier, redirectUrl, redirectUrlComplete }) still exists on the SDK for backwards compatibility, but for new code use signIn.sso() per the current enterprise-connections custom flow doc.

Key Rules

  • provider is nested. Always enterpriseAccounts[i].enterpriseConnection?.provider — not directly on the account.
  • SSO connection owns the domain. The domain the SSO connection enforces on is set on the connection itself; it does NOT require a separate Verified Domain (and in fact the two features are mutually exclusive per-domain).
  • Strategy name matters. Core 3 uses 'enterprise_sso'; Core 2 used 'saml'. They are NOT interchangeable.
  • Multiple connections per org is fine. Typical enterprise: one SAML connection to Okta + one OIDC to Azure AD for different user segments / domains.
  • Auto-join via JIT Provisioning. Users who authenticate via an Organization's Enterprise SSO connection are added to the org automatically with the org's Default Role. No invitation step.
  • Two setup paths. Dashboard for interactive UI, or clerk api for scripted setup: clerk api -X POST /v1/enterprise_connections (create), clerk api -X PATCH /v1/enterprise_connections/{id} (update), clerk api -X DELETE /v1/enterprise_connections/{id} (remove). Pass the IdP metadata or client credentials in the request body; Clerk returns the ACS URL + Entity ID in the response. Create / update endpoints require a plan with the SAML feature enabled. The legacy /v1/saml_connections endpoint is deprecated, use /v1/enterprise_connections instead.

Source: SKILL.md on GitHub

No alerts6d5 checks · Risk SAFE
  • Gen Agent Trust Hub6d

    The skill provides legitimate guidance and tools for integrating Clerk Organizations into applications. It includes safety instructions requiring user confirmation for administrative actions and uses official vendor resources.

  • Socket6d

    No alerts

  • Snyk6d

    Risk: LOW · No issues

  • Runlayer7mo

    2 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 47c55cd. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last week
What it can do
Network
metadata
{
  "author": "clerk",
  "version": "3.1.1"
}
All 1 allowed tools
WebFetch
Other metadata
compatibility
Requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY. Organizations must be enabled in Clerk Dashboard → Organizations. Membership mode (required vs optional) must match the B2B vs B2C + B2B coexistence story of your app.
  • Next.js
  • clerk
  • b2b
  • saas
  • organizations
  • rbac
  • multi-tenant
  • sso
  • authentication

README badge

README badge for clerk/skills/clerk-orgs

Manages multi-tenant B2B SaaS with Clerk Organizations — handles org creation, member invitations, role-based access control, verified domains, and enterprise SSO. Requires Organizations enabled in Clerk Dashboard and targets Next.js, React, and other Clerk SDK frameworks for team workspaces and org-scoped routing.

Generated from the current SKILL.md.

Does this work with frameworks other than Next.js?
Yes. The skill covers @clerk/nextjs by default, but the same feature-level APIs (has(), orgId, <OrganizationSwitcher />, <Show>) work across @clerk/react, @clerk/astro, @clerk/vue, @clerk/expo, @clerk/react-router, and @clerk/tanstack-react-start. Framework-specific patterns like middleware live in the nextjs-patterns reference.
What's the difference between Membership required and Membership optional?
Membership required (default) disables personal accounts and routes signed-in users through a choose-organization task, suitable for B2B-only apps. Membership optional keeps personal accounts available alongside org memberships, needed for B2C + B2B coexistence or apps with personal subscriptions.
How do I check if a user has a specific permission?
Use the has() function with a permission slug: has({ permission: 'org:sys_memberships:manage' }). System permissions prefix with org:sys_; custom permissions use org:<resource>:<action>. The full catalog is in references/roles-permissions.md.
Can I manage organizations and invitations programmatically?
Yes. The skill includes Backend API commands (clerk api) for org CRUD, membership management, and invitations. You can also use clerkClient().organizations.* in code. Billing/seat limits are handled by the clerk-billing skill.

Generated from the current SKILL.md. These answers refresh after source changes.