Plugin

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 :id
POST /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.

Impersonation is never silent

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.

The impersonator cookie expires

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 usePermissions on the users.edit permission, listing users with an Impersonate button each.
  • A use-impersonate hook 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.

No privilege escalation

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.