Ghost & view-as

Impersonate is a permission, never a role. Sessions are read-first, banner-flagged, time-boxed and fully audited — and the banner + acting-as state derive from the SERVER session, never client state: when the session ends, acting-as ends, fail-closed (ledger #239 P1: the live banner outlived the server session and actions then hit the admin’s OWN account — this concept renders the fix: server-derived state, hard expiry, no action without a live grant). The discipline live Folo support already runs (“ghost sessions in the inbox are read-first, banner-flagged, time-boxed and fully audited”), made a first-class surface.
Demo dataPattern from live FG + Folo

Start a session

Pick who, then how deep. The entity type scopes the search — a fan, a creator, an agency and a chatter are different records with different blast radii.

👁 View as Read-only

See exactly what they see. Nothing can be sent, bought, changed or deleted — the session cannot write, so it needs no reason and no expiry ceremony. Still logged.

⚠ Act as Impersonate

Full control of the account. Requires the Impersonate/act-as permission, a written reason, and an auto-expiry — the session ends itself.

15m1h4h
Opens in a new window with the banner below pinned.
Low-stakes variant (investors-dibi reference): for harmless previews — “view as investor” there — plain one-click links per named test account beat a modal flow. We keep that shape for sandbox/test personas only; anything touching a real person’s account goes through this picker.

The in-session banner Live demo

Pinned to the top of every page for the whole session — you can never forget whose eyes you’re borrowing.
You are acting as @delisha · read-only · 42:17 remaining · every action audited
Countdown is real in-app; expiry force-ends the session and writes ghost.expire. The demo above ticks for illustration only.

Session log Demo data

Audited history — opens, closes, and every action taken while inside.
WhenEventAdminTargetPlatformDetail
Today 13:12ghost.openSimon O.@delisharead-only · 1h box
Today 11:48ghost.actionDana R.Marta V. (fan)act-as · resent a stuck receipt email · reason: “support #4187”
Today 11:31ghost.openDana R.Marta V. (fan)act-as · 15m box · reason: “support #4187”
Today 11:46ghost.closeDana R.Marta V. (fan)ended by admin, 1m before expiry
2026-08-08ghost.expireKavi N.Northlight Agencyread-only · hit the 4h box, force-ended
2026-08-08ghost.deniedOwen P.@missariaact-as refused — lacks the Impersonate permission

Active sessions 2 open

👁
Simon O. → @delisharead-only · started 13:12 · 42m left
Mara T. → Velvet Studioact-as · started 12:50 · 3h 08m left
Any super-admin can end any session; the target’s record shows an open-session flag while one runs.

What ghost can never do

Hard limits, sourced from live FG behaviour — not preferences.
Move money. No payout approval, no purchase, no refund from inside a session — finance actions bounce to the Finance admin under the admin’s own identity.
Read credentials. Passwords, tokens and payment details are never rendered — the live services page states “no endpoints/tokens ever read” and ghost inherits that rule.
Outlive its box. Auto-expiry is mandatory on act-as; there is no “until further notice” session.
Run silent. The banner cannot be dismissed, and open/close/action/expiry all write to the audit log with the admin’s identity.
Be a role. Impersonate is granted per person as a permission chip in Roles & access — no role ships with it by default.