> ## Documentation Index
> Fetch the complete documentation index at: https://docs.braintrust.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Impersonation permissions for service tokens

> Fix 403 impersonation errors with service tokens by verifying Owner grants and using a project-level grant alternative.

> [!NOTE]
>
> **Applies to:**
>
> * Plan - Any
> * Deployment - Self-hosted
> *
> * Use case - Service creates projects/datasets in an environment-scoped org and needs to make a newly created project visible to a single user without requiring Owner grants across other orgs

plans="Any"
deployments="Self-hosted"
use\_case="Use case - Service creates projects/datasets in an environment-scoped org and needs to make a newly created project visible to a single user without requiring Owner grants across other orgs"
/>

## Summary

Impersonation can return `403 Insufficient privileges to impersonate user` when the caller lacks `Owner` on every organization the target user belongs to. This guide shows how to verify the user's org membership, add the required `Owner` grants, and an alternative flow that avoids impersonation.

## What is happening

Braintrust authorizes the calling identity against the impersonated user's full organization footprint. If the caller is not `Owner` on every org the user belongs to, impersonation fails with `403 Insufficient privileges to impersonate user`. The impersonated user must also have permission to perform the requested action, such as `POST /v1/project`.

## Fix or suggestion

### Option 1: grant Owner on every org the user belongs to

1. Identify the target user's organizations. Go to ** Settings** > [** Members**](https://www.braintrust.dev/app/~/configuration/members) and search for the user. Note every org the user appears in.
2. Have an existing organization owner add an `Owner` ACL entry for your calling identity (service account). Use `POST /v1/acl` to add the grant for each org the user belongs to.
3. Have an existing member of the [**Owners** permission group](https://docs.braintrust.dev/admin/access-control.md#built-in-permission-groups) add an `Owner` ACL entry for your calling identity (service account). Use `POST /v1/acl` to add the grant for each org the user belongs to.

Notes on step 2:

* The grant must be created by an existing member of the [**Owners** permission group](https://docs.braintrust.dev/admin/access-control.md#built-in-permission-groups) in the target org.
* Grant `Owner` for each organization the user is a member of, even if the API call targets only one org.

### Option 2: skip impersonation and grant project-level access (recommended for per-user visibility)

1. Have the service create the project and dataset using its service token by calling `POST /v1/project` and `POST /v1/dataset`, respectively.
2. Grant the user access to that project only. Add a project-level ACL via `POST /v1/acl` that gives the target user `read`, `create`, `update`, or `delete` permissions as needed.
3. Ensure no organization-wide role or group grants unintentionally give broader project visibility. Project-level grants are additive. Remove or restrict org-wide project read if you need the user to be the only non-admin with access.

Minimal example (conceptual):

* Create project: `POST /v1/project` authenticated with your service token.
* Grant project access: `POST /v1/acl` with this request body:

  ```json theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  {
    "object_type": "project",
    "object_id": "<project-id>",
    "user_id": "<user-id>",
    "permission": "read"
  }
  ```

## How to confirm it worked

* Retry the impersonated request. A successful impersonation returns `200` or the expected success code.
* For the project-level flow, verify the user can access the project in the UI or via an API call authenticated as that user.
* If the impersonation still fails, collect the request timestamp and request id from your service logs or the API response and open a support trace.

## Notes

* Impersonation works with service tokens (`user_type: service_account`).
* The caller must be `Owner` on every org the impersonated user belongs to.
* For self-hosted deployments, gather the request timestamp and request id before escalation so traces can be located quickly.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.