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
dotnet add package 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());
// appsettings.json

{
  "Descope": {
    "ProjectId": "your-project-id",
    "ManagementKey": "your-management-key"
  }
}

// Program.cs

using Descope;
using Microsoft.Extensions.Configuration;

// ... In your setup code
var config = new ConfigurationBuilder()
  .AddJsonFile("appsettings.json")
  .Build();

var descopeProjectId = config["Descope:ProjectId"];
var descopeManagementKey = config["Descope:ManagementKey"];

var descopeConfig = new DescopeConfig(projectId: descopeProjectId);
var descopeClient = new DescopeClient(descopeConfig)
{
    ManagementKey = descopeManagementKey,
};

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
//   refreshDuration (number): Optional, duration in seconds for which the new JWT will be valid
const impersonatorId = "admin@company.com"
const loginId = "user@company.com"
const validateConsent = true
const customClaims = {"key1": "value1"}
const tenantId = "your-tenant-id"
const refreshDuration = 3600

const resp = await descopeClient.management.jwt.impersonate(
  impersonatorId,
  loginId,
  validateConsent,
  customClaims,
  tenantId,
  refreshDuration
);
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
#   refresh_duration (int): Optional, duration in seconds for which the new JWT will be valid
impersonator_id = "admin@company.com"
login_id = "user@company.com"
validate_consent = True
custom_claims = {"key1": "value1"}
tenant_id = "your-tenant-id"
refresh_duration = 3600

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,
    refresh_duration=refresh_duration
  )
  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"
//   refreshDuration (int32): Optional, a custom refresh duration in seconds for the JWT
refreshDuration := int32(3600)

refreshJWT, err := descopeClient.Management.JWT().Impersonate(ctx, impersonatorID, loginID, validateConsent, customClaims, tenantID, refreshDuration)
if err != nil {
  fmt.Println("Unable to impersonate user.", err)
} else {
  fmt.Println("Successfully impersonated user.")
  fmt.Println(refreshJWT)
}
// Args:
//   impersonatorId (String): The login ID of the user that's doing the impersonating.
//   loginId (String): 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 (Map<String, Object>): Optional, custom claims to add to the impersonated user's JWT.
//   tenantId (String): Optional, one of the tenants the impersonated user belongs to.
JwtService jwts = descopeClient.getManagementServices().getJwtService();
try {
  String refreshJwt = jwts.impersonate(
      "admin@company.com",
      "user@company.com",
      true,
      new HashMap<String, Object>() {{
        put("key1", "value1");
      }},
      "your-tenant-id");
  System.out.println("Successfully impersonated user.");
  System.out.println(refreshJwt);
} catch (DescopeException de) {
  // Handle the error
}
// Args:
//   ImpersonatorId (string): The login ID of the user that's doing the impersonating.
//   LoginId (string): The login ID of the user that's to be impersonated.
//   ValidateConsent (bool?): Whether to check if the user to be impersonated has given consent.
//   CustomClaims (ImpersonateRequest_customClaims): Optional, custom claims to add to the impersonated user's JWT.
//   SelectedTenant (string): Optional, one of the tenants the impersonated user belongs to.
//   RefreshDuration (int?): Optional, duration in seconds for which the new JWT will be valid.
var customClaims = new ImpersonateRequest_customClaims();
customClaims.AdditionalData["key1"] = "value1";

var impersonateRequest = new ImpersonateRequest
{
    ImpersonatorId = "admin@company.com",
    LoginId = "user@company.com",
    ValidateConsent = true,
    CustomClaims = customClaims,
    SelectedTenant = "your-tenant-id",
    RefreshDuration = 3600,
};

var impersonateResponse = await descopeClient.Mgmt.V1.Impersonate.PostAsync(impersonateRequest);
Console.WriteLine("Successfully impersonated user.");
Console.WriteLine(impersonateResponse?.Jwt);

Impersonate User with Step-Up

Note

You can also use our /impersonate/stepup API to impersonate a user with step-up authentication.

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

# 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
#   refresh_duration (int): Optional, duration in seconds for which the new JWT will be valid
#   stepup (bool): Whether to generate a step-up token for the impersonated user
impersonator_id = "admin@company.com"
login_id = "user@company.com"
validate_consent = True
custom_claims = {"key1": "value1"}
tenant_id = "your-tenant-id"
refresh_duration = 3600

try:
  session_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,
    refresh_duration=refresh_duration,
    stepup=True
  )
  print("Successfully impersonated user with step-up.")
  print(session_jwt)
except AuthException as error:
  print("Unable to impersonate user with step-up.")
  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"
//   refreshDuration (int32): Optional, a custom refresh duration in seconds for the JWT
refreshDuration := int32(3600)

sessionJWT, err := descopeClient.Management.JWT().ImpersonateStepup(ctx, impersonatorID, loginID, validateConsent, customClaims, tenantID, refreshDuration)
if err != nil {
  fmt.Println("Unable to impersonate user with step-up.", err)
} else {
  fmt.Println("Successfully impersonated user with step-up.")
  fmt.Println(sessionJWT)
}
// Args:
//   impersonatorId (String): The login ID of the user that's doing the impersonating.
//   loginId (String): 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 (Map<String, Object>): Optional, custom claims to add to the impersonated user's JWT.
//   tenantId (String): Optional, one of the tenants the impersonated user belongs to.
JwtService jwts = descopeClient.getManagementServices().getJwtService();
try {
  String sessionJwt = jwts.impersonateStepup(
      "admin@company.com",
      "user@company.com",
      true,
      new HashMap<String, Object>() {{
        put("key1", "value1");
      }},
      "your-tenant-id");
  System.out.println("Successfully impersonated user with step-up.");
  System.out.println(sessionJwt);
} catch (DescopeException de) {
  // Handle the error
}

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 (int32): Optional, a custom refresh duration in seconds for the JWT
refreshDuration := int32(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)
}
// Args:
//   jwt (String): The impersonation JWT to be stopped (required).
//   customClaims (Map<String, Object>): Optional, custom claims to add to the new JWT.
//   tenantId (String): Optional, the tenant ID to set on the DCT claim.
JwtService jwts = descopeClient.getManagementServices().getJwtService();
try {
  String newJwt = jwts.stopImpersonation(
      "xxxxxxxxx",
      new HashMap<String, Object>() {{
        put("role", "admin");
      }},
      "tenant-123");
  System.out.println("Successfully stopped impersonation. New JWT issued.");
  System.out.println(newJwt);
} catch (DescopeException de) {
  // Handle the error
}
// Args:
//   Jwt (string): The impersonation JWT to be stopped (required).
//   CustomClaims (StopImpersonationRequest_customClaims): Optional, custom claims to add to the new JWT.
//   SelectedTenant (string): Optional, the tenant ID to set on the DCT claim.
//   RefreshDuration (int?): Optional, duration in seconds for which the new JWT will be valid.
var customClaims = new StopImpersonationRequest_customClaims();
customClaims.AdditionalData["role"] = "admin";

var stopImpersonationRequest = new StopImpersonationRequest
{
    Jwt = "xxxxxxxxx",
    CustomClaims = customClaims,
    SelectedTenant = "tenant-123",
    RefreshDuration = 3600,
};

var stopImpersonationResponse = await descopeClient.Mgmt.V1.Stop.Impersonation.PostAsync(stopImpersonationRequest);
Console.WriteLine("Successfully stopped impersonation. New JWT issued:");
Console.WriteLine(stopImpersonationResponse?.Jwt);
Was this helpful?

On this page