English
  • saas development
  • multi-tenant saas
  • saas architecture
  • saas boilerplate

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.

Yijun
Yijun
Developer

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!

documind-home-page.png

Documind dashboardDocumind organization page

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 at the end of this article. 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?

Multi-tenant architecture

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.

multi-tenant-app-architecture.svg

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.

organization-examples.png

Membership

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.

Role and permission design

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:

  1. Users who join an organization automatically get the member role.
  2. The first user to create a workspace is automatically assigned the admin role.

Sign-up and login flow

Ensure a user-friendly and secure registration and authentication process, including basic sign-in and sign-up options:

  1. Email and password sign-in: Traditional login method with email and password.
  2. Passwordless sign-in: Use email verification codes for easy and secure access.
  3. Account management: An account center where users can update their email, password, and other details.
  4. Social sign-in: Options like Google and GitHub for quick login.
  5. Multi-Factor Authentication (MFA): Enhance security by allowing login via authenticator apps like Duo.

Tenant creation and invitation

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 typeEntry point
New accountEnter from sign in and sign up page to create a new tenant
Existing accountCreate another tenant inside the product
The existing account got a new tenant invitationEnter from sign in and sign up page
The existing account got a new tenant invitationEnter from the invitation email
The new account got a new tenant invitationEnter from sign in and sign up page
The new account got a new tenant invitationEnter 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.

A new account creates a tenantAn existing user creates another tenant
An existing user sign in An existing user join through email
A new user sign-inAn new user join through email

Technical architecture and system design

Once we understand all the product requirements, let’s move on to the implementation.

Define authentication strategy

Authentication looks scary. Users need:

  • Email & password sign-up/login
  • One-click sign-in with Google/Github
  • Password reset when they forget
  • Team-wide login for enterprise customers
  • ...

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!

Establish multi-tenant architecture

The organization system enables users to create and join multiple organizations. Let's understand the core relationships:

In this system, each user can belong to multiple organizations, and each organization can have multiple members.

Enable access control in multi-tenant app

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:

  1. Unified permission definitions: Permissions are defined at the system level and apply consistently across all organizations, ensuring maintainable and consistent permission management
  2. 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!

Tech stack

I chose a beginner-friendly, portable stack:

  1. Frontend: React (easily transferable to Vue/Angular/Svelte)
  2. 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.

Add basic authentication flow to your app

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.

Install Logto to your app

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:

documind-home-page.png

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.

Customize sign in and sign up methods

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.

sign-in-experience-settings.png

And the sign-in flow will look like this:

Logto sign-in page

Enable multi-factor authentication

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.

mfa-settings.png

And the MFA flow will look like this:

Mfa verification stepScan QR code in authenticator app

Everything is so simple! We've set up a complex user authentication system in just a few minutes!

Adding multi-tenant organization experience

Now have our first user! However, this user doesn't belong to any organization yet, and we haven't created any organizations.

Logto provides built-in support for multi-tenancy. You can create any number of organizations in Logto. Each organization can have multiple members.

Each user can get their organization information from Logto. This enables multi-tenancy support

Get a user's organization information

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".

dashboard-no-orgs.png

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:

  1. Manually create organizations through the Logto Console
  2. Use the Logto Management API to create organizations, especially when designing a SaaS flow that lets users create their own organizations (workspaces).

Create organization in Logto console

Click the "Organizations" menu button on the left side of the Logto Console. Create an organization.

Now you have your first organization.

console-organizations.png

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.

console-add-member-to-orgs.png

Refresh your APP page. You'll see the user now belongs to an organization!

dashboard-has-orgs.png

Implement self-serve organization creation experience

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.

For guidance, check out the Interact with Management API documentation to set up API communication with Logto.

Understand organization auth interaction flow

Let’s take organization creation flow as an example. Here's how the organization creation process works:

This flow has two key authentication requirements:

  1. Protecting backend service API:
    • Frontend access to our Backend Service API requires authentication
    • API endpoints are protected by validating user's Logto Access Token
    • Ensures only authenticated users can access our services
  2. Accessing Logto Management API:
    • Backend Service needs to securely call Logto Management API
    • Follow the Interact with Management API guide for setup
    • Use Machine-to-Machine authentication to obtain access credentials

Protect your backend 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.

  1. Click the "API resources" button on the right.
  2. Click "Create API resource". Select Express in the popup.
  3. Fill in "DocuMind API" as the API name. Use "https://api.documind.com" as the API identifier.
  4. Click create.

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.

Calling Logto Management API

Let's implement organization creation using the Logto Management API.

Like frontend requests to backend service, backend service requests to Logto need Access tokens.

In Logto, we use Machine-to-Machine authentication for access tokens. See Interact with Management 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.

m2m-application.png

Now we can get Logto Management API access tokens through this M2M application.

Use this access token to call Logto Management API.

We'll use these Management APIs:

We've now implemented organization creation through Logto Management API. We can also add users to organizations.

Let's test this feature in the Dashboard.

dashboard-create-org.png

and click “Create Organization”

dashboard-has-orgs.png

Creation successful!

The next step would be inviting users to an organization. We won't implement this feature in our tutorial yet. You already know how to use the Management API. You can refer this Tenant creation and invitation as product design reference and easily implement this feature by following this blog post: How we implement user collaboration within a multi-tenant app.

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

Let's see how to implement these features.

Using Logto organization token

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:

  1. 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.
  2. 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.

Some software requires data isolation between organizations. For further discussion and implementation, you can refer to the blog post: Multi-tenancy implementation with PostgreSQL: Learn through a simple real-world example.

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.

org-template-permission.png

Then go to the organization roles tab to create two user roles: Admin and Collaborator, and assign corresponding permissions to these roles.

organization-details.png

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.

org-template-role.png

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.

Add more multi-tenant app features

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.

Summary

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.

The complete source code for this tutorial is available at: Multi-tenant SaaS Sample.

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.