---
title: Tenant management
description: Use the tenant management plugin for an out-of-the-box admin experience
sidebar:
  order: 80
---

## Overview

This tutorial shows you how to add comprehensive tenant management functionality to your SuperTokens authentication flows.
The guide makes use of the plugins functionality which provides complete multi-tenancy management including tenant creation, user roles, invitations, join requests, and seamless tenant switching.

## Before you start

The tenant management plugin supports only the `React` and `NodeJS` SDKs.
Support for other platforms is under active development.

## Steps

### 1. Initialize the backend plugin

#### 1.1 Install the plugin

```bash
npm install @supertokens-plugins/tenants-nodejs
```

#### 1.2 Update your backend SDK configuration

```typescript
import SuperTokens from "supertokens-node";
import TenantsPlugin from "@supertokens-plugins/tenants-nodejs";

SuperTokens.init({
  appInfo: {
    appName: "My app",
    apiDomain: "https://api.example.com",
  },
  recipeList: [
    // your recipes
  ],
  experimental: {
    plugins: [TenantsPlugin.init()],
  },
});
```

##### Configuration options

The plugin supports the following configuration options:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `requireNonPublicTenantAssociation`    | `boolean` | `false` | Require users to associate with at least one non-public tenant |
| `requireTenantCreationRequestApproval` | `boolean` | `true` | Whether tenant creation requires admin approval |
| `enableTenantListAPI`                  | `boolean` | `false` | Enable API to list all tenants |
| `createRolesOnInit` | `boolean` | `true` | Auto-create required roles on init |

### 2. Initialize the frontend plugin

#### 2.1 Install the plugin

```bash
npm install @supertokens-plugins/tenants-react
```

#### 2.2 Update your frontend SDK configuration

```typescript
import SuperTokens from "supertokens-auth-react";
import ProfileBasePlugin from "@supertokens-plugins/profile-base-react";
import TenantsPlugin from "@supertokens-plugins/tenants-react";

SuperTokens.init({
  appInfo: {
    appName: "My app",
    apiDomain: "https://api.example.com",
    websiteDomain: "https://example.com",
  },
  recipeList: [
    // your recipes
  ],
  experimental: {
    plugins: [ProfileBasePlugin.init(), TenantsPlugin.init()],
  },
});
```

##### Configuration options

The plugin supports the following configuration options:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `requireTenantCreation`    | `boolean` | `false` | Whether users must create a tenant before accessing the app |
| `redirectToUrlOnJoiningTenant` | `string` | `/` | The path to which users are redirected after joining a tenant |

### 3. Test the implementation

With this configuration, users can access comprehensive tenant management features through the profile interface.
Make sure that you have a user with the required permissions and then access`/user/tenants/create` to create a new tenant.

## Customization

### Roles and permissions

The plugin automatically creates the following roles and permissions:

#### Default roles

| Role | Description | Permissions |
|------|-------------|-------------|
| `tenant-admin` | Full administrative access within the tenant | All tenant permissions |
| `tenant-member` | Basic member access within the tenant | `tenant-access` |
| `app-admin` | Global application administrator | All permissions across all tenants |

#### Available permissions

| Permission | Description |
|------------|-------------|
| `tenant-access` | Basic access to tenant |
| `list-users` | View list of users in tenant |
| `manage-invitations` | Create and manage tenant invitations |
| `manage-join-requests` | Approve or reject join requests |
| `change-user-roles` | Modify user roles within tenant |
| `remove-users` | Remove users from tenant |

### Email delivery configuration

Configure custom email delivery for tenant-related notifications:

```typescript check=false reason="This example omits the surrounding SuperTokens application configuration."
import SuperTokens from "supertokens-node";
import { PluginSMTPService } from "@supertokens-plugins/tenants-nodejs";
import TenantsPlugin from "@supertokens-plugins/tenants-nodejs";

SuperTokens.init({
  // ... other config
  experimental: {
    plugins: [
      TenantsPlugin.init({
        emailDelivery: {
          service: new PluginSMTPService({
            smtpSettings: {
              host: "smtp.example.com",
              port: 587,
              from: {
                name: "Your App",
                email: "noreply@example.com",
              },
              secure: false,
              authUsername: "username",
              password: "password",
            },
          }),
        },
      }),
    ],
  },
});
```

### Custom implementation override

You can override default behaviors by providing custom implementations:

```typescript check=false reason="This example omits surrounding application and SuperTokens configuration."
TenantsPlugin.init({
  override: {
    functions: (originalImplementation) => ({
      ...originalImplementation,
      isAllowedToCreateTenant: async (session) => {
        // Custom logic to determine if user can create tenant
        const userId = session.getUserId();
        // Add your custom logic here
        return true;
      },
      canApproveJoinRequest: async (targetUser, tenantId, session) => {
        // Custom logic for approving join requests
        return true;
      },
    }),
  },
});
```

### Custom user interface

To create your own UI you can use the `usePluginContext` hook.
It exposes an interface which you can use to interface with the endpoints exposed by the backend plugin.

```tsx
import { useState } from "react";
import { usePluginContext } from "@supertokens-plugins/tenants-react/dist/plugin";

function CustomTenantComponent() {
  const { api, t } = usePluginContext();
  const [tenants, setTenants] = useState<Array<{ id: string; name: string; role: string }>>([]);

  const handleFetchTenants = async () => {
    const result = await api.fetchTenants();
    if (result.status === "OK") {
      setTenants(result.tenants);
    }
  };

  const handleCreateTenant = async (name: string) => {
    const result = await api.createTenant({ name });
    if (result.status === "OK") {
      console.log("Tenant created successfully");
    }
  };

  const handleSwitchTenant = async (tenantId: string) => {
    const result = await api.switchTenant(tenantId);
    if (result.status === "OK") {
      console.log("Switched to tenant successfully");
    }
  };

  return (
    <div>
      <h2>{t("PL_TB_CREATE_TENANT_LABEL")}</h2>
      <button onClick={handleFetchTenants}>Load Tenants</button>
      {tenants.map((tenant) => (
        <div key={tenant.id}>
          <span>
            {tenant.name} ({tenant.role})
          </span>
          <button onClick={() => handleSwitchTenant(tenant.id)}>Switch</button>
        </div>
      ))}
    </div>
  );
}
```

### Custom page components

You can customize the default pages by providing your own components:

```typescript check=false reason="This example depends on local application modules."
import TenantsPlugin from "@supertokens-plugins/tenants-react";
import { CustomSelectTenant, CustomTenantManagement } from "./your-custom-components";

SuperTokens.init({
  // ... other config
  experimental: {
    plugins: [
      TenantsPlugin.init({
        override: (oI) => ({
          ...oI,
          pages: (originalPages) => ({
            ...originalPages,
            selectTenant: CustomSelectTenant,
            tenantManagement: CustomTenantManagement,
          }),
        }),
      }),
    ],
  },
});
```

## Next steps

Besides tenant management, you can also explore other enterprise authentication features:

<CardGroup cols={3}>
  <Card title="Tenant discovery" href="/authentication/enterprise/tenant-discovery" />
  <Card title="Initial setup" href="/authentication/enterprise/initial-setup" />
  <Card title="Manage tenants" href="/authentication/enterprise/manage-tenants" />
  <Card title="User roles" href="/additional-verification/user-roles/introduction" />
  <Card title="Plugins reference" href="/references/plugins/introduction" />
</CardGroup>
