Tenants with Management SDKs

If you wish to learn more about Tenants in general, visit our section on Tenant Management.

The Descope service supports multi-tenancy architecture natively. Each project can have multiple tenants, and the end-users can be assigned to either the project or can belong to one or many tenants. The most common use case of tenants is when you are building a B2B application, and each of your customers can have multiple users. You must manage these users and their roles at a tenant level. Descope admins can create and update tenants either manually in the Descope console or using the tenant management API and sdk from within their application as show below.

Tenant management using the management SDK

Install SDK

Terminal
npm i --save @descope/node-sdk

Import and initialize Management SDK

import DescopeClient from '@descope/node-sdk';
 
const managementKey = "xxxx"
 
try{
    //  baseUrl="<URL>" // When initializing the Descope clientyou can also configure the baseUrl ex: https://auth.company.com  - this is useful when you utilize CNAME within your Descope project.
    const descopeClient = DescopeClient({ projectId: '__ProjectID__', managementKey: managementKey });
} catch (error) {
    // handle the error
    console.log("failed to initialize: " + error)
}
 
// Note that you can handle async operation failures and capture specific errors to customize errors.
//     An example can be found here: https://github.com/descope/node-sdk?tab=readme-ov-file#error-handling

Load All tenants

Use the code below to load all existing tenants within the project

let resp = await descopeClient.management.tenant.loadAll();
if (!resp.ok) {
  console.log("Unable to load tenants.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully loaded tenants:")
  console.log(resp.data)
}

Load Tenant by ID

This function allows for you to load a specific tenant based on the tenant's ID.

// Args:
//  id (String): The ID of the tenant which you want to load
const id = "xxxx"
 
let resp = await descopeClient.management.tenant.load(id);
if (!resp.ok) {
  console.log("Failed to load tenant.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully loaded tenant.")
  console.log(resp.data)
}

Search Tenants

This function allows for you to search Descope tenants by ID, name, self service provisioning domain, and custom attributes.

// Args:
//  ids (String[]): Array of tenant IDs to search for.
const ids = ["TestTenant"]
//  names (String[]): Array of tenant names to search for.
const names = ["TestTenant"]
//  selfProvisioningDomains (String[]): Array of self service provisioning domains to search for.
const selfProvisioningDomains = ["example.com", "company.com"]
//  customAttributes (String[]): Array of self service provisioning domains to search for.
const customAttributes = {"mycustomattribute": "Test"}
 
// When searching based on one of these items or a few of these items, leave the applicable items you are not searching for to null.
let resp = await descopeClient.management.tenant.searchAll(ids, names, selfProvisioningDomains, customAttributes);
 
if (!resp.ok) {
  console.log("Failed to search tenants.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully searched tenants.")
  resp.data.forEach((tenant) => {
    console.log(tenant)
  });
}

Create Tenant

At the time of creation, the tenant must be given a name and a tenant-id. If you don't provide a tenant-id, a tenant-id is automatically generated. The tenant-id is used for sign-up/sign-in and other management operations later. In addition, you can also set domains for the tenant. The domain is used to automatically assign the end-user to a tenant at the time of sign-up and sign-in. The tenant name must be unique per project. The tenant ID is generated automatically for the tenant when not provided.

// There are two ways to create a tenant via SDK. createWithId (which will assign the given id) and create (which will automatically generate the id). Examples below:
// createWithId: Create a new tenant with a given name and tenant id.
// ==================================================================
// Args:
//    name (str): The tenant's name
var name = "TestTenantCreateWithId"
//    id (str): The tenant's id.
var id = "TestConfiguredId"
//    selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant.
var selfProvisioningDomains = ["TestDomain1.com", "TestDomain2.com"]
//   customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
 
let resp = await descopeClient.management.tenant.createWithId(id, name, selfProvisioningDomains, customAttributes)
if (!resp.ok) {
  console.log(resp)
  console.log("Unable to create tenant.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully created tenant.")
  console.log(resp.data)
}
 
// Create: Create a new tenant with the given name. The id will be automatically generated and returned.
// ==================================================================
// Args:
//    name (str): The tenant's name
name = "TestTenantCreateGeneratedId"
//    selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant.
selfProvisioningDomains = ["TestDomain3.com", "TestDomain4.com"]
//   customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
 
resp = await descopeClient.management.tenant.create(name, selfProvisioningDomains, customAttributes)
if (!resp.ok) {
  console.log("Unable to create tenant.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully created tenant.")
  console.log(resp.data)
}

Update Tenant

Use the code below to update an existing tenant with the given name and domains. All parameters are used as overrides to the existing tenant. Empty fields will override populated fields.

// Args:
//    id (str): The tenant's id.
var id = "xxxxxx"
//    name (str): The tenant's name
var name = "Test Updated Name"
//    selfProvisioningDomains (List[str]): An optional list of domains that are associated with this tenant. Users authenticating from these domains will be associated with this tenant. If changed, it will be the new list of self provisioned domains.
var selfProvisioningDomains = ["TestUpdatedDomain1.com", "TestUpdatedDomain2.com"]
//   customAttributes (dict): Optional, set the different custom attributes values of the keys that were previously configured in Descope console app
const customAttributes = {"attribute1": "Value 1", "attribute2": "Value 2"}
 
const resp = await descopeClient.management.tenant.update(id, name, selfProvisioningDomains, customAttributes);
if (!resp.ok) {
  console.log(resp)
  console.log("Failed to update tenant.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully update tenant.")
  console.log(resp.data)
}

Delete Tenant

Use the code below to delete an existing tenant. Please note that this action is irreversible.

// Args:
//    id (str): The tenant's id.
var id = "xxxxxx"
//    cascade (boolean): Pass true to cascade value, in case you want to delete all users/keys associated only with this tenant
var cascade = false
 
let resp = await descopeClient.management.tenant.delete(id, cascade);
if (!resp.ok) {
  console.log(resp)
  console.log("Unable to delete tenant.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully deleted tenant.")
  console.log(resp.data)
}

Update Tenant Password Policy

Use the code below to update password policy for your tenant.

// Args:
  //tenantId (str): The tenant Id whose password policy has to be updated.
  //enabled (boolean): To enable 
  //minLength (int) : minimum passwords length
  //lowercase (boolean): Requires atleast one lowercase letter
  //uppercase (boolean): Requires atleast one uppercase letter
  //number (boolean): Requires atleast one number
  //nonAlphaNumeric (boolean) : Requies at least one non-alphanumeric character
  //expiration (boolean): Enable password expiration
  //expirationWeeks (int): Password expiration period in weeks
  //reuse (boolean): Enable/Disable prevent password reuse
  //reuseAmount (int): Number of passwords to remember
  //lock (boolean) : Enable/Disable account locking
  //lockAttempts (int) : Lock account after this number of attempts
 
const tenantId = "xxxx"
const policysetting = {
  enabled: true,
  minLength: 8,
  expiration: true,
  expirationWeeks: 4,
  lock: true,
  lockAttempts: 5,
  reuse: true,
  reuseAmount: 6,
  lowercase: true,
  uppercase: false,
  number: true,
  nonAlphaNumeric: false,
 
}
 
const resp = await descopeClient.management.password.configureSettings(tenantId, policysetting);
if (!resp.ok) {
  console.log("Failed to update access key.")
  console.log("Status Code: " + resp.code)
  console.log("Error Code: " + resp.error.errorCode)
  console.log("Error Description: " + resp.error.errorDescription)
  console.log("Error Message: " + resp.error.errorMessage)
}
else {
  console.log("Successfully updated password policy.")
  console.log(resp.data)
}
Was this helpful?

On this page