Agent Wranglers

Support and staff access Required

Impersonate customers only with a reason and a time limit

Let staff view an account as its customer only with a recorded reason, for at most 60 minutes. Make it read-only by default and log it for the customer.

How to do it

Start a separate session that carries both identities, such as the act claim of OAuth token exchange in RFC 8693. Ask for a ticket number. Show a banner on every page with the staff member's name and an end button. Block password, factor, email, payment, export and deletion actions. Write the staff member, the reason and each write action to the audit log and the customer's security log. Never let staff impersonate other staff.

Example

{ "sub": "u_7c1e", "act": { "sub": "staff_31", "reason": "ticket 4821" }, "exp": 1793606400 }
const BLOCKED_FOR_STAFF = new Set(['password.change', 'factor.change', 'email.change', 'billing.change', 'data.export', 'account.delete']);

export function assertAllowedInSession(session, action) {
  if (session.actor && BLOCKED_FOR_STAFF.has(action)) {
    throw new ForbiddenError('This action is not available while support is viewing the account.');
  }
}
BLOCKED_FOR_STAFF = {"password.change", "factor.change", "email.change", "billing.change", "data.export", "account.delete"}

def assert_allowed_in_session(session, action: str) -> None:
    if session.actor is not None and action in BLOCKED_FOR_STAFF:
        raise Forbidden("This action is not available while support is viewing the account.")

How to check

Start impersonation without a reason, and it is refused. With a reason, try to change the email, and it is refused. After 60 minutes the session ends. The customer's security log shows the visit.

For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers accounts playbook: https://agentwranglers.se/playbook/accounts/support-and-staff-access/impersonation.