Clerk user impersonation for customer support

How Clerk impersonation works, with an actor-token example: the act claim, session limits and revocation, plus what a support team still has to add.

Yes, Clerk supports user impersonation natively. A Clerk Dashboard user can “log in as” a customer from the Users page, and your backend can create actor tokens that sign a staff member in as a specific user, as Clerk’s impersonation docs (opens in a new tab) explain. You do not need another product just to open your application as a customer.

What Clerk gives you is the sign-in mechanism. A support team usually also needs to decide who may impersonate whom, what they may do once inside, and how access ends. This guide covers what Clerk provides, a worked actor-token example, the session limits worth knowing, and the parts your application has to own.

What Clerk gives you out of the box

Dashboard impersonation. On the Users page, open a user’s menu and choose “Impersonate user”. This is the quickest option for a small team that already has Dashboard access.

Actor tokens. Your server calls the Backend API’s actor token endpoint (opens in a new tab) (POST /v1/actor_tokens) with the target user_id and an actor object whose sub is the staff member’s user ID. Clerk returns a one-time sign-in URL. This lets you build impersonation into your own admin tool and decide who is allowed to request it.

Impersonation detection. An impersonated session token includes an act claim, according to Clerk’s session token docs (opens in a new tab). Its sub is the impersonator, while the top-level sub stays the customer. In code, read actor from useAuth() in React, or on the server from auth() in Next.js or the Auth object your backend SDK provides. Anything you put in the actor object ends up in the act claim. If you use a custom JWT template, add {{session.actor}} to expose it.

Two practical details:

  • Usage limits. Clerk’s pricing page (opens in a new tab) lists 5 impersonations per month on every plan, with unlimited impersonations in its Enhanced Administration add-on. Check current pricing if your team handles many tickets.
  • Opening the link signs out the current user. An actor token URL signs out any existing session in that browser before starting the impersonated one. Support staff who also use your app should use a separate browser profile.

Clerk impersonation example

Here is the request shape from Clerk’s documentation, with placeholder IDs. Your server sends it with your Clerk secret key, never from the browser:

curl -X POST https://api.clerk.com/v1/actor_tokens \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "user_customer123",
    "expires_in_seconds": 600,
    "actor": { "sub": "user_staff456" }
  }'

The response includes a url. Opening it signs user_staff456 in as user_customer123. Inside that session, the token’s top-level sub is the customer, and act.sub is the staff member (abridged):

{ "sub": "user_customer123", "act": { "sub": "user_staff456" } }

Before you build on it, decide who may trigger this request and for which customers. The Backend API acts on whatever user_id your server sends with a valid secret key, so that eligibility check is yours.

Three clocks: token, session and inactivity

Teams often assume the actor token’s expiry controls how long impersonation lasts. It does not.

SettingDefaultWhat it controls
expires_in_seconds on the actor token1 hourHow long the sign-in URL can be redeemed
session_max_duration_in_seconds30 minutesMaximum life of the impersonated session
Inactivity timeout10 minutesEnds an idle impersonated session

Clerk’s frontend SDKs keep an active session alive, but not past the maximum duration.

Ending access early is a separate step. You can revoke an actor token (opens in a new tab) at any time, but that only stops an unused token from signing in. Once the session exists, end it by revoking the Clerk session itself. If your support policy says “access ends when the ticket closes or an admin cancels it”, someone has to trigger that revocation.

When native Clerk is enough

Clerk’s built-in flow may be all you need if:

  • Only a few trusted people can impersonate, and Dashboard access is an acceptable gate.
  • You don’t need per-request approval, a recorded reason, or limits on which customers each agent may open.
  • Your backend already reads actor and blocks risky operations during impersonated sessions.
  • The 30-minute default, or a value you set per token, matches how long investigations take.
  • Your logs already record the impersonator alongside the customer.

Try cheaper options first, too. A denial log, a narrow internal support view or a synthetic staging account often answers the ticket without opening a real customer account.

What a support workflow adds

As more agents handle tickets, the questions shift from “can we sign in as the user?” to policy. This matrix separates what Clerk provides from what your team decides.

RequirementWhat Clerk providesWhat your team decides
Open the customer’s appDashboard impersonation or actor-token URLWho may start it, and from where
Tell staff and customer apartact claim and actor helperRecord both identities in your audit events
Know the active workspaceActive organization in the session token (o claim in v2 tokens)Check every request against the customer’s real membership
Limit session timeMax duration and inactivity timeoutMatch it to the approved investigation window
Restrict actionsNothing by defaultWhich operations are blocked during impersonation
Approve and record accessNot part of the native flowRequest, reason, approver and access history

For the broader ownership decision, see build vs buy user impersonation.

Keep staff, customer and organization separate

Record three things for every investigation: who is acting, whose account they are in, and which workspace the request concerns. Don’t collapse them into a single user ID.

Check whether the staff member may access that customer before you create the actor token. Once the session exists, keep the customer’s normal authorization on every request. A workspace selected in the browser is input to validate, not permission to cross a tenant boundary. Clerk deprecated version 1 session tokens (opens in a new tab), which carried org_id, org_role and org_slug, on April 14, 2025, so read organization context from the current token format or the SDK helpers.

If support should only reach customers assigned to them, that check belongs in your token-issuing endpoint. The assigned-customer guide covers how to do it.

Enforce restrictions on the backend

The act claim identifies the impersonator. It does not stop them doing anything. Hiding an edit button won’t stop a direct API call, so the backend has to read actor and apply a policy.

For most inspection tickets, start read-only: allow reads and reject writes, credential changes, role changes, billing and bulk exports. Check routes whose method looks harmless but trigger side effects, such as a GET that sends an email. Read-only user impersonation walks through that inventory.

How Devora fits with Clerk

Devora is not a replacement for Clerk. It manages the support workflow around a Clerk impersonation: requests with a reason, approval by an approver or admin in your organization, read-only or read-and-write scope, a time limit, and access history. Clerk still creates the browser session, as Devora’s auth provider overview (opens in a new tab) explains.

The Devora Clerk guide (opens in a new tab) works like this:

  1. Your server creates the actor token and puts Devora’s verified context in the actor object, so it reaches the act claim.
  2. After Clerk middleware runs, your backend reads that context and passes it to Devora’s backend guard. The guard enforces scope, expiry and endpoint rules (opens in a new tab) on the routes you protect.
  3. When Devora ends access, your app signs out or revokes the Clerk session. To do this with no tab open, store a mapping from the Devora session ID to the Clerk session ID and revoke on Devora’s signed termination notice (opens in a new tab).

You still own the token-issuing endpoint, the claim-shape check for your JWT template, tenant authorization and revocation. Set session_max_duration_in_seconds no longer than the approved window, so the Clerk session can’t outlive the approval.

Test one support session in staging

Use synthetic accounts and record your Clerk SDK versions. These are the results to look for, not results we have already run:

ScenarioPass conditionEvidence
Approved read-only inspectionactor and userId differ; only the intended workspace loadsSanitized claims plus one API response
Direct write during read-only accessBackend rejects it; data unchangedAPI response and before/after state
Substituted user or organization IDRequest deniedDenial for the substituted target
Session hits its time limitNext API request failsTimestamped request, not just a banner
Admin ends access with the tab closedClerk session revoked; next request rejectedTermination notice and rejected request

The Devora testing guide (opens in a new tab) lists the full set of checks. If Clerk alone covers your requirements, keep it. If you need approvals, scoped access and access history on top, create a Devora account and run one staging investigation with the matrix above.

Sources

Quick answers

Common questions, answered clearly.

Direct answers to the questions teams usually ask when evaluating this approach.

Does Clerk support user impersonation?

Yes. You can impersonate a user from the Users page in the Clerk Dashboard, or create an actor token through the Backend API and use its one-time sign-in URL. The resulting session carries an act claim identifying the impersonator. Clerk's pricing page lists 5 impersonations per month on every plan, with unlimited impersonations in a paid add-on.

How do I detect an impersonated session in Clerk?

Read actor from useAuth() in the frontend, or on the server from auth() in Next.js or the Auth object your backend SDK provides. It contains the impersonator's ID (act.sub), while userId remains the impersonated customer. If you use a custom JWT template, add {{session.actor}} as a claim.

Does actor-token expiry end an impersonation session?

No. expires_in_seconds (default one hour) only limits how long the token can be used to sign in. The session it creates is limited separately by session_max_duration_in_seconds (default 30 minutes) and a 10-minute inactivity timeout. Revoking the actor token stops an unused token; to end an active session, revoke the Clerk session.

Is a Clerk actor token enough for read-only support?

No. The act claim tells your backend who is impersonating, but it does not block anything. Your backend has to read it and reject writes and sensitive operations while keeping the customer's normal tenant and permission checks.

Which parts of the support workflow does Devora add?

Devora handles access requests, approvals, read or write scope, time limits and access history, and passes that context to your backend. Clerk still creates the browser session. Your application reads the context, enforces it on the backend and revokes the Clerk session when Devora ends access.

Put it into practice

Give your team context.Keep control of access.

Bring approvals, scoped sessions, and access history into your support workflow.