Using the Cylance Multi-Tenant Console (MTC) API

The Cylance Mult-Tenant Console (MTC) enables partners to manage and interact with their Cylance Protect tenants in a centralized manner. Using the v2 MTC API, developers can automate many important workflows such as creating a new Protect Tenant or getting a tenant’s install token for automating device provisioning. There are many great C.R.U.D (Create, Read, Update, Delete) based automation use-cases for Cylance MTC API developers. 

For more information on the API endpoints available, check out this handy API documentation.

In this blog, we will be discussing how to directly interact with your underlying Cylance PROTECT tenant’s REST APIs starting from the MTC API. The following examples will be in Python 3. 

First, we must create an “Application” in the Mult-Tenant Console. For the purposes of the blog's API calls, ensure that “Tenant API Management” is selected under “Manage”. 

Before we can make our MTC API calls, we must get authenticated with the MTC API, which will give us an authentication token. Here is that API call in Python:

1.      [Multi-Tenant Cylance API] /POST/ auth

import base64 import requests def authenticate(app_id, app_secret, region): base_url = "{region}".format(region=region) authenticate_url = base_url + "/auth" """ Generating the Authorization header value. """ pre_encoded_str = "{app_id}:{app_secret}".format(app_id=app_id, app_secret=app_secret) base64_encoded = base64.b64encode(pre_encoded_str.encode()) basic_auth = "Basic {auth}".format(auth=base64_encoded.decode()) payload = 'grant_type=client_credentials&scope=api' headers = {"Content-Type": "application/x-www-form-urlencoded", "Authorization": basic_auth} response =, data=payload, headers=headers) print(response)

Next, we need the Tenant ID of the Cylance PROTECT Tenant we want to make direct API Calls to.  For the sake of this blog, we are going to GET all of them in a list and choose one to work with.

2.      [Multi-Tenant Cylance API] /GET/ tenants/list

import json def list_tenants(region, auth_token): base_url = "{region}".format(region=region) list_tenants_url = base_url + "/tenants/list" headers = {"Authorization": "Bearer {auth_token}".format(auth_token=auth_token)} response = requests.get(list_tenants_url, headers=headers) json_response = json.loads(response.text) print(json_response["listData"])

This response will contain all the tenants you manage under your MTC. Choose one for the next API call.

This next API call to /tenants/tenant-app/{venue_tenant_id} is a “PUT” call. It allows you to get authorization for managed tenants' APIs.

1.      It will generate a custom ‘Application’ in the underlying Tenant with FULL permissions.

a.      This only occurs on the first call. Subsequent calls use the existing custom ‘Application’ generated by this API. 

2.      It will generate a valid JWT token in that custom ‘Application’ scope.

3.      It will return this JWT token to the caller.

4.      You can use the JWT token to authorize requests against the PROTECT Web API.

This is what the generated ‘Application’ looks like in the underlying tenant’s “Settings -> Integrations” tab. 

Here’s what that API call looks like in Python:

3.      [Multi-Tenant Cylance API] /PUT/ tenants/tenant-app/{venue_tenant_id}

def put_application_for_tenant(region,tenant_id, auth_token): base_url = "{region}".format(region=region) url = base_url + "/tenants/tenant-app/{tenant_id}".format(tenant_id=tenant_id) headers = {"Authorization": "Bearer {}".format(auth_token)} response = requests.put(url, headers=headers) print(response.text)

The response of this MTC API call includes a valid JWT token for Cylance PROTECT Web API calls.

Finally, let’s use our JWT token to make API calls to our selected PROTECT tenant that we manage. The API call I’ll be making is ‘GET’ Devices, however, there are MANY API calls you can make. For example, you can check out our blog on remotely locking down a device via API calls!

4.      [Cylance Protect API] /GET/ devices   

url = "" headers = {'Accept': 'application/json', 'Authorization': f"Bearer {JWT_token}"} response = requests.get(url, headers=headers) print(response.text)
Armed with these examples, you can now fully automate interactions, gather required details, and perform any of these calls on your managed tenants chained from MTC API calls! 
Matthew Falkner

About Matthew Falkner

I work in Enterprise Solutions Development at BlackBerry.