Yes, WorkOS supports user impersonation through AuthKit. According to the AuthKit impersonation docs (opens in a new tab), a member of your WorkOS team opens a user in the WorkOS Dashboard, gives a reason, and signs in to your application as that user. If your support team works from the Dashboard and that is enough, you don’t need another tool.
The native flow covers signing in and recording who did it and why. It doesn’t decide which customers each agent may open, require approval, limit what they can do once inside, or end access when a ticket closes. This guide covers what AuthKit provides, the settings that trip teams up, and what your application has to own.
How WorkOS impersonation works
- Enable it. Impersonation is off by default in every environment. Someone with the Admin role turns it on under Authentication → Features → User impersonation.
- Start it from the Dashboard. Open Users, select the user, and choose Impersonate User under Danger Zone. You must enter a reason. If the user belongs to more than one organization, you also pick which one to sign in to.
- Your app completes sign-in. The browser goes to your application, and your callback receives an authorization code for the impersonated user, as with any other AuthKit login.
- The session expires after 60 minutes.
You can also link straight to the impersonation dialog from your own admin tool: https://dashboard.workos.com/<environment_id>/users/<user_id>/details?dialog=impersonate. The person clicking it still needs Dashboard access.
Detecting impersonation in your app
WorkOS gives you two signals:
- The Authenticate with Code response includes an
impersonatorobject with the staff member’semailandreason. - The access token carries an
actclaim with the impersonator’s email, so every API request already says who is really acting.
{ "sub": "user_customer123", "sid": "session_abc", "act": { "sub": "agent@yourcompany.com" } }
Libraries expose it in different places. authkit-nextjs ships an Impersonation component that renders a visible frame with a button to stop. authkit-react includes impersonator in its auth state, per the authkit-react source code (opens in a new tab). authkit-js returns it on the authentication response (opens in a new tab), so read it from there when you set up your staff banner.
A banner is a courtesy, not a control. Reading the claim in the browser doesn’t stop anything. Your backend has to verify the access token and decide what an impersonated request may do.
Fix the callback error first
The most common WorkOS impersonation failure looks like a broken SDK. The Dashboard starts the flow, so an SDK that validates PKCE or OAuth state receives a response to a request it never made, and rejects it.
The fix is a setting: under Applications → your application → Redirects, set the Initiate login URI to your sign-in route, not your callback route. The impersonation redirect then lands on sign-in first, the SDK sets up PKCE and state, and the flow continues to your callback, as WorkOS’s impersonation docs (opens in a new tab) explain.
Limits to plan around
| Behavior | What it means for support |
|---|---|
| Starts from the WorkOS Dashboard | Whoever impersonates needs Dashboard access to that environment; a deep link doesn’t remove that |
Reason required, recorded on the session.created event | You get the who and why; you can listen for the event through the events API |
| 60-minute automatic expiry | Plan investigations to fit, or end them sooner yourself |
| Same access as the user | Nothing is read-only by default; you restrict sensitive views and actions |
| Organization chosen at start | Check every request against the user’s real membership in that organization |
To end a session early, revoke it with POST /user_management/sessions/revoke, passing the session ID from the access token’s sid claim, per the revoke session API reference (opens in a new tab). If your policy says access ends when the ticket closes, something has to make that call.
When native WorkOS is enough
AuthKit’s built-in flow may cover you if:
- Only a few trusted people have Dashboard access to production.
- A required reason on each session is enough of a record, and you don’t need an approval step before access starts.
- Your backend already reads
actand blocks risky operations during impersonated sessions. - Sixty minutes fits your investigations.
- You don’t need to limit which customers each agent may open.
Try lighter options first, too. A backend denial log or a narrow internal support view often answers the ticket without signing in as the customer.
What a support workflow adds
| Requirement | What WorkOS provides | What your team decides |
|---|---|---|
| Open the customer’s app | Dashboard impersonation and deep link | Who has Dashboard access |
| Tell staff and customer apart | act claim and impersonator response field | Record both identities in your audit events |
| Record why | Required reason on session.created | Whether a reason alone is enough, or approval is needed |
| Limit session time | 60-minute expiry; session revoke API | When to revoke early |
| Restrict actions | Nothing by default | Which operations are blocked during impersonation |
| Limit which customers | Not part of the native flow | Assignment and eligibility checks |
The read-only impersonation guide covers the backend restrictions, and impersonation audit logs covers recording actor and subject together.
How Devora fits with WorkOS
This is the important limit. WorkOS documents impersonation as a Dashboard flow. Its docs don’t describe an API that another product can call to create an AuthKit session for a user it chooses. So, as Devora’s WorkOS guide explains (opens in a new tab), a Devora approval can’t be turned directly into a standard AuthKit session, the way Clerk actor tokens allow.
What Devora documents instead, in its custom session guide (opens in a new tab), is an application-owned session bridge:
- After a Devora approval, your
IMPERSONATEhandler looks up the target WorkOS user and returns a short-lived, one-time handoff token. - Your app exchanges it once for its own HTTP-only support session. That session stores the target user ID and Devora’s verified context unchanged, and expires no later than the approval.
- Your backend passes that context to Devora’s guard, which enforces scope and expiry (opens in a new tab) on protected routes.
- When Devora ends access, your
TERMINATEhandler revokes the support sessions indexed by Devora’s session ID.
That only works if your application can create and trust its own sessions after WorkOS authentication. It is not an AuthKit session, and you should never build one by re-signing AuthKit tokens, reusing a customer’s refresh token or automating their login.
If your app relies entirely on AuthKit sessions, keep using the WorkOS Dashboard flow on its own. It won’t start from Devora’s approval workflow, and it shouldn’t be presented as a Devora-integrated session.
Test it in staging
Use synthetic users and record your AuthKit SDK version. These are pass conditions to check, not results we’ve already run:
| Scenario | Pass condition |
|---|---|
| Dashboard impersonation with an SDK that validates PKCE | Sign-in completes once the Initiate login URI is set |
| Impersonated request to your API | Backend sees act and the customer sub as different identities |
| Write attempt during a session you treat as read-only | Backend rejects it; data unchanged |
| Organization substituted in the request | Denied |
| Session revoked through the API | Next protected request fails |
| Token refresh during an impersonated session | Staff banner still shows, and act is still present |
If AuthKit alone covers your requirements, keep it. If you need approvals, scoped access and access history, and your app can own a support session, read the Devora WorkOS guide (opens in a new tab), then create a Devora account to try one staging investigation. The build vs buy guide can help with the wider decision.
Sources
- WorkOS: Impersonation (AuthKit) (opens in a new tab)
- WorkOS authkit-react source: auth state (opens in a new tab)
- WorkOS authkit-js source: authentication response (opens in a new tab)
- WorkOS API reference: Revoke session (opens in a new tab)
- Devora: WorkOS AuthKit guide (opens in a new tab)
- Devora: Custom JWT or cookie session (opens in a new tab)
- Devora: Scope and security (opens in a new tab)