Skip to content

Multi tenant explained

Jon P Smith edited this page Aug 11, 2023 · 19 revisions

A multi-tenant application provides a way to deliver a service to multiple companies (known as tenants) with the minimum of hosting costs. It does this by storing each tenant's data using a tenant key (this is known as the DataKey in the AuthP library) and only that tenant can access its data. See the diagram below for an example of how this works.

BasicMultiTenantArchitecture

The diagram above isn't the only way to organisation the data and the database, but it shows the basics - which is that there can be different tenants and only users linked to a tenant can access their data.

There are two things that define the the multi-tenant data. They are

  1. The structure of the data, that is the arrangement of the data within a tenant.
  2. The database arrangement to hold the data, that is how you store the tenant data in databases.

In the next two "Defining..." sections will cover the options

1. Defining the two multi-tenant structures

The AuthP's provides two structures for holding the tenant's data. They are:

  • SingleLevel: This means each tenant is completely separate from other tenants. This is the typical way most multi-tenant databases are arranged.
  • HierarchicalTenant: This means each tenant can create sub-tenants which allows a manager the access the sub-tenants data. This is useful if you need a groups sub-tenants into groups so that they can be managed as one, e.g. managing the stock across a specific geographical area.

The multi-tenant part of AuthP is handled by creating a Tenant for each different grouping of data.

SingleLevel multi-tenant

In an application using the SingleLevel multi-tenant setting, then Tenant has a unique key and the data is never shared between other tenants. So the tenant names might be:

  • Company1
  • Company2
  • Company3
  • and so on...

HierarchicalTenant multi-tenant

If the application using the HierarchicalTenant multi-tenant setting, then one Tenant can link to a another tenant. This provides the 'higher' tenants to look at the data in the 'lower' tenants. So the tenant names might be:

  • Company1
    • West Coast
      • SanFran shop1
      • SanFran shop2
    • East Coast
      • ... and so on
  • Company2
    • London
      • ... and so on

Company1 and Company2 in this hierarchical setup are completely separate, but within each company users with a higher level can see data in the lower levels, e.g. a user linked to the "Company1" tenant can see all the data in Company!, while a user with a tenant of "Company1 -> West Coast" can only see the "West Coast", "West Coast -> SanFran shop1", and "West Coast -> SanFran shop2".

NOTE: All of a hierarchical tenant's data MUST be in the same database.

2. Defining the three multi-tenant database arrangements

In version 3 of the AuthP library the TenantTypes enum gains a AddSharding flag. This allows you to upgrade to using multiple databases to store tenant data. The diagram below defines three database arrangements with a summary of their Pros/Cons.

ThreeMultiTenantApproaches

NOTE: I would strongly recommend Microsoft's documentation about multi-tenant systems. This article covers all the different approaches to multi-tenant applications, including a comparison of each approaches.

Lets look at each database arrangement in turn.

1. One shared database

This is the easiest and simplest database arrangement, and also only needs one database which it can share with the AuthP DbContext. That means you only need one database, so its likely its cheaper if you are using a cloud database.

If you are starting building a multi-tenant application this database arrangement would a good starting point. If you find the performance isn't good enough you can upgrade to one of the other database arrangements later.

NOTE: If you do upgrade you can keep your current data and even move it to another database. You have to be careful, but it is possible.

2. Sharding - a database per tenant

This means each tenant has his own database. That's going to give you more performance and security, but it will cost you more.

NOTE: You should look out for Azure's SQL Server Elastic Pools, which helps manage the load across multiple databases.

3. Hybrid - offering both shared database and sharding

The implement of the sharding feature needed to work with the original shared database organisation, so the hybrid database arrangement is possible and useful. It lets you to group tenants that don't have a lot of data / usage in a single database while tenants with high data / usage can be placed in its own database.

NOTE: There is a tenant admin command that will move a tenant in a shared database to its own database, and the reverse (that is, own database tenant to shared database), but the part you have to write to implement this is complex.

How are you going to manage your multi-tenant application?

In my article "The (long) journey to a better sharding multi-tenant application" ??LINK?? I talk about two types of multi-tenant applications that might help you to decide how you want to manage (also known as administration). In this article I characterises the management two multi-tenant types as:

  1. The organisation who owns the multi-tenant applications takes control of the administration of the user, tenants, etc. This approach typically creates a more secure application, but you need hire people (referred to by app admin users) to administration the application. A bank app is a obvious version of this approach.
  2. Certain tenant users (known as tenant admin users) are give control over the tenant they are in, e.g. adding / remove users, changing the users capabilities (AuthP roles) etc. This approach needs you to hire lot less app admin users, but the downside is the multi-tenant administration code is more complex. However AuthP has built-in solutions to most of the tenant admin features. GitHub is a good example of this approach.

NOTE: see the article called "Building ASP.NET Core and EF Core multi-tenant apps – Part2: Administration" which covers all the ways to manage tenants, users, roles etc.

I suggest you "this section" ??LINK?? to "The (long) journey to a better sharding multi-tenant application" for a much longer description of these two types of administration.

Understanding AuthP's Tenant class does

The Tenant class contains information that defines the multi-tenant data. To create a new Tenant you have to provide a unique name e.g., "Company XYZ", and once created the method GetTenantDataKey() will return a unique string, known as the DataKey. This DataKey is what defines the unique 'slice' of your applications data.

Once an AuthP user has a Tenant class linked to it, then the AuthP's will automatically add a DataKey claim to the ASP.NET Core user. This allows you to send the DataKey claim value to your application's DbContext via the AuthP IGetDataKeyFromUser service (see GetDataKeyFromUser class) to filter your various entity classes using EF Core's Global Query Filters. How you do that is explained in the creating a multi-tenant app documentation.

The Tenant class also has a many-to-many link called TenantRoles to AuthP's Roles. This allows tenant

NOTE: If user hasn't got a Tenant class linked to it, then that user can't access any of the multi-tenant data.

There are two examples of multi-tenant applications you can run:

  • Example3, which implements a single-level multi-tenant application in a shared database.
  • Example4, which implements a hierarchical multi-tenant application in a shared database.
  • Example6, which implements a single-level multi-tenant application in a hybrid database arrangement with three databases.

Additional resources

Articles / Videos

Concepts

Setup

Usage

Admin

SupportCode

Clone this wiki locally