X Enterprises
fastify-xadmin

Impersonation Routes

Admin impersonation sessions — POST /api/admin/impersonation/start, POST /stop, and GET /status, using a session token passed via the x-impersonation-token header.

Impersonation Routes

Allow admins to temporarily act as another user for support and debugging. Starting a session returns an opaque session token (64-char hex, not a JWT) valid for 1 hour; subsequent status/stop calls identify the session via the x-impersonation-token header. All three routes require the impersonation:use permission.

Routes

MethodPathPermissionDescription
POST/api/admin/impersonation/startimpersonation:useStart impersonating a user
POST/api/admin/impersonation/stopimpersonation:useStop impersonating
GET/api/admin/impersonation/statusimpersonation:useCurrent session status

Sessions are persisted in the ImpersonationSession Prisma model; without that model the routes degrade gracefully (start returns an in-memory session, stop/status become no-ops).


POST /api/admin/impersonation/start

Start an impersonation session for a target user.

Body Fields

FieldTypeRequiredDescription
userIdstringYesID of the user to impersonate.

Response

{
  "success": true,
  "data": {
    "sessionId": "imp_9f2c...",
    "impersonatedUser": { "id": "usr_123", "name": "Alice", "email": "alice@example.com", "role": "user" },
    "originalAdmin": { "id": "usr_admin", "name": "Admin", "email": "admin@example.com" },
    "startedAt": "2026-07-27T12:00:00.000Z",
    "expiresAt": "2026-07-27T13:00:00.000Z",
    "token": "a1b2c3..."
  }
}

Errors

  • 401 — no authenticated admin on the request (request.user.id missing).
  • 403 — the target user has role admin or super_admin (privilege-escalation guard).
  • 404 — target user not found.

POST /api/admin/impersonation/stop

End a session. The token is read from the x-impersonation-token header first, falling back to a sessionToken body field.

Body Fields

FieldTypeRequiredDescription
sessionTokenstringNoSession token (alternative to the header).

Errors

  • 400 — no token provided in header or body.
  • 404 — session not found.

The response reports sessionId, duration (seconds), actionsPerformed, and endedAt.


GET /api/admin/impersonation/status

Report the status of the session identified by the x-impersonation-token header. Returns { "isImpersonating": false } when the header is absent, the session is unknown, ended, or expired. Active sessions include sessionId, impersonatedUser, originalAdmin, startedAt, expiresAt, and timeRemaining (seconds).

Example — Full impersonation workflow

// 1. Start impersonation
const { data } = await fetch("/api/admin/impersonation/start", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${adminToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ userId: targetUserId }),
}).then((r) => r.json());

// 2. Check session status
const status = await fetch("/api/admin/impersonation/status", {
  headers: {
    Authorization: `Bearer ${adminToken}`,
    "x-impersonation-token": data.token,
  },
}).then((r) => r.json());

// 3. End the session when done
await fetch("/api/admin/impersonation/stop", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${adminToken}`,
    "x-impersonation-token": data.token,
  },
});

Start and stop events are recorded in the Audit Log.

AI Context

package: "@xenterprises/fastify-xadmin"
routes:
  - POST /api/admin/impersonation/start — body: userId (required); returns 1h session token; 401 no admin, 403 admin target, 404 unknown user
  - POST /api/admin/impersonation/stop — token via x-impersonation-token header or sessionToken body; 400 no token, 404 unknown session
  - GET /api/admin/impersonation/status — reads x-impersonation-token header; { isImpersonating, ... }
permission: impersonation:use on all three
security: admin/super_admin users cannot be impersonated; tokens are opaque (not JWT), 1h TTL, non-renewable
notes: ImpersonationSession model optional — routes degrade gracefully without it

See Also

Copyright © 2026