Sudo Mode
Luminary admins can view the app exactly as any other team member โ using their permissions, their role, their session.
Sudo Mode (Admin Impersonation)
Luminary admins can view the app as another team member โ using that member's role and a session token issued for their identity.
How to sudo
Lumen โ Users โ open the row menu (โขโขโข) for a user and choose View as <name>. There is no separate "Sudo" button โ impersonation is started entirely from this per-user row-menu item.
The action is only shown to Luminaries, and only for active, non-disabled users who aren't yourself.
There is no confirmation dialog in the current code โ clicking the item starts the session immediately and redirects you into the app as that user.
What changes
The backend issues a short-lived JWT carrying the target user's id and role (plus sudo: true and sudo_by: <your id>). The frontend stores it in sessionStorage (as celiq_sudo_token, alongside the saved original auth) and reloads the app as that user.
The sudo banner
A red sticky bar appears at the top of the app. Code renders:
๐ Viewing as <name or email> (<role>) โ this is what they see ยท Exit sudo
The banner is position: sticky at the top with a high z-index, so it stays on screen as you scroll.
Exiting sudo
Click Exit sudo in the red banner. The component calls POST /api/sudo/end (best-effort), restores the original auth from sessionStorage, clears the sudo keys, and redirects to /lumen. No logout required.
Limits
| Constraint | Status in code |
|---|---|
| Requester must be a Luminary | Enforced (startSudo rejects non-luminary with 403) |
| Cannot sudo yourself | Enforced (400 if requesterId === targetUserId) |
| Target must be an active workspace member | Enforced (404 otherwise) |
| Session token expires automatically | 30 minutes (SUDO_TTL_SECONDS = 30 * 60) |
| Cannot impersonate a higher role | Enforced server-side (startSudo rejects a target whose role ranks above the requester; same-or-lower, including LuminaryโLuminary, is allowed) |
| Sudo sessions logged | Recorded server-side in sudo_sessions (best-effort โ the audit row is skipped silently if the table is missing). There is no in-app view of these records. |
Use cases
Support debugging โ reproduce what a user is seeing without asking them to screenshare. Role testing โ verify what a Tracer can and cannot see after a permission change. Onboarding โ walk through the app as a new team member would experience it.Session logging
Sudo sessions are logged on the server only โ there is no in-app "Audit Log" view to browse them.
On start, startSudo attempts to insert one row into the sudo_sessions table (columns requester_id, target_user_id, workspace_id, token_issued_at, expires_at). On exit, endSudo attempts to set ended_at on the most recent open row for that requester/target/workspace. Both writes are best-effort โ wrapped in try/catch so they never fail the request, and skipped silently if the table does not exist.