Multi-Tenant SaaS Applications With Stormpath - Stormpath
Multi-Tenant SaaS Applications With Stormpath - Stormpath
Language: Guides
Multi-Tenant SaaS
Applications with
Stormpath
(/guides/multi-tenant)
What is Stormpath?
What is a MultiTenant SaaS
Application?
Why Build a MultiTenant SaaS
Application?
What is Stormpath?
Stormpath is a user management API that makes it easy for developers to launch applications with secure, scalable user
infrastructure. It automates:
User Account registration and login
Multi-Tenant Design
Multi-Tenant User
Management
Why use Stormpath
for Multi-Tenant SaaS
Applications?
Were Always Here to
Help
Using ID Site
(/guides/using-id-site)
While Stormpath is a great choice for any application, it excels for multi-tenant use cases.
Integrating Stormpath
with Facebook and
Google (/guides/socialintegrations)
Integrating Stormpath
with Active Directory
and LDAP (/guides/adldap)
Setting up
Development and
Production
Environments
(/guides/dev-testprod-environments)
Using Stormpath for
API Authentication
(/guides/api-key-
Most web applications are designed to support only one user base or organization: typically the organization installs
and maintains the application. This traditional software architecture usually has an application codebase that uses a
primary database. For example:
Application
|
|
\/
-- Database -|
data
|
--------------
A multi-tenant SaaS application by contrast is a single application that can service multiple organizations simultaneously.
In these applications, each organization is referred to as a tenant.
Just like in an apartment building, although there is a single building, there may be multiple tenants, each with their own
apartment in the building. Similarly, a multi-tenant SaaS application needs to ensure that each Tenant or customer
organization has its own private space that cannot be seen or interfered with by other Tenants/Organizations: when
Organization As users access the application, they cannot see Organization Bs data, and vice versa. In this guide and
elsewhere in Stormpath documentation tenant refers to the data partition specific to a customer organization.
To ensure data separation, a multi-tenant SaaS application typically partitions each tenants data virtually, so that the
data is cleanly segmented in the data store. This means a multi-tenant SaaS application architecture looks something
like this:
Application
|
|
\/
------- Database ---------| org1 | org2 | ... | orgN |
--------------------------
https://docs.stormpath.com/guides/multi-tenant/
1/9
8/6/2015
Multi-Tenant Design
There are a lot of ways to build multi-tenant SaaS applications. For the purpose of this article, were going to focus on
approaches to support the significant majority of multi-tenant SaaS apps:
A public (Internet-facing) multi-tenant web application with per-organization data partitioning. For example:
https://myapplication.io
When an organization registers with myapplication.io a new tenant (partitioned data space) is created for them.
When users from that organization log in to the application, they will access and see only their own tenant/organization
data, and the application must know which tenant/organization the user is attempting to access. This is almost always
done by the user specifying a tenant identifier when accessing the application.
TENANT IDENTIFIER
When a new organization signs up and their tenant is created, a globally-unique name identifier is almost always
assigned to that tenant/organization. This identifier (unique across all tenants) is typically represented in some way on
every request to the application.
The application then uses this identifier to restrict which (virtual) data partition is accessed during a request.
For example, lets say we have a multi-tenant e-commerce SaaS application that shows purchase history. If a user
requests the /purchases view, they should only be able to see the purchases specific to their tenant/organization.
This means that instead of executing a query like this to a database:
The application needs to know the request users tenant identifier so they can show only the purchases for that tenant.
The application might instead execute the following query:
https://docs.stormpath.com/guides/multi-tenant/
2/9
8/6/2015
1. Subdomain Name
When generating or assigning the tenants name identifier, ensure it is a valid unique subdomain name. This could allow
users from an organization to access your application via a unique subdomain URL for all of their needs, for example:
https://organizationA.myapplication.io (https://organizationA.myapplication.io)
This approach is really nice: the application never needs to ask the user for the tenant identifier, because it is inherently
part of every request in the HOST header.
This is the most intuitive and convenient tenant identifier convention weve seen we recommend this approach.
Subdomain Name Specification
This approach requires your name identifiers to be compliant with the subdomain
(http://en.wikipedia.org/wiki/Subdomain) naming specification. The name must:
Be between 1 and 63 characters long (64 or more is too long)
Not contain any whitespace at all
Contain only lowercase** characters a-z or the dash character Not start with or end with a dash ** Techically, subdomain names are case insensitive, but if you force them to be all lowercase in your application, youll
guarantee uniqueness and prevent unexpected collisions.
Subdomain Tips
Keep your customer organization subdomains space completely separate from your companys subdomain space
by using a different top-level (aka apex) domain name for your SaaS application.
Lets say your companys website url is http://mycompany.com.
We do NOT recommend supporting customer subdomains like this:
http://customerA.mycompany.com http://customerB.mycompany.com
In this scenario, it is possible that a customers chosen subdomain can conflict with a subdomain your company
might need, either now or in the future. For example, what if a customer chose the subdomain name of docs?
This would mean that your own company couldnt use http://docs.mycompany.com later, because it is taken
by one of your customers. It is also a difficult and unnecessarily time-consuming exercise to try to determine which
domains you might use for your company in the future and block them off in your application. Even then, you may
still have conflicts later.
Instead, we believe it is better to have a separate top-level domain for the product. For example:
http://mycompany.io
Then you can have as many subdomains for customers as necessary, and they will never conflict with your
companys own subdomain needs.
If you didnt want to use a separate top-level domain, you could also use sub-subdomains. For example, the app
could be accessible here:
http://myapp.mycompany.com
And customer organization subdomains for that app would be accessible via:
http://customerA.myapp.mycompany.com
http://customerB.myapp.mycompany.com
etc.
It is our opinion that the separate top-level domain, e.g. http://mycompany.io is the nicer alternative: it is
shorter, easier to remember and type, and looks better.
https://docs.stormpath.com/guides/multi-tenant/
3/9
8/6/2015
https://myapplication.io
Email : ________________________
Password: ________________________
Submit
https://docs.stormpath.com/guides/multi-tenant/
4/9
8/6/2015
The user selects the tenant (s)he wants to use, and all subsequent requests are handled based on the subdomain
name as explained above.
https://myapplication.io
Email : ________________________
Password: ________________________
Submit
Organization: ________________________
Email
: ________________________
Password
: ________________________
Submit
Then, when the customer logs in successfully, you can store their tenant id (represented to the end-user as an
Organization field) in their HTTP Session. Then, for all subsequent requests to your application, you can:
1. Inspect the session
2. Look up the tenant id
3. Customize data views and queries based on the sessions tenant id
Login Form Field Tips
We STRONGLY advise that, even if you do not support subdomains today, that your human-readable tenant
identifiers still adhere to the domain name specification. This allows you to support subdomains at any point in the
future, as soon as youre able to setup network infrastructure to do so. Do this in the beginning and you will likely
eliminate many problems later.
We advise that you auto-remember the login form tenant id value in a cookie so that field is pre-populated
whenever a user returns to log in. Users dont like having to remember and type that value in every time they log
in.
We strongly advise you start with the subdomain naming approach. Although you can start with the Login
Form-based approach, it can be a pain to retrofit the application for subdomains later. We speak from
experience!
https://docs.stormpath.com/guides/multi-tenant/
5/9
8/6/2015
+---------+
+----->| Account |
| 1..* +---------+
+-------------+
| Application |
+-------------+
| 1..* +-------+
+----->| Group |
+-------+
But this isnt very flexible and can cause problems over time especially if you need to support more applications or
services in the future.
Stormpath is more powerful and flexible. Instead of tightly coupling Accounts and Groups directly to a single
Application, Accounts and Groups are owned instead by a Directory, and an Application can reference one or
more Directorys dynamically:
Stormpath User Management Model:
+---------+
+----->| Account |
| 1..* +---------+
+-------------+ 1..* +-----------+
| Application |----->| Directory |
+-------------+
+-----------+
| 1..* +-------+
+----->| Group |
+-------+
A Directory isnt anything complicated think of it just as a top level bucket for Accounts and Groups.
This model gives you many benefits:
Multiple applications can reference the same Directory and share users.
You can segment user populations into multiple directories.
An application can plug in to multiple directories, so multiple user populations can access the same application.
You can disassociate directories or groups from applications, preventing those users from logging in.
Security policies for Accounts are configured at the Directory level, giving you tighter control over security
https://docs.stormpath.com/guides/multi-tenant/
6/9
8/6/2015
https://docs.stormpath.com/guides/multi-tenant/
7/9
8/6/2015
{
"href": "https://api.stormpath.com/v1/groups/2gdhVFEQMXpaUMAPzLXen4"
"name": "customerA"
... remaining fields omitted for brevity ...
}
POST https://api.stormpath.com/v1/directories/29E0XzabMwPGluegBqAl0Y/groups
{
"name": "2gdhVFEQMXpaUMAPzLXen4_administrators"
}
underscore_index = stormpath_group.name.last_index_of('_')
display_name = stormpath_group.name.substring(underscore_index)
print("You are a member of the " + display_name + "group")
https://docs.stormpath.com/guides/multi-tenant/
8/9
8/6/2015
GET https://api.stormpath.com/v1/directories/29E0XzabMwPGluegBqAl0Y/groups?name=2gdhVFEQMXpa
UMAPzLXen4_*
Notice the asterisk at the end of the query? Stormpaths query support (https://docs.stormpath.com/rest/productguide/#Directory-groups) supports starts-with matching, so the above query will return all groups that start with our ID
+ underscore prefix.
If you wanted to retrieve the tenant group and all of its subgroups, make the query a little less restrictive by removing
the underscore:
GET https://api.stormpath.com/v1/directories/29E0XzabMwPGluegBqAl0Y/groups?name=2gdhVFEQMXpa
UMAPzLXen4*
APPROACH 2: DIRECTORY-PER-TENANT
In Stormpath, an Account is guaranteed to be unique only within a Directory. This means:
Note:
As a result, you could create a Directory in Stormpath for each of your tenants, and your user Account identities will be
100% separate. With this Directory-per-Tenant approach, your applications user Accounts are guaranteed to be unique
within a tenant (Directory) but can exist independently in multiple directories.
Directory-per-Tenant is an advanced data model that offers more flexibility, but at the expense of complexity. It is the
model that Stormpath itself uses and it is only recommended for more advanced applications or those with special
requirements. As a result, we dont cover the approach in further detail here. If you feel the Directory-per-Tenant
approach might be appropriate for your project, and youd like some advice, please contact [email protected]
(mailto:[email protected]). We are happy to help you model out your user data, whether or not Stormpath is the
right option for your application.
C OP YR I GH T 2 0 1 5 S TO RM P ATH, I N C.
https://docs.stormpath.com/guides/multi-tenant/
ALL R I GH TS R E SE R VE D
P RI VA CY PO L IC Y (/ PR I VA CY_ P O LI C Y)
TE R MS OF S E R VI CE ( / TE R MS _O F _S ER V IC E )
9/9