Deployments and TestingUser Impersonation

User Impersonation with Management SDKs

The management SDK requires a management key, which can be generated here.

You can use Descope management SDK for user impersonation operations.

Install SDK

Terminal
npm i --save @descope/node-sdk
Terminal
pip3 install descope
Terminal
go get github.com/descope/go-sdk
// Include the following in your `pom.xml` (for Maven)
<dependency>
    <artifactId>java-sdk</artifactId>
    <groupId>com.descope</groupId>
    <version>sdk-version</version> // Check https://github.com/descope/descope-java/releases for the latest versions
</dependency>
Terminal
gem install descope

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 a custom domain within your Descope project.
    const descopeClient = DescopeClient({ projectId: '__ProjectID__', managementKey: managementKey });
} catch (error) {
    // handle the error
    console.log("failed to initialize: " + error)
}
from descope import (
    REFRESH_SESSION_TOKEN_NAME,
    SESSION_TOKEN_NAME,
    AuthException,
    DeliveryMethod,
    DescopeClient,
    AssociatedTenant,
    RoleMapping,
    AttributeMapping
)

management_key = "xxxx"

try:
    # You can configure the baseURL by setting the env variable Ex: export DESCOPE_BASE_URI="https://auth.company.com  - this is useful when you utilize a custom domain within your Descope project."
    descope_client = DescopeClient(project_id='__ProjectID__', management_key=management_key)
except Exception as error:
    # handle the error
    print ("failed to initialize. Error:")
    print (error)
import "github.com/descope/go-sdk/descope"
import "github.com/descope/go-sdk/descope/client"
import "fmt"

// Utilizing the context package allows for the transmission of context capabilities like cancellation
//      signals during the function call. In cases where context is absent, the context.Background()
//      function serves as a viable alternative.
//      Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
import (
	"context"
)

managementKey = "xxxx"

// DescopeBaseURL // within the client.Config, you can also configure the baseUrl ex: https://auth.company.com  - this is useful when you utilize a custom domain within your Descope project.
descopeClient, err := client.NewWithConfig(&client.Config{ProjectID:"__ProjectID__", managementKey:managementKey})
if err != nil {
    // handle the error
    log.Println("failed to initialize: " + err.Error())
}
import com.descope.client;

// Initialized after setting the DESCOPE_PROJECT_ID env var (and optionally DESCOPE_MANAGEMENT_KEY)
var descopeClient = new DescopeClient();

// ** Or directly **
var descopeClient = new DescopeClient(Config.builder()
        .projectId("__ProjectID__")
        .managementKey("management-key")
        .build());
require 'descope'

descope_client = Descope::Client.new(
  {
    project_id: '__ProjectID__',
    management_key: 'management_key'
  }
)

Impersonate User

Note

You can also use our /impersonation API to impersonate a user.

This operation allows administrators to impersonate an existing user. The impersonator user must have the impersonation permission in order for this request to work. On success, the response will be a refresh JWT of the impersonated user.

// Args:
//   impersonatorId (str): The login_id of the user that's doing the impersonating.
//   loginId (str): The login_id of the user that's to be impersonated.
//   validateConsent (boolean): Whether to check if the user to be impersonated has given consent
//   customClaims (object): Optional, custom claims to be added to the impersonated user's JWT
//   tenantId (str): Optional, one of the tenants the impersonated user belongs to
const impersonatorId = "admin@company.com"
const loginId = "user@company.com"
const validateConsent = true
const customClaims = {"key1": "value1"}
const tenantId = "your-tenant-id"

const resp = await descopeClient.management.jwt.impersonate(
  impersonatorId,
  loginId,
  validateConsent,
  customClaims,
  tenantId
);
if (!resp.ok) {
  console.log("Failed to impersonate user")
  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 impersonated user")
  console.log(resp.data)
}
# Args:
#   impersonator_id (str): The login_id of the user that's doing the impersonating.
#   login_id (str): The login_id of the user that's to be impersonated.
#   validate_consent (boolean): Whether to check if the user to be impersonated has given consent
#   custom_claims (dict): Optional, custom claims to be added to the impersonated user's JWT
#   tenant_id (str): Optional, one of the tenants the impersonated user belongs to
impersonator_id = "admin@company.com"
login_id = "user@company.com"
validate_consent = True
custom_claims = {"key1": "value1"}
tenant_id = "your-tenant-id"

try:
  refresh_jwt = descope_client.mgmt.jwt.impersonate(
    impersonator_id=impersonator_id,
    login_id=login_id,
    validate_consent=validate_consent,
    custom_claims=custom_claims,
    tenant_id=tenant_id
  )
  print("Successfully impersonated user.")
  print(refresh_jwt)
except AuthException as error:
  print("Unable to impersonate user.")
  print("Status Code: " + str(error.status_code))
  print("Error: " + str(error.error_message))
// Args:
//   ctx: context.Context - Application context for the transmission of context capabilities like
//        cancellation signals during the function call. In cases where context is absent, the context.Background()
//        function serves as a viable alternative.
//        Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
//   impersonatorID (str): The login_id of the user that's doing the impersonating.
impersonatorID := "admin@company.com"
//   loginID (str): The login_id of the user that's to be impersonated.
loginID := "user@company.com"
//   validateConsent (boolean): Whether to check if the user to be impersonated has given consent
validateConsent := true
//   customClaims (map[string]interface{}): Optional, custom claims to be added to the impersonated user's JWT
customClaims := map[string]interface{}{"key1": "value1"}
//   tenantID (str): Optional, one of the tenants the impersonated user belongs to
tenantID := "your-tenant-id"

refreshJWT, err := descopeClient.Management.JWT().Impersonate(ctx, impersonatorID, loginID, validateConsent, customClaims, tenantID)
if err != nil {
  fmt.Println("Unable to impersonate user.", err)
} else {
  fmt.Println("Successfully impersonated user.")
  fmt.Println(refreshJWT)
}
// Pending release
# Pending release

Stop User Impersonation

Note

You can also use our /stop-impersonation API to impersonate a user.

This feature enables users to seamlessly switch back to their original account during an impersonation session.

// Args:
//   jwt (string): The impersonation JWT to be stopped (required).
//   customClaims (object): Optional, custom claims to add to the new JWT
//   selectedTenant (string): Optional, the tenant ID to set on the DCT claim
//   refreshDuration (number): Optional, duration in seconds for which the new JWT will be valid
const jwt = "xxxxxxxxx"
const customClaims = {"role": "admin"}
const selectedTenant = "tenant-123"
const refreshDuration = 3600

const resp = await descopeClient.management.jwt.stopImpersonation(
  jwt,
  customClaims,
  selectedTenant,
  refreshDuration
);
if (!resp.ok) {
  console.log("Failed to stop impersonation")
  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 stopped impersonation. New JWT issued:")
  console.log(resp.data.jwt)
}
# Args:
#   jwt (str): The impersonation JWT you want to stop.
#   custom_claims (dict): Optional, custom claims to add to the new JWT
#   tenant_id (str): Optional, tenant ID to set on the DCT claim
#   refresh_duration (int): Optional, duration in seconds for which the new JWT will be valid
jwt = "xxxxxxxx"
custom_claims = {"role": "admin"}
tenant_id = "tenant_123"
refresh_duration = 3600

try:
  new_jwt = descope_client.mgmt.jwt.stop_impersonation(
    jwt=jwt,
    custom_claims=custom_claims,
    tenant_id=tenant_id,
    refresh_duration=refresh_duration
  )
  print("Successfully stopped impersonation. New JWT issued.")
  print("JWT:", new_jwt)
except AuthException as error:
  print("Failed to stop impersonation")
  print("Status Code:", error.status_code)
  print("Error:", error.error_message)
// Args:
//   ctx: context.Context - Application context for the transmission of context capabilities like
//        cancellation signals during the function call. In cases where context is absent, the context.Background()
//        function serves as a viable alternative.
//        Utilizing context within the Descope GO SDK is supported within versions 1.6.0 and higher.
ctx := context.Background()
//   jwt (string): The impersonation JWT that you want to stop.
jwt := "xxxxxxx"
//   customClaims (map[string]interface{}): Optional, custom claims to add to the new JWT (can be nil if not used)
customClaims := map[string]interface{}{"role": "admin"}
//   tenantID (string): Optional, tenant ID for DCT claim context
tenantID := "tenant-123"
//   refreshDuration (int): Optional, a custom refresh duration in seconds for the JWT, 0 will use project configuration
refreshDuration := 3600

resp, err := descopeClient.Management.JWT().StopImpersonation(
  ctx,
  jwt,
  customClaims,
  tenantID,
  refreshDuration
)
if err != nil {
  fmt.Println("Failed to stop impersonation:", err)
} else {
  fmt.Println("Successfully stopped impersonation. New JWT issued:")
  fmt.Println(resp.JWT)
}
// Pending release
# Pending release
Was this helpful?

On this page