Clerk logo

Clerk Docs

Ctrl + K
Go to clerkstage.dev
Check out a preview of our new docs.

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 token
curl -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 token
curl -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.

If you're using Clerk components, you can simply visit the sign in URL of your application and set the __clerk_ticket query parameter with the token.

If you're using ClerkJS, 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.

1
import { useAuth } from "@clerk/nextjs";
2
import { withServerSideAuth } from "@clerk/nextjs/ssr";
3
4
// SSR authentication context
5
export const getServerSideProps = withServerSideAuth(
6
async ({ req }) => {
7
// The request is augmented with an auth object.
8
// The actor object is available in there.
9
const { userId, actor } = req.auth;
10
return {
11
props: { userId, actor },
12
};
13
}
14
);
15
16
function Home({ userId, actor }) {
17
return (
18
<div>
19
Server side info:
20
<p>
21
{actor && <span>User {actor.sub} has </span>}
22
signed in as user {userId}
23
</p>
24
25
<ClientSideInfo />
26
</div>
27
)
28
}
29
30
function ClientSideInfo() {
31
// Client-side authentication context.
32
const { userId, actor } = useAuth();
33
return
34
<div>
35
Client side info:
36
<p>
37
{actor && <span>User {actor.sub} has </span>}
38
signed in as user {userId}
39
</p>
40
</div>
41
);
42
}
1
import { useAuth } from "@clerk/react";
2
3
function Home() {
4
const { userId, actor } = useAuth();
5
return (
6
<div>
7
{actor && <span>user {actor.sub} has </span>
8
logged in as user {userId}
9
</div>
10
);
11
}
1
const { session } = window.Clerk;
2
if (session.actor) {
3
const { actor, user } = session;
4
console.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.js
2
import { withAuth } from "@clerk/nextjs/api";
3
4
export default withAuth(async (req) => {
5
// The request object is augmented with the
6
// Clerk authentication context.
7
const { userId, actor } = req.auth;
8
// The response includes actor and user IDs.
9
return { data: { userId, actor } };
10
});
1
import express from "express";
2
import { ClerkExpressWithAuth } from "@clerk/clerk-sdk-node";
3
4
const app = express();
5
6
// Apply the Clerk express middleware
7
app.get(
8
"/protected-endpoint",
9
ClerkExpressWithAuth({
10
// ...options
11
}),
12
(req, res) => {
13
// The request object is augmented with the
14
// Clerk authentication context.
15
const { userId, actor } = req.auth;
16
res.json({ userId, actor });
17
}
18
);
19
20
app.listen(3000, () => {
21
console.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.

Was this helpful?

Clerk © 2023