惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
腾讯CDC
博客园 - 司徒正美
A
About on SuperTechFans
H
Help Net Security
J
Java Code Geeks
C
Check Point Blog
B
Blog RSS Feed
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MongoDB | Blog
MongoDB | Blog
U
Unit 42
Hugging Face - Blog
Hugging Face - Blog
Last Week in AI
Last Week in AI
MyScale Blog
MyScale Blog
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
H
Hackread – Cybersecurity News, Data Breaches, AI and More
F
Fortinet All Blogs
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
博客园 - 【当耐特】
雷峰网
雷峰网

Clerk Blog

Going to production with Clerk Deploy Clerk Init: The fastest way to start a new project Introducing Clerk CLI Middleware-based route protection bypass Postmortem: Clerk System Outage (March 10, 2026) Clerk for the AI era Add API Key support to your SaaS in minutes Postmortem: Clerk System Outage (February 19, 2026) Using Clerk in a React Native app Postmortem: DNS Provider Outage (February 10, 2026) How do I implement passkeys in Next.js? Clerk ranked #4 fastest-growing software vendor on Ramp’s December 2025 list How do I handle JWT verification in Next.js? Committing to Agent Identity: Clerk raises $50m Series C from Menlo and Anthropic’s Anthology Fund What is the best way to handle authentication in Next.js App Router? Postmortem: Database Incident (September 14–18, 2025) How do I add authentication to a Next.js app? Introducing Free Trials in Clerk Billing Postmortem: August 28, 2025 - elevated API latency and errors Introducing Mosaic: Bring Your Brand to Every Authentication Flow Multi-tenant authentication: What you need to know (and how Clerk helps) What are the risks and challenges of multi-tenancy? Resilience in Practice: Regional Failover at Clerk Build a Cross-Platform B2B App with Clerk, Expo, and Supabase Highlights from the MiduDev/Clerk Hackathon Add multi-tenancy to an app built with Clerk, Lovable, and Supabase How to build an AI coding rules app with Clerk, Lovable, and Supabase Choosing the right SaaS architecture: Multi-Tenant vs. Single-Tenant Postmortem: June 26, 2025 service outage How to Design a Multi-Tenant SaaS Architecture
How to Build Multi-Tenant Authentication with Clerk
Brian Morrison II · 2025-06-27 · via Clerk Blog

If you're building a SaaS product, multi-tenancy shouldn’t be an afterthought. Designing with multiple tenants in mind sets you up to scale effectively and securely.

But building multi-tenant logic from scratch can get complicated fast. You need to think through everything from how users join organizations to how sessions are scoped and how permissions are enforced across contexts.

That’s where Clerk comes in.

Clerk’s built-in support for isolating tenants within a single codebase simplifies the heavy lifting. Instead of wiring up custom logic, you can use Clerk’s drop-in UI components to get a multi-tenant foundation in place quickly, while still maintaining flexibility as your product grows.

What You’ll Learn in This Guide

In this guide, we’ll walk through how to use Clerk to build a complete multi-tenant experience into your app. Specifically, you’ll learn how to:

  • Let users create and join organizations
  • Invite users to organizations with specific roles
  • Scope authentication and session logic by organization
  • Use our organization switcher so users can switch between multiple tenants
  • Enforce role-based access control (RBAC) per organization
  • Configure custom domains with Clerk’s Verified Domains

Building multi-tenancy features into a task manager

To demo this, you’ll learn how to add multi-tenancy features into a task manager called Kozi. At the moment, Kozi is feature complete for individual users, allowing them to add tasks and organize their tasks into projects.

Once the multi-tenancy features are added using Clerk, users will be able to create team workspaces and switch between them. Each workspace will have four distinct roles:

  • Admin - the default role, users in this role can perform all actions and manage the organization
  • Member - users in this role can create and manage tasks, but not the organization
  • Reader - users in this role can only read existing tasks but not make changes

The app is built with Next.js, Clerk, Neon, and Prisma for the ORM.

Following along

If you want to follow along, clone the orgs-exp-start branch in the Kozi repo and follow the instructions in the README to get set up.

You’ll need the following before you get started:

Step 1 - Enable Organizations in your Clerk app

Start by accessing your application in the Clerk dashboard. Select Configure from the top nav and then Settings under Organization management. Toggle the Enable organizations option to turn the feature on.

Once on, the view will update to present a number of new options. Here are a few notable ones:

  • Allow new members to delete organizations - When enabled, organization creators will be granted the Delete organization permission, allowing them to delete organizations. Turn this off if you want to allow users to create organizations but not delete them.
  • Enable verified domains - This option allows you to associate domains with organizations, and is something we will explore later in this article.
  • Allow new members to create organizations - If you want to control organization creation, disabling this option will prevent members to create organizations themselves.

Enable organizations

While we’re in the dashboard, create the roles and permissions by heading to Roles and Permissions, then select the Permissions tab. You’ll use the Create new permission button to create two permissions with the following values:

Next head back to the Roles tab and select the Create new role button to create the following role:

Next select both the Admin and Member roles and add the org:tasks:read and org:tasks:write permissions to enable those roles to use the new permissions.

Step 2 - Let users create and join orgs

Now that the Clerk application is configured, let’s move over to the code. The first change to make is to add the <OrganizationSwitcher /> component which is an all-in-one component that lets users create organizations, invite other members, and switch between the ones they have access to.

Open the project locally and update the Sidebar.tsx component to add the <OrganizationSwitcher /> component like so:

src/app/app/components/Sidebar.tsx

Now the bottom of the sidebar shows a “Personal account” button. This is the <OrganizationSwitcher /> component. By default every user has a personal account (meaning they do not have an organization active on their account), but clicking that button opens a menu allowing users to create new organizations:

The organization switcher

Step 3 - Creating an organization and inviting members

With the <OrganizationSwitcher /> in place, let’s use it to create a new organization and invite others to it. Open the switcher and select Create Organization. This will bring up a modal where you can set the name of your new organization. I’ll create one called Frontiers:

Create organization

After clicking Create organization, the form will ask for email addresses of anyone that should be invited to the organization, along with the role those users should be assigned:

Invite members

Clerk handles the process of sending email invitations to those users. When the user clicks the Accept Invitation button in their email, they’ll be brought to the application where they will then be able to access that organization as well in the switcher.

Accept invitation

At this point, Kozi permits users to switch their active organization, but the code still needs to be slightly modified to only return data relevant to that organization. As of now, the current user’s ID is used to filter data returned from the queries.

For example, the following code renders the Inbox page. It includes a query that returns tasks not associated to any projects. The auth helper function from Clerk is parsing the userId and setting that to ownerId which is in turn used in the query:

src/app/app/page.tsx

The auth function also returns an orgId if the user has an organization selected (it will return null otherwise) so we can modify the code to check for the orgId first and default back to the userId if it is not present:

src/app/app/page.tsx

The same change can be made to the page that renders each project:

src/app/app/projects/[id]/page.tsx

And finally, all of the other queries stored in actions.ts:

src/app/app/actions.ts

The Sidebar.tsx renders a list of projects associated with the current user or organization, and while the getProjects function in the actions.ts file will fetch the correct list of projects, the Sidebar is a client component and we need a way for it to react to changes. Instead of using the auth helper function (which is a server-side function), we can use the useOrganization() helper to get details about the user’s active organization and react to changes with a useEffect.

Make the following changes to Sidebar.tsx to update it’s behavior:

src/app/app/components/Sidebar.tsx

With this change, the list of projects in the sidebar will react to changing between organizations.

Step 4 - Gate access using RBAC

Now that users can switch between organizations, you’ll need to handle the different roles assigned to each user. To make this as simple as possible, Clerk offers the has helper function which takes a role or permission as a parameter to check to see if the user in the current context has the proper role/permission.

Recall that we created the Reader role which should have read-only access to tasks. This role omits the orgs:tasks:write permission so we can conditionally render the components differently if the user’s role does not have this permission.

To prevent the user from creating tasks, edit CreateTaskInput.tsx as follows:

src/app/app/components/CreateTaskInput.tsx

To make sure the user can’t edit tasks (including completing/uncompleting them), edit the TaskCard.tsx file:

src/app/app/components/TaskCard.tsx

The Sidebar should also be edited to prevent Reader users from seeing the option to add a project:

src/app/app/components/Sidebar.tsx

Now that the frontend is updated, you also need to modify any backend code to also check the user’s permissions for maximum security. Fortunately the has function works the same in server-side operations just like it does on the front end.

For any server action that makes changes to the database, you’ll use has to check the permissions like so:

src/app/app/actions.ts

Users with the Reader role in a specific organization should now only be able to see tasks in that organization, but not edit them. Furthermore if they switch to another organization where they have the Member role, they can add and edit tasks.

Optional - Add custom domains per org

Using Verified Domains, you can also configure your application to automatically invite users to a specific organization if they sign in with an email address that matches a specific domain. This is extremely helpful for HR or IT teams who need to onboard users into an application. It avoids having them manually create a user record.

As an example, let’s say I want to automatically invite any user who signs in with an @clerk.dev domain name into the Frontiers organization. I’ll start by toggling Enable verified domains in the organizations settings page shown earlier. I’ll also enable Automatic invitation and Automatic suggestion to streamline the experience.

Enable verified domains

In Kozi, I’ll access the organization settings by opening the <OrganizationSwitcher /> and selecting Manage. In the modal, I can add a domain to the Verified domains list. I’ll be asked to verify ownership of the domain by entering my email address to receive a six digit code.

Add verified domain

Now whenever somebody joins the app with an @clerk.dev email address, the <OrganizationSwitcher /> will automatically list the Frontiers organization as available for me to join and access.

Conclusion

Multi-tenancy is one of those architectural decisions that pays off early and compounds over time. Whether you're supporting teams, companies, or entire departments, having the right structure in place makes it easier to manage access, enforce security, and scale your product with confidence.

With Clerk, adding multi-tenant support doesn’t require reinventing your auth stack. You get drop-in UI components, APIs, and sensible defaults that help you stay focused on your product, not boilerplate.

As your app grows, so will the complexity of your users and their organizations. This guide gives you a solid foundation to handle that complexity with clarity.