Impersonate
Sign in as another user to see exactly what they see — then return to your own account in one click.
grit plugin add impersonate
Requires the roles system (Grit v3.66.0+) and an admin app, so it runs on the triple and full architectures.
The problem it solves
A user reports a bug or a permissions issue, and reproducing it means asking them for screenshots or guessing at what their account can and can't see. Impersonation removes the guesswork: an admin signs in as that user and sees the app exactly as they do — same data, same role, same UI.
How it works
The session swap is entirely server-side, because web auth lives in HttpOnly cookies the browser's JavaScript can't read. The admin never handles a raw token.
Starting impersonation calls an admin-only endpoint. The handler re-issues the auth cookies (grit_access / grit_refresh) for the target user, and stashes the admin's own token in a separate HttpOnly cookie named grit_impersonator so it can be restored later:
POST /api/admin/impersonate/:id admin-only; start impersonating :idPOST /api/auth/impersonate/stop protected; return to your own account
A second, non-HttpOnly cookie named grit_impersonating carries only the display name and email (never a token), so the admin UI can render a persistent banner. HttpOnly cookies are invisible to JS, so without this the browser couldn't tell it was impersonating at all.
Notice where stop lives: on the protected route group, not the admin group. The caller is currently the impersonated user, who may not be an admin — they must still be able to return. It reads and validates grit_impersonator, re-issues the admin's auth cookies, and clears the impersonation cookies.
Both start and stop write an activity-log entry — user.impersonate.start at severity warn and user.impersonate.stop at info — so every session shows up under System → User Activity.
grit_impersonator lasts one hour. After that the admin simply re-authenticates — there is no long-lived escape hatch back to elevated access.
Install
What the plugin ships:
- A persistent amber banner in the dashboard layout with a Return to your account button.
- An Impersonate screen under System, gated with
usePermissionson theusers.editpermission, listing users with an Impersonate button each. - A
use-impersonatehook that drives the start/stop calls.
grit plugin add impersonate
Using it
Open the admin, go to System → Impersonate, and click Impersonate next to a user. The whole app reloads as that user and a banner appears at the top:
System → Impersonate → [Impersonate] next to a user→ app reloads as that user, amber banner at the top→ "Return to your account" in the banner switches you back
Because every route is still enforced server-side, you get exactly the target user's real permissions while impersonating — no more — and one click on the banner restores your own session.
Impersonation grants the target user's permissions, not the admin's. The screen itself is gated on users.edit, and every impersonation is audit-logged — so the feature never widens what anyone can reach.
Use cases
- Reproduce a user-reported bug exactly as they see it, with their data and their role.
- Verify a role or permission change grants or restricts the right things — log in as an affected user and check.
- Support and debugging a specific account without asking for screenshots or credentials.
- QA of per-role UI — confirm each role sees the screens and controls it should.
