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.
| Setting | Default | What it controls |
|---|---|---|
expires_in_seconds on the actor token | 1 hour | How long the sign-in URL can be redeemed |
session_max_duration_in_seconds | 30 minutes | Maximum life of the impersonated session |
| Inactivity timeout | 10 minutes | Ends 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
actorand 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.
| Requirement | What Clerk provides | What your team decides |
|---|---|---|
| Open the customer’s app | Dashboard impersonation or actor-token URL | Who may start it, and from where |
| Tell staff and customer apart | act claim and actor helper | Record both identities in your audit events |
| Know the active workspace | Active organization in the session token (o claim in v2 tokens) | Check every request against the customer’s real membership |
| Limit session time | Max duration and inactivity timeout | Match it to the approved investigation window |
| Restrict actions | Nothing by default | Which operations are blocked during impersonation |
| Approve and record access | Not part of the native flow | Request, 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:
- Your server creates the actor token and puts Devora’s verified context in the actor object, so it reaches the
actclaim. - 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.
- 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:
| Scenario | Pass condition | Evidence |
|---|---|---|
| Approved read-only inspection | actor and userId differ; only the intended workspace loads | Sanitized claims plus one API response |
| Direct write during read-only access | Backend rejects it; data unchanged | API response and before/after state |
| Substituted user or organization ID | Request denied | Denial for the substituted target |
| Session hits its time limit | Next API request fails | Timestamped request, not just a banner |
| Admin ends access with the tab closed | Clerk session revoked; next request rejected | Termination 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
- Clerk: User impersonation (opens in a new tab)
- Clerk Backend API: Create actor token (opens in a new tab)
- Clerk: Session tokens (opens in a new tab)
- Clerk pricing (opens in a new tab)
- Devora: Auth providers (opens in a new tab)
- Devora: Clerk guide (opens in a new tab)
- Devora: Scope and security (opens in a new tab)
- Devora: Session lifecycle (opens in a new tab)
- Devora: Testing guide (opens in a new tab)