Build a multi-tenant SaaS application: A complete guide from design to implementation
Learn how to efficiently build a multi-tenant SaaS application with robust authentication, organization management, and role-based access control in just a few hours.
YijunDeveloper
Stop wasting weeks on user auth
Launch secure apps faster with Logto. Integrate user auth in minutes, and focus on your core product.
How are apps like Notion, Slack, or Figma built? These multi-tenant SaaS applications look simple to use, but building one yourself? That's a different story.
When I first thought about building such a complex beast, my mind exploded:
Users need multiple sign-in options (email, Google, GitHub)
Each user can create and belong to multiple organizations
Different permission levels within each organization
Enterprise organizations requiring auto-join for specific email domains
MFA requirements for sensitive operations
...
"Boss, let's talk about product design in two weeks. I'm stuck in the mud right now."
But when I actually started working on it, I find that it's not as daunting as it seems.
I just built a system with all these features in LESS THAN 2 HOUR!
I'll show you exactly how to design and implement such a system from the ground up - and you'll be amazed at how simple it really is in 2025 with modern tools and the right architectural approach.
The complete source code is available in this Github Repo. Let's dive in!
We'll start with an AI documentation SaaS product called DocuMind.
DocuMind is an AI documentation SaaS product designed with a multi-tenant model to support individual users, small businesses, and enterprises.
The platform provides powerful AI capabilities for document management, including automatic summary generation, key point extraction, and intelligent content recommendations within organizations.
What features are required for SaaS authentication and authorization?#
First, let’s review the necessary requirements. What features do you need?
To enable a multi-tenant architecture, you’ll need an entity layer called organization. Imagine having a single pool of users who can access multiple workspaces. Each organization represents a workspace, and users maintain a single identity while accessing different workspaces (organizations) based on their assigned roles.
It’s a widely used feature in authentication providers. An organization in an identity management system corresponds to your SaaS app’s workspace, project, or tenant.
A member is a temporary concept used to indicate an identity’s membership status within an organization.
For example, Sarah signs up for your app using her email, [email protected]. She can belong to different workspaces. If Sarah is part of Workspace A but not Workspace B, she is considered a member of Workspace A but not Workspace B.
In a multi-tenant architecture, users need roles with specific permissions to access their tenant resources.
Permissions are detailed access controls that define specific actions, such as read: order or write: order. They determine what actions can be performed on particular resources.
Roles are a set of permissions assigned to members in a multi-tenant environment.
You’ll need to define these roles and permissions, then assign roles to users, and sometimes it may include automated processes. For example:
Users who join an organization automatically get the member role.
The first user to create a workspace is automatically assigned the admin role.
In a multi-tenant SaaS app, a key difference in the user flow is the need to support tenant creation and member invitations. This process requires careful planning and execution as it plays a key role in product activation and growth.
Here are a few typical use flows you need to consider:
User type
Entry point
New account
Enter from sign in and sign up page to create a new tenant
Existing account
Create another tenant inside the product
The existing account got a new tenant invitation
Enter from sign in and sign up page
The existing account got a new tenant invitation
Enter from the invitation email
The new account got a new tenant invitation
Enter from sign in and sign up page
The new account got a new tenant invitation
Enter from the invitation email
Here are some common scenarios found in almost every SaaS app. Use these as a reference to inspire your product and design team, and feel free to create your own flows as needed.
Implementing just these basic features could take weeks of development.
But now, we don't need to build ANY of this ourselves!
Modern auth providers (I will choose Logto this time) have packaged all these features for us. The authentication flow is straightforward:
From weeks of development to 15 minutes of setup, Logto handles all the complex flows for us! We'll cover the integration steps in the implementation section later. Now we can focus on building DocuMind core features!
Role-Based Access Control (RBAC) is important for ensuring security and scalability in multi-tenant SaaS applications.
In a multi-tenant app, the design of permissions and roles is usually consistent, as it stems from the product design. For example, in multiple workspaces, there’s typically an admin role and a member role. Logto as an auth provider has the following organization-level role-based access control design:
Unified permission definitions: Permissions are defined at the system level and apply consistently across all organizations, ensuring maintainable and consistent permission management
Organization templates: Pre-defined role and permission combinations through organization templates, simplifying organization initialization
The permission relationship looks like this:
Since each user needs their own role(s) within each organization, the relationship between roles and organizations must reflect the roles assigned to each user:
We've designed the organization system and access control system, and now we can start building our product!
Frontend: React (easily transferable to Vue/Angular/Svelte)
Backend: Express (simple, intuitive API)
Why separate frontend and backend?Because it has a clear architecture, easy to learn and simple to switch stacks. And for auth providers, I use Logto as an example.
And for the following guides, its patterns here work with: Any frontend, any backend and any auth system.
This is the easiest step. We just need to integrate Logto into our project. Then we can configure user login/registration methods in the Logto Console based on our needs.
First, log into Logto Cloud. You can sign up for a free account if you don't have one. Create a Development Tenant for testing.
In the Tenant Console, click the "Application" button on the left. Then select React to start building our application.
Follow the guide on the page. You can complete the Logto integration in about 5 minutes!
Here's my integration code:
Here's a useful trick: Our login page has both Sign in and Register buttons. The Register button leads directly to Logto's registration page. This works through Logto's first screen feature. It determines which step of the auth flow users see first.
You can default to the registration page when your product expects many new users.
After clicking login, you'll go to the Logto login page. Upon successful login (or registration), congratulations! Your app has its first user (you)!
And call the signOut function from the useLogto hook to sign out the user when you want to.
In the Logto Console, click "Sign-in Experience" on the left menu. Then click the "Sign-up and sign-in" tab.
On this page, follow the instructions to configure Logto's login/registration methods.
With Logto, enabling MFA is simple. Just click the "Multi-factor auth" button in the Logto Console. Then enable it on the Multi-factor authentication page.
And the MFA flow will look like this:
Everything is so simple! We've set up a complex user authentication system in just a few minutes!
To get a user's organization information from Logto, follow these two steps:
Declare organization information access in the Logto Config. This is done by setting the appropriate scopes and resources.
Use Logto's fetchUserInfo method to get user information, including organization data.
After completing these steps, you need to sign out and sign in again. This is necessary because we modified the requested scope and resource.
Right now, you haven't created any organizations. The user hasn't joined any organizations either. The dashboard will show "You don’t have any organization yet".
Next, we’ll create an organization for our users and add them to it.
Thanks to Logto, we don't need to build complex organization relationships. We just need to create an organization in Logto and add users to it. Logto handles all the complexity for us. There are two ways to create Organizations:
Manually create organizations through the Logto Console
Use the Logto Management API to create organizations, especially when designing a SaaS flow that lets users create their own organizations (workspaces).
Click the "Organizations" menu button on the left side of the Logto Console. Create an organization.
Now you have your first organization.
Next, let's add the user to this organization.
Go to the organization details page. Switch to the Members tab. Click the "+ Add member" button. Select your login user from the left list. Click the "Add members" button in the bottom right. Now you've successfully added the user to this organization.
Refresh your APP page. You'll see the user now belongs to an organization!
Creating an organization in the console is not enough. Your SaaS app needs a flow that allows end users to easily create and manage their own workspaces. To implement this functionality, use the Logto Management API.
First, let's create an API endpoint in our backend service for creating organizations.
Our backend service API only allows authenticated users. We need to use Logto to protect our API. We also need to know the current user's information (like user ID).
In Logto's concept (and OAuth 2.0), our backend service acts as a resource server. Users access DocuMind resource server with an Access token from the frontend. The resource server verifies this token. If valid, it returns the requested resources.
Let's create an API Resource to represent our backend service.
Go to the Logto Console.
Click the "API resources" button on the right.
Click "Create API resource". Select Express in the popup.
Don't worry about this API identifier URL. It's just a unique identifier for your API in Logto. It's not related to your actual backend service URL.
You'll see a tutorial for using the API resource. You can follow that tutorial or our steps below.
Let's create a requireAuth middleware to protect our POST /organizations endpoint.
To use this middleware, we need these environment variables:
LOGTO_JWKS_URL
LOGTO_ISSUER
Get these variables from your Logto tenant's OpenID Configuration endpoint. Visit https://<your-tenant-id>.logto.app/oidc/.well-known/openid-configuration. You'll find the needed information in the returned JSON:
Now use the requireAuth middleware in our POST /organizations endpoint.
This protects our POST /organizations endpoint. Only users with valid Logto access tokens can access it.
We can now get the token from Logto in our frontend. Users can create organizations through our backend service with this token. The middleware also gives us the user ID. This helps when adding users to organizations.
In the frontend code, declare this API resource in the Logto config. Add its identifier to the resources array.
Like before, users need to log in again after we update the Logto config.
In the Dashboard, get the Logto Access Token when creating an organization. Use this token to access our backend service API.
Now we can properly access DocuMind backend service API.
Go to the applications page in Logto Console. Create a Machine-to-Machine application. Assign the "Logto Management API access" role. Copy the Token endpoint, App ID, and App Secret. We'll use these for access tokens.
Now we can get Logto Management API access tokens through this M2M application.
Use this access token to call Logto Management API.
Implement access control to your multi-tenant app#
Now let's move on to organization access control.
We want to achieve:
Users can only access resources belonging to their own organizations: This can be done through Logto's organization token
Users have specific roles within organizations (containing different permissions) to perform authorized actions: This can be implemented through Logto's organization template feature
Similar to the Logto access token we mentioned earlier, Logto issues an access token corresponding to a specific resource, and users use this token to access protected resources in the backend service. Correspondingly, Logto issues an organization token corresponding to a specific organization, and users use this token to access protected organization resources in the backend service.
In the frontend application, we can use Logto's getOrganizationToken method to obtain a token for accessing a specific organization.
Here, organizationId is the id of the organization to which the user belongs.
Before using getOrganization or any organization features, we need to ensure that urn:logto:scope:organizations scope and urn:logto:resource:organization resource are included in the Logto config. Since we've already declared these earlier, we won't repeat it.
In our organization page, we use the organization token to fetch documents within the organization.
There are two important points to note in this implementation:
If the organizationId passed to getOrganizationToken is not an organization id that belongs to the current user, this method won't be able to get a token, thus ensuring users can only access their own organizations.
When requesting organization resources, we use the organization token instead of the access token because for resources belonging to an organization, we want to use organization permission control rather than user permission control (you'll better understand this when we implement the GET /documents API later).
Next, we create a GET /documents API in our backend service. Similar to how we use API resource to protect the POST /organizations API, we use organization-specific resource indicators to protect the GET /documents API.
First, let's create a requireOrganizationAccess middleware to protect Organization resources.
Then we use the requireOrganizationAccess middleware to protect the GET /documents API.
This way, we've implemented using organization tokens to access organization resources. In the backend service, you can retrieve corresponding resources from the database based on the organization id.
Implement organization-level role-based access control design#
We've implemented using organization tokens to access organization resources. Next, we'll implement user permission control within organizations using RBAC.
Let's assume DocuMind has two roles: Admin and Collaborator.
Admins can create and access documents, while Collaborators can only access documents.
Therefore, our Organization needs to have these two roles: Admin and Collaborator.
Admin has both read:documents and create:documents permissions, while Collaborator has only the read:documents permission.
Admin
read:documents
create:documents
Collaborator
read:documents
This is where Logto's organization template feature comes in.
An organization template is a blueprint of the access control model for every organization: it defines the roles and permissions that apply to all organizations.
Why organization template?
Because scalability is one of the most important requirements for SaaS products. In other words, what works for one client should work for all clients.
Let's go to Logto Console > Organization Templates > Organization permissions and create two permissions: read:documents and create:documents.
Then go to the organization roles tab to create two user roles: Admin and Collaborator, and assign corresponding permissions to these roles.
This way, we've created an RBAC permission model for each organization.
Next, we go to our Organization details page to assign appropriate roles to our members.
Now our organization users have roles!
You can achieve these steps via Logto Management API:
Now we can implement user permission control by checking their permissions.
In our code, we need to make the user's organization token carry permission information, and then verify these permissions in the backend.
In the frontend code's Logto config, we need to declare the permissions users need to request within the organization. Let's add read:documents and create:documents permissions to the scopes.
As usual, log in again with your user to make these configurations take effect.
Then in the backend's requireOrganizationAccess middleware, we add verification for user permissions.
Then create a POST /documents API, and use the requireOrganizationAccess middleware with requiredScopes configuration to protect this API and the previous GET /documents API.
This way, we've implemented user permission control by checking user permissions.
In the frontend, you can get user permission information by decoding the organization token or calling Logto's getOrganizationTokenClaims method.
Control page elements based on user permissions by checking the scopes in the claims.
So far, we've implemented the basic user and organization features in a multi-tenant SaaS system! However, there are still some features we haven't covered, such as customizing login page branding for each Organization, automatically adding users with specific domain emails to certain organizations, and integrating enterprise-level SSO functionality.
These are all out-of-the-box features, and you can find more information about these features in the Logto documentation.
Remember how overwhelming it felt at the beginning? Users, organizations, permissions, enterprise features... it seemed like an endless mountain to climb.
But look at what we've accomplished:
A complete authentication system with multiple sign-in options and MFA support
A flexible organization system that supports multiple memberships
Role-based access control within organizations
And the best part? We didn't have to reinvent the wheel. By leveraging modern tools like Logto, we transformed what could have been months of development into a matter of hours.
This is the power of modern development in 2025 - we can focus on building unique product features instead of wrestling with infrastructure. Now it's your turn to build something amazing!
Explore all of Logto’s features, from Logto Cloud to Logto OSS, on the Logto website or sign up Logto cloud today.