Skip to main content

Initial setup

Create your first tenant and configure authentication on it.

Before you start

This feature is only available to paid users.

These instructions assume that you already have gone through the main quickstart guide. If you have skipped that page please follow the tutorial and return here once you're done.

Steps

1. Create a tenant

The first step in setting up a multi tenant login system is to create a tenant in the SuperTokens core. Each tenant has a unique tenantId mapped to that tenant's configuation. The tenantId could be that tenant's sub domain, or a workspace URL, or anything else that can help identify them.

The configuration mapped to each tenant contains information about which login methods they enable.

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function createNewTenant() {
let resp = await Multitenancy.createOrUpdateTenant("customer1", {
firstFactors: ["emailpassword", "thirdparty", "otp-email", "otp-phone", "link-phone", "link-email"]
});

if (resp.createdNew) {
// Tenant created successfully
} else {
// Existing tenant's config was modified.
}
}

The snippet creates a new tenant with the id "customer1". It enables the email password, third party and passwordless login methods for this tenant. You can also disable any of these by not including them in the firstFactors input. If firstFactors is not specified, by default, the system does not enable any of the login methods.

If you set firstFactors to null the SDK uses any of the login methods.

The built-in Factor IDs available for firstFactors include:

Authentication TypeFactor ID
Email password authemailpassword
Social login / enterprise SSO auththirdparty
Passwordless - Email OTPotp-email
Passwordless - SMS OTPotp-phone
Passwordless - Email magic linklink-email
Passwordless - SMS magic linklink-phone

Configure third party providers

If you are using the thirdparty recipe on a tenant, you also need to set the providers that you want to use with it. There's an extensive list of built-in providers, but you can also configure a custom provider.

The next code snippet shows how you can add an Active Directory login to your tenant. Update the clientId, clientSecret, and directoryId based on your tenant configuration.

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function addThirdPartyToTenant() {
let resp = await Multitenancy.createOrUpdateThirdPartyConfig("customer1", {
thirdPartyId: "active-directory",
name: "Active Directory",
clients: [{
clientId: "...",
clientSecret: "...",
}],
oidcDiscoveryEndpoint: "https://login.microsoftonline.com/<directoryId>/v2.0/.well-known/openid-configuration",
});

if (resp.createdNew) {
// Provider added to customer1
} else {
// Existing provider config overwritten for customer1
}
}

2. Provide additional configuration per tenant

You can also configure a tenant to use different settings. The next sample shows you how to customize the values.

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function createNewTenant() {

let resp = await Multitenancy.createOrUpdateTenant("customer1", {
coreConfig: {
"email_verification_token_lifetime": 7200000,
"password_reset_token_lifetime": 3600000,
"postgresql_connection_uri": "postgresql://localhost:5432/db2",
}
});

if (resp.createdNew) {
// new tenant was created
} else {
// existing tenant's config was modified.
}
}

In the above example, the system assigns different values for certain configurations for customer1 tenant. All other configurations inherit from the base configuration.

Notice the postgresql_connection_uri. This allows you to achieve data isolation on a tenant level. This configuration is not required. If not provided, the database stores the tenant's information as specified in the core's configuration. It is still a different user pool though.

3. View tenant details

To view the configuration for a specific tenant you can use an SDK method or call the API directly.

import Multitenancy from "supertokens-node/recipe/multitenancy";

async function getTenant(tenantId: string) {

let resp = await Multitenancy.getTenant(tenantId);

if (resp === undefined) {
// tenant does not exist
} else {
let coreConfig = resp.coreConfig;

let firstFactors = resp.firstFactors;

let configuredThirdPartyProviders = resp.thirdParty.providers;
}
}

The returned coreConfig is the same as what you set when creating / updating the tenant. The rest of the core configurations for this tenant inherit from the app's (or the public tenant) configuration. The public tenant, for the public app inherits its configurations from the config.yaml / docker environment variables values.

4. Set up the user interface

To allow users to authenticate using one of your previously created tenants you need to update your frontend application. You can do this in two ways: through a common domain, through subdomains.

Explore the two guides for a full list of instructions on how to implement the flows.

See also