User Impersonation
Learn how to sign in as another user and detect impersonated sessions.
Overview
User Impersonation allows you to sign in as a different user in your application. It allows administrators to access and operate on an instance as if they were logged in as a different user of that instance.
User Impersonation allows one user (Alice) to interact with your application as another (Bob). For the duration of an impersonated session, the application considers Alice to be Bob. Alice is given all the rights that Bob has, and is indistinguishable from Bob in that context.
User Impersonation can be useful for testing or debugging purposes. It is a powerful feature during troubleshooting or investigation processes carried out by customer support teams.
However, please consider when and how you use User Impersonation. It is advised to seek the impersonated user's consent and respect your users' privacy.
How it works
Clerk allows developers or admins of an application to sign in as different users. The feature involves two parts:
1. Get an actor token that can be used to sign in as a different user.
2. Detect an impersonated session as soon as you're signed in.
Actor tokens
Actor tokens are similar to sign in tokens. They can be used for one-time logins, but they result in impersonated sessions. You can obtain an actor token from our Backend API.
Actor tokens need to declare the impersonator user (actor) and the impersonated user (subject). When Alice decides to impersonate Bob, she will issue an actor token. Alice is the actor and Bob is the subject of the Impersonation.
You can also configure the validity duration of an actor token by setting an expiration time, but you can revoke it at any time.
Creating actor tokens
API request to create an actor tokencurl -X POST https://api.clerk.dev/v1/actor_tokens -d '{ \"user_id": "user_1o4qfak5AdI2qlXSXENGL05iei6", \"expires_in_seconds": 600 \"actor": { \"sub": "user_21Ufcy98STcA11s3QckIwtwHIES", \} \}'
The above request will create an actor token that is valid for 600 seconds (10 minutes). Using the generated token will result in user with ID "user_21Ufcy98STcA11s3QckIwtwHIES" (the actor) signing in as user with ID "user_1o4qfak5AdI2qlXSXENGL05iei6" (the subject).
When creating actor tokens, the object that you pass as the "actor" parameter will end up in the authentication token's "act" claim. You can read more details in the JWT claims section of this document.
Revoking actor tokens
Request to revoke an actor tokencurl -X POST https://api.clerk.dev/v1/actor_tokens/act_2EL6mQKzeUtoRwGuLZsznyfkIsH/revoke
The above request will revoke the actor token with ID "act_2EL6mQKzeUtoRwGuLZsznyfkIsH" even if it's not expired yet. Revoked actor tokens can no longer be used for signing in.
Signing in with an actor token
Actor tokens are consumed the same way as sign in tokens.
Actor tokens can be created from the Backend API. Once you've successfully created an actor token, you can use the "url" or "token" attributes of the response to consume the token and impersonate a user.
The goal is to visit the sign in page of your application and set the __clerk_ticket
query parameter with the token. You can do this manually and use the "token" attribute from the create actor token response.
Alternatively, you can use the "url" attribute from the the create actor token response.
The "url" attribute is a Clerk Frontend API URL that will use the token to sign out existing users and prepare the sign-in object for impersonation. You can directly visit the "url" provided in the response to consume the actor token.
The Clerk Frontend API will redirect you to the /sign-in page of your application, where you can continue the flow by consuming the __clerk_ticket
parameter.
If you're using ClerkJS directly and implementing a custom sign in flow, you should provide the token when creating a sign in attempt.
Detecting impersonated sessions
Once a user is signed in as a different user, Clerk provides APIs and helper methods to distinguish an impersonated session from a regular session. It also provides the whole actor object, which contains information about the impersonator user.
JWT claims
Following the standard actor claim of RFC 8693, the Clerk session token includes an act
claim with the ID of the impersonating user.
Example of a JWT for an impersonated session{"sub": "user_1o4qfak5AdI2qlXSXENGL05iei6","act": {"sub": "user_21Ufcy98STcA11s3QckIwtwHIES"}}
The above JSON snippet shows only two of the claims that the actual session JWT token contains. The `sub` claim is the impersonated user ("user_1o4qfak5AdI2qlXSXENGL05iei6"), while `act.sub` contains the ID of the impersonator ("user_21Ufcy98STcA11s3QckIwtwHIES").
Note that when using a custom JWT template, the {{session.actor}}
will need to be added as a claim in order to expose it.
Frontend
When working with frontend (client-side) code, you can easily detect impersonated sessions and gain access to the actor ID or other information from the "act" claim.
1import { useAuth } from "@clerk/nextjs";2import { withServerSideAuth } from "@clerk/nextjs/ssr";34// SSR authentication context5export const getServerSideProps = withServerSideAuth(6async ({ req }) => {7// The request is augmented with an auth object.8// The actor object is available in there.9const { userId, actor } = req.auth;10return {11props: { userId, actor },12};13}14);1516function Home({ userId, actor }) {17return (18<div>19Server side info:20<p>21{actor && <span>User {actor.sub} has </span>}22signed in as user {userId}23</p>2425<ClientSideInfo />26</div>27)28}2930function ClientSideInfo() {31// Client-side authentication context.32const { userId, actor } = useAuth();33return34<div>35Client side info:36<p>37{actor && <span>User {actor.sub} has </span>}38signed in as user {userId}39</p>40</div>41);42}
1import { useAuth } from "@clerk/react";23function Home() {4const { userId, actor } = useAuth();5return (6<div>7{actor && <span>user {actor.sub} has </span>8logged in as user {userId}9</div>10);11}
1const { session } = window.Clerk;2if (session.actor) {3const { actor, user } = session;4console.log(`User ${actor.sub} is signed in as user ${user.id}.`)5}
Backend
When working with backend code, Clerk provides middleware that can be used in Next.js API routes or directly in express-like Node.js applications. The middleware will provide information about impersonated sessions and the actor ID.
1// pages/api/some-handler.js2import { withAuth } from "@clerk/nextjs/api";34export default withAuth(async (req) => {5// The request object is augmented with the6// Clerk authentication context.7const { userId, actor } = req.auth;8// The response includes actor and user IDs.9return { data: { userId, actor } };10});
1import express from "express";2import { ClerkExpressWithAuth } from "@clerk/clerk-sdk-node";34const app = express();56// Apply the Clerk express middleware7app.get(8"/protected-endpoint",9ClerkExpressWithAuth({10// ...options11}),12(req, res) => {13// The request object is augmented with the14// Clerk authentication context.15const { userId, actor } = req.auth;16res.json({ userId, actor });17}18);1920app.listen(3000, () => {21console.log("Booted.")22});
Impersonate a user from the dashboard
If you prefer, you can impersonate a user right from the Clerk dashboard from the Users menu.