View as
Preview Pact as another role, persona, or user — a strictly read-only owner tool for verifying what a given audience sees, distinct from write-through impersonation.
View as
View as lets a tenant owner preview the product exactly as a given persona and role would see it — a UI-shape and data-slice preview for answering "what does a Sales Manager actually see?" It is strictly read-only. The HTTP surface is api/routes/admin_view_as.py; read-only enforcement is an ASGI middleware (api/middleware_view_as.py).
Start a preview
POST /v1/admin/view-as
{
"persona": "sales_manager", // one of core.personas.PERSONAS
"role_override": "manager", // admin | manager | member | viewer
"user_id": 42, // optional — pin to a specific user's data slice
"reason": "QA the manager dashboard",
"ttl_minutes": 30 // 1..120, default 30
}
The response returns a token plus session metadata (same shape as impersonation), so the web client reuses the existing X-Impersonate-Token header, storage, and banner machinery. Available personas include sales_rep, sales_manager, sales_director, marketer, dpo, cs_csm, cs_manager, cs_director, revops, and admin.
Owner-only, one at a time
Only the tenant owner can start a persona view-as session — the router hard-gates on owner and rejects admins. You cannot start a second preview while one is live; exit first. This avoids the "switch persona without clearing state" footgun that would confuse an audit reviewer.
Read-only is enforced at the edge
While a persona session is active, a middleware blocks every unsafe method (POST, PUT, PATCH, DELETE) before it reaches a handler — so there is no way to accidentally save a change while previewing. Only the exit and logout paths are whitelisted:
POST /v1/admin/view-as/exit — end the preview (idempotent)
DELETE /v1/admin/impersonation/{token} — stop
POST /v1/auth/logout — logout also revokes
If the token can't be resolved (DB blip, TTL race), the middleware degrades to allow — failing closed would block the exit endpoints during an incident, which is the wrong tradeoff; the downstream handler reaches the same read-only conclusion anyway.
Inspect the active session
GET /v1/admin/view-as/current — describe the active session for the token
GET /v1/admin/view-as/catalog — list available personas
View as vs. impersonation
Two related tools, different posture
Pact also has user-mode impersonation (/v1/admin/impersonation) which allows writes (with audit) so an admin can act on a real user's behalf and verify an end-to-end flow. Persona view-as is the stricter sibling: it simulates a UI shape, blocks all writes, and is owner-only. They live in separate routers on purpose so their auth postures can never grow together by accident.
Every impersonation and view-as action is recorded in the audit log, and impersonation exposes its own audit list and CSV export at GET /v1/admin/audit/impersonation and GET /v1/admin/audit/impersonation.csv.