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

推荐订阅源

L
LINUX DO - 最新话题
C
Cyber Attacks, Cyber Crime and Cyber Security
G
GRAHAM CLULEY
T
Tenable Blog
T
Threatpost
C
CXSECURITY Database RSS Feed - CXSecurity.com
I
Intezer
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
Security Latest
Security Latest
P
Privacy & Cybersecurity Law Blog
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
P
Palo Alto Networks Blog
TaoSecurity Blog
TaoSecurity Blog
Webroot Blog
Webroot Blog
Spread Privacy
Spread Privacy
O
OpenAI News
The Last Watchdog
The Last Watchdog
P
Proofpoint News Feed
C
Check Point Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
人人都是产品经理
人人都是产品经理
S
Security @ Cisco Blogs
Scott Helme
Scott Helme
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
月光博客
月光博客
S
Securelist
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
T
Troy Hunt's Blog
W
WeLiveSecurity
GbyAI
GbyAI
N
News | PayPal Newsroom
Y
Y Combinator Blog
C
Cisco Blogs
H
Help Net Security
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 【当耐特】
Jina AI
Jina AI
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
云风的 BLOG
云风的 BLOG
小众软件
小众软件
N
News and Events Feed by Topic

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 What is multi-tenancy and why it matters for B2B SaaS How OAuth Works Synchronize user data from Clerk to Supabase Add subscriptions to your SaaS with Clerk Billing Getting started with Clerk Billing Multi-tenant analytics with Tinybird and Clerk How Huntr Migrated 250K Users to Clerk: A Scalable Auth Solution for Startups How to take Clerk to Production How to take your Clerk application to production A practical guide to testing Clerk Next.js applications Implementing multi-tenancy into a Supabase app with Clerk How Clerk integrates with a Next.js application using Supabase How Clerk integrates with Supabase Build a blog with tRPC, Prisma, Next.js and Clerk How to enrich PostHog events with Clerk user data How to build a secure project management platform with Next.js, Clerk, and Neon Validate your SaaS idea while building an audience Postmortem: February 6, 2025 service outage Implement Role-Based Access Control in Next.js 15 Build a Next.js sign-up form with React Hook Form Build a Next.js login page template How to implement Google authentication in Next.js 15 What is middleware in Next.js? How to customize Next.js metadata How to set environment variables in Node.js Building a React Login Page Template How to implement per-user OAuth scopes with Clerk Using Clerk SSO to access Google Calendar and other service data Streamline enterprise customer onboarding with SAML and Clerk Clerk launches EASIE SSO and eliminates SSO fees How to secure Liveblocks Rooms with Clerk in Next.js Securing Node.js Express APIs with Clerk and React Combining the benefits of session tokens and JWTs Build a task manager with Next.js, Supabase, and Clerk Comparing Clerk Webhooks vs Backend API Automate Neon schema changes with Drizzle and GitHub Actions A guide to reading authenticated user data from Clerk Role based access control with Clerk Organizations Mitigating OAuth’s recently discovered Open Response Type vulnerability Per-user B2B monetization with Stripe and Clerk Organizations Build a team-based task manager with Next.js, Neon, and Clerk Building a Hybrid Sign-Up/Subscribe Form with Stripe Elements Welcoming Colin from Zod as our inaugural Open Source Fellow Build a modern authenticated chat application with Next.js, Ably, and Clerk Build a waitlist with Clerk user metadata How to use Clerk with PostHog Identify in Next.js How to secure API Gateway using JWT and Lambda Authorizers with Clerk What are passkeys and how do they work? Comparing Authentication in React.js vs. Next.js How to Add an Onboarding Flow for your Application with Clerk Create Your Own Custom User Menu with Radix - Part 2 Introducing Webhook Workflows with Inngest & Svix Clerk raises $30M Series B from CRV and Stripe Clerk in 2023: A Year in Review Build a Movie Emoji Quiz App with Remix, Fauna, and Clerk Ultimate Guide to Magic Link Authentication Create Your Own Custom User Menu with Radix Introducing has(), protect(), and <Protect> Updated Pricing: 10,000 MAUs Free, and a new “Pro Plan” Next.js Authentication with Clerk: Streamlined SSR Handling Clerk Webhooks: Data Sync with Convex Exploring Clerk Metadata with Stripe Webhooks The Ultimate Guide to Next.js Authentication Empower Your Support Team With User Impersonation Clerk Webhooks: Getting Started A Complete Guide to Session Management in Next.js The Advanced Guide to Passwordless Authentication in Next.js How We Roll – Chapter 10: Roundup How We Roll – Chapter 9: Infrastructure Password-Based Authentication in Next.js
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.