> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://help.sigmacomputing.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://help.sigmacomputing.com/_mcp/server.

# Impersonate users

> Sigma admins can impersonate users in the UI or API to assume their permissions for troubleshooting, security, and document management.

This document describes how users assigned the Admin account type can assume the permissions and access of another user in their organization to assist with troubleshooting, maintain data security, and better manage documents.

## Requirements

If you use OAuth to authenticate to your organization, you cannot impersonate users in the UI.

To impersonate another user, you must be assigned the **Admin** [account type](/docs/create-and-manage-account-types). Users who are only *team* admins cannot impersonate other users.

## Overview

Impersonating users allows admins to act as a user and view, edit, and access Sigma resources based on the [user's account type](/docs/account-type-and-license-overview).

An admin can impersonate a user in the UI or when using the API:

* [Impersonate a user in the UI](#impersonate-a-user), for example, to identify and troubleshoot issues that a user experiences from their perspective, or validate row-level security (RLS) and column-level security (CLS).
* [Impersonate a user in the API](#impersonate-users-for-api-calls), for example, to verify which documents a user can access and the corresponding access levels, retrieve a list of files in a user's **Documents** folder, or make changes on behalf of a user in embedded content.

When you impersonate a user, an event is created in [audit logs](/docs/access-and-explore-audit-logs) that identifies the user and the impersonating user.

## Impersonate a user

Follow the steps below to impersonate a user in your organization. You can impersonate a user on the **Users** or **Teams** tabs.

Users assigned the Admin account type can only impersonate non-admin users. Admins cannot impersonate other admins.

For Snowflake and PostgreSQL connections, the impersonation also applies to the role and warehouse attribute used on your connection.

### Impersonate a user from the Users tab

1. Go to **Administration** > **Users**:

   1. In the Sigma header, click your user avatar to open the user menu.

   2. Select **Administration** to open the **Administration** portal.

   3. In the side panel, select **Users**.
2. Select a user to impersonate.
3. On the user profile, click **Impersonate user**.
4. At the top of the Sigma UI, you see a banner that identifies the user that you are impersonating. During the impersonation session, you can view, edit, and access Sigma resources based on the [user's account type](/docs/account-type-and-license-overview).

   ![The yellow/orange banner appears at the top of the Sigma UI, above the header when viewing any page within Sigma. The banner indicates who you are impersonating and has a Stop impersonation button.](https://files.buildwithfern.com/sigma.docs.buildwithfern.com/ab87a2274b8dd4842cc10b7af7cc1687f82c3cf57c6e88431af95fef009d3d8b/assets/docs-images/f0418c7d9030ebe8310f376d1ace9cec1232a9875a55bd3f46ae29b3bd7201bc-impersonating.png)
5. To end the session, in the yellow banner, click **Stop impersonation**. You return to the user's profile logged in as yourself.

### Impersonate a user from the Teams tab

1. Go to **Administration** > **Teams**:

   1. In the Sigma header, click your user avatar to open the user menu.

   2. Select **Administration** to open the **Administration** portal.

   3. In the side panel, select **Teams**.
2. Select the team with the user that you want to impersonate.
3. Locate the user that you want to impersonate, then click the <img src="https://sigma-docs-screenshots.s3.us-west-2.amazonaws.com/Icons/more.svg" alt="" /> (**More**) menu and select **Impersonate user**.

   ![List of team members on the team tab, with the more menu open and showing the option to impersonate user. The email addresses of the team members are blurred for privacy reasons.](https://files.buildwithfern.com/sigma.docs.buildwithfern.com/8be5cf145226fb1f0ade198e7e9d065f6d9ff195363d3726c188298881026549/assets/docs-images/4069cf1595783ce2bcf1e9d0ee3809e0ebf05ddf08e9bcdd468acd73e741d17d-impersonate-team-member-list.png)
4. At the top of the UI, you see a yellow banner that confirms the identity of the user you are impersonating. During the impersonation session, you can view, edit, and access Sigma resources based on the [user's account type](/docs/account-type-and-license-overview).

## Impersonate users for API calls

This documentation describes one or more public beta features that are in development. Beta features are subject to quick, iterative changes; therefore the current user experience in the Sigma service can differ from the information provided in this page.

This page should not be considered official published documentation until Sigma removes this notice and the beta flag on the corresponding feature(s) in the Sigma service. For the full beta feature disclaimer, see [Beta features](/docs/sigma-product-releases#beta-features).

For most API endpoints, you can impersonate other users and retrieve information or perform actions on behalf of other users. As with all impersonation, you must be assigned the Admin account type.

To impersonate users for API calls, do the following:

1. [Generate client credentials](/reference/generate-client-credentials), if you do not already have them, to use for the Sigma REST API.

2. [Get an access token](/reference/post-token) with your client credentials to use in a future API call.

3. Generate a self-signed JWT token for each user that you want to impersonate:

   * To impersonate a user in your organization, provide the `sub` claim and specify the email address of the user that you want to impersonate.
   * To impersonate a user in a tenant organization as an admin in the parent organization, provide the `sub` claim and specify the email address of the user that you want to impersonate, and provide the `tenant` claim with the organization ID of the tenant organization.
   * To perform actions in the tenant organization as the `TenantAdminRobot`, provide the `tenant` claim with the organization ID of the tenant organization and do not provide a `sub` claim.

     If the tenant organization is in a different region than the parent organization, get the access token (step 2) and the impersonation token (step 4) using the base URL of the parent organization. Then, perform API calls as the impersonated user (step 5) using the base URL for the region and cloud provider in which the tenant is hosted. For details about which URL to use and how to identify the region, see [Supported cloud platforms and regions](/docs/region-warehouse-and-feature-support#supported-cloud-platforms-and-regions).

4. [Get an impersonation token](/reference/post-token):

   * Provide the access token to authenticate the request and as the `actor_token`.
   * Provide the self-signed JWT token as the `subject_token`.

5. Use the impersonation token included in the response as the bearer token to authenticate API requests that you perform as the impersonated user.

For an example script that performs all of these steps, refer to the [Example Python script for impersonated API calls](#example-python-script-for-impersonated-api-calls).

### Limitations

The following API endpoints do not support an impersonation token. Requests made with an impersonation token to any of the following endpoints fail to return results:

* [Get connection path for a table](/reference/get-inode-connection-path) (`GET /v2/connections/paths/{inodeId}`)
* [Look up connections by path](/reference/lookup-connection) (`GET /v2/connection/{connectionId}/lookup`)
* [Export data from a workbook](/reference/export-workbook) (`POST /v2/workbooks/{workbookId}/export`)
* [Export a workbook](/reference/send-workbook) (`POST /v2/workbooks/{workbookId}/send`)
* [Export data from a report](/reference/export-report) (`POST /v2/reports/{reportId}/export`)
* [Export a report](/reference/send-report) (`POST /v2/reports/{reportId}/send`)
* [Add workbook schedule](/reference/post-workbook-schedule) (`POST /v2/workbooks/{workbookId}/schedules`)
* [Add report schedule](/reference/create-report-schedule) (`POST /v2/reports/{reportId}/schedules`)

### Example Python script for impersonated API calls

The following example Python script does the following:

* Get an access token and print it to the console.
* Generate a self-signed JWT token using the <a href="https://pypi.org/project/jwt/" target="_blank">jwt</a> library
* Generate an impersonation token using the access token and the self-signed JWT token.
* Get current user details with both the access token and the impersonation token.
* Get the list of workbook files accessible to the admin and impersonated user using the [List files](/reference/list-files) (`GET /v2/listfiles`) endpoint.

Do not use this script in any client-facing code. This example script prints sensitive details to the console, such as API access tokens, for testing and validation purposes.

Before running the script, update the code to provide the following details as environment variables or with another secure method:

* REST API client ID
* REST API client secret
* [Base URL for API calls](/docs/region-warehouse-and-feature-support#supported-cloud-platforms-and-regions). If you impersonate a tenant in a different region, use the base URL for the region the tenant is deployed in for performing tasks in the tenant.
* Email address of the user to impersonate, or the tenant organization ID, if performing tasks in a tenant organization as an admin.

```python
import requests
import jwt
import json

requests.packages.urllib3.disable_warnings()

# provide your client ID, client secret,
# and base URL for Sigma REST API calls
# as environment variables
client_id=""
client_secret=""
url = ""
# tenant_region_url = ""

# Get the admin access token to use as the actor token
def get_actor_token():
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    payload = {
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret
    }

    try:
        response = requests.post(f"{url}/v2/auth/token", headers=headers, data=payload, verify=False)
        response.raise_for_status()
        result = response.json()
        print(f"Generated actor token: {result}")
        return result["access_token"]
    
    except requests.exceptions.RequestException as e:
        print(f"Error getting actor token: {e}")
        if hasattr(e, 'response') and e.response is not None:
            print(f"Response status: {e.response.status_code}")
            print(f"Response body: {e.response.text}")
        raise

# Generate the self-signed JWT token
# Provide the email address of the user to impersonate
def generate_subject_token():
    jwt_payload = {
        # to impersonate a user, provide the sub claim
        "sub": "<email address of user to impersonate>",
        # to impersonate a user in a tenant organization, also provide the tenant claim
        # "tenant": "<organization ID of a tenant organization>",
        # to perform actions in a tenant organization as the TenantAdminRobot user, only provide the tenant claim
    }

    jwt_header = {
        "alg": "HS256",
        "kid": client_id,
        "typ": "JWT"
    }

    try:
        jwt_token = jwt.encode(
            jwt_payload,
            client_secret,
            algorithm="HS256",
            headers=jwt_header
        )
        print(f"Generated subject token: {jwt_token[:50]}...")
        return jwt_token
    except Exception as e:
        print(f"Error generating subject token: {e}")
        raise

def exchange_token(subject_token, actor_token):

    # Get impersonation token
    try:
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json",
            "User-Agent": "Python-OAuth-Client/1.0",
            "Authorization": f"Bearer {actor_token}"
        }

        payload = {
            "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
            "subject_token": subject_token,
            "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
            "actor_token": actor_token,
            "actor_token_type": "urn:ietf:params:oauth:token-type:access_token",
        }

        print(f"Token exchange payload: {json.dumps({k: v[:50] + '...' if len(str(v)) > 50 else v for k, v in payload.items()}, indent=2)}")

        response = requests.post(
            f"{url}/v2/auth/token",
            headers=headers,
            data=payload,
            verify=False,
            timeout=30
        )

        print(f"Token exchange response status: {response.status_code}")
        print(f"Token exchange response headers: {dict(response.headers)}")
        print(f"Token exchange response body: {response.text}")

        response.raise_for_status()
        return response.json()

    except requests.exceptions.RequestException as e:
        print(f"Error during token exchange: {e}")
        if hasattr(e, 'response') and e.response is not None:
            print(f"Response status: {e.response.status_code}")
            print(f"Response body: {e.response.text}")
        raise
    except Exception as e:
        print(f"Unexpected error during token exchange: {e}")
        raise

# Retrieve the ID of the impersonated user
def get_current_user(token):
    headers = {
        "Authorization": f"Bearer {token}"
    }

    try:
        response = requests.get(
            f"{url}/v2/whoami",
            headers=headers,
            verify=False,
            timeout=30
        )

        print(f"Whoami response status: {response.status_code}")

        response.raise_for_status()
        return response.json()

    except requests.exceptions.RequestException as e:
        print(f"Error retrieving current user: {e}")
        if hasattr(e, 'response') and e.response is not None:
            print(f"Response status: {e.response.status_code}")
            print(f"Response body: {e.response.text}")
        raise
    except Exception as e:
        print(f"Unexpected error retrieving current user: {e}")
        raise

# List workbook files accessible by current user
def list_files_for_user(token):
    headers = {
        "Authorization": f"Bearer {token}"
    }

    try:
        response = requests.get(
            f"{url}/v2/files?typeFilters=workbook",
            # for tenant impersonation for tenants in other regions, instead use:
            # f"{tenant_region_url}/v2/files?typeFilters=workbook",
            headers=headers,
            verify=False,
            timeout=30
        )

        print(f"List workbook files response status: {response.status_code}")

        response.raise_for_status()
        return response.json()

    except requests.exceptions.RequestException as e:
        print(f"Error listing workbook files for the current user: {e}")
        if hasattr(e, 'response') and e.response is not None:
            print(f"Response status: {e.response.status_code}")
            print(f"Response body: {e.response.text}")
        raise
    except Exception as e:
        print(f"Unexpected error listing workbook files for the current user: {e}")
        raise

# Run all defined functions as a test
def main():
    print("=== OAuth Token Exchange Test ===")

    try:
        print("\n1. Generating subject token...")
        subject_token = generate_subject_token()
        print(f"Subject token: {subject_token[:100]}...")

        print("\n2. Getting actor token...")
        actor_token = get_actor_token()
        print(f"Actor token: {actor_token[:100]}...")

        print("\n3. Exchanging tokens to impersonate user...")
        result = exchange_token(subject_token, actor_token)
        print(f"Token impersonation result: {json.dumps(result, indent=2)}")

        print("\n4. Get current user with actor token...")
        whoami_a = get_current_user(actor_token)
        print(f"Current user: {whoami_a}")

        print("\n5. Get current user with impersonation token...")
        whoami_b = get_current_user(result["access_token"])
        print(f"Current user: {whoami_b}")

        print("\n6. Listing workbook files for user with actor token...")
        workbooks = list_files_for_user(actor_token)
        print(f"Workbooks accessible by current user: {workbooks}")

        print("\n7. Listing workbook files for user with impersonation token...")
        workbooks = list_files_for_user(result["access_token"])
        print(f"Workbooks accessible by current user: {workbooks}")

    except Exception as e:
        print(f"Script failed with error: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()
```

## Related resources

* [Create and manage teams](/docs/manage-teams)