Back to BlogArchitecture & Engineering

Safe User Impersonation for SaaS Support Teams: Consent, Scope and Audit

Rupak Amin

Founder & Lead Engineer, RAITHub

8 min read

RAITHub ships and tests production software. See QA as a Service or talk to us.

Build SaaS impersonation so support can see what a customer sees without becoming them: keep the staff member's real identity in the session alongside the impersonated user, scope what impersonation may do (often read-only or no access to money and credentials), time-limit it, show a persistent banner, and write every action to the audit log under the real staff member, not the customer.

This is engineering guidance for multi-tenant SaaS. If you would rather have it built and tested for you, see how RAITHub would build this below.

Why is impersonation so risky if you get it wrong?

Because a naive version replaces the session's user with the customer's, so from that point on the system cannot tell staff from customer. If staff then change a setting or delete data, the audit log blames the customer. If the session leaks, an attacker inherits a staff member's ability to walk into any account. And it is often done with no customer awareness at all. The fix is to never lose the real identity, and to constrain what impersonation can reach.

DesignWho the system thinks you areRisk
Swap the session userThe customer, fullyAudit blames the customer; no limits; no accountability
Share the customer's passwordThe customerCredential sprawl; impossible to revoke or attribute
Dual-identity sessionStaff member acting as the customerLow, if scoped, timed and audited

How should an impersonation session be modelled?

Keep both identities in the session: the acting staff member and the impersonated user. Authorisation for the customer's data comes from the impersonated user; accountability stays with the staff member. Record each session so it can be reviewed and ended.

// The session carries BOTH identities for the whole impersonation.
interface Session {
  userId: string               // the impersonated customer (drives data access)
  tenantId: string
  actingStaffId?: string       // set ONLY during impersonation
  impersonationId?: string     // the impersonation_sessions row
  impersonationExpiresAt?: string
  scope?: 'read_only' | 'full' // what this impersonation may do
}

// Every write records WHO really did it.
export function actorForAudit(s: Session) {
  return s.actingStaffId
    ? { actorId: s.actingStaffId, actorType: 'staff', onBehalfOf: s.userId }
    : { actorId: s.userId, actorType: 'user' }
}
CREATE TABLE impersonation_sessions (
  id          uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  staff_id    uuid NOT NULL REFERENCES users(id),   -- the real person
  target_id   uuid NOT NULL REFERENCES users(id),   -- the customer
  tenant_id   uuid NOT NULL REFERENCES tenants(id),
  reason      text NOT NULL,                         -- a support ticket reference
  scope       text NOT NULL DEFAULT 'read_only',
  consent     text NOT NULL DEFAULT 'none',          -- none | policy | explicit
  started_at  timestamptz NOT NULL DEFAULT now(),
  expires_at  timestamptz NOT NULL,                  -- short, e.g. 30 minutes
  ended_at    timestamptz
);

What should impersonation be allowed to do?

Default to read-only, and carve out things no support session should ever reach even when fuller access is granted: viewing or changing passwords and 2FA, reading recovery codes, changing payout details, or taking destructive actions. Scope is enforced in code on every request, not by asking staff to be careful. A time limit is part of the scope: a 30-minute window that cannot be silently extended means a forgotten impersonation session expires on its own.

// A single check all customer-data writes pass through.
export function assertAllowed(session: Session, action: 'read' | 'write' | 'sensitive') {
  if (!session.actingStaffId) return                 // normal user, normal rules
  if (new Date(session.impersonationExpiresAt!) < new Date())
    throw new Error('impersonation session expired')
  if (session.scope === 'read_only' && action !== 'read')
    throw new Error('impersonation is read-only')
  if (action === 'sensitive')
    throw new Error('impersonation cannot perform sensitive actions')
}

Which permissions a staff role may use while impersonating should come from the same permission model as the rest of the product, so it is declared and testable rather than scattered through the code. That model is covered in the SaaS authorization and RBAC design guide.

At minimum, make impersonation visible: a persistent banner while it is active ("You are viewing Acme as support agent Dana"), and an option for workspace admins to require explicit customer consent before a session can start. Three honest levels: none (your policy allows support access, disclosed in your terms), policy-based (the customer's plan or admin setting controls whether it is allowed), and explicit (the customer approves each session or a time-boxed window). Enterprise buyers increasingly ask which you offer.

Whether customers can be impersonated without per-session consent, and what you must disclose, depends on your contracts and local law. This is general information; confirm the requirements with your adviser. The engineering job is to make every level possible and to prove, from the audit log, which was used.

How does impersonation stay accountable?

Every action taken during impersonation is written to the audit log under the real staff member, with the impersonated user recorded as "on behalf of", so a later review reads "Dana (support), acting as Acme's owner, exported the customer list". Log the start and end of every session, its reason and scope, and surface a customer-visible history of when support accessed their account. The append-only, tamper-evident design for that log is in the SaaS audit log design guide.

Do-it-yourself estimate: 1–2 weeks for a dual-identity session, scope enforcement, expiry, a banner and audit entries, if you already have an audit log and a permission model. The main risks are a session that loses the real identity (so the audit blames the customer) and a scope that is not enforced on the server.

Buy, build or hire?

OptionExamplesChoose this whenWatch out for
Auth provider impersonation featureA hosted auth service with a "login as user" actionYou use their sessions and want a quick support loginScope limits, consent levels and your own audit trail may still be yours
A support/session toolA co-browsing or screen-sharing support toolYou want to see the screen without acting in the accountDifferent from acting as the user; no changes, but also no write access when needed
Custom build on your sessionsThe dual-identity design in this guideImpersonation must follow your roles, scopes, consent and auditYou own scope enforcement, expiry and accountability
Hire a team to build itRAITHub or another studioEnterprise buyers ask about support access and you want it auditedGet the scope, expiry and audit tests in the handover

How do you test impersonation?

  • Attribution: act during impersonation and assert the audit entry names the staff member, not the customer.
  • Scope: in a read-only session, attempt a write and a sensitive action and assert both are refused.
  • Expiry: use the session past its window and assert it is rejected and cannot be silently extended.
  • Isolation: assert staff can only impersonate within permission, and never reach passwords, 2FA or recovery codes.
  • Visibility: assert the banner shows throughout and the customer's access history records the session.

How RAITHub would build this

  • Session model: a dual-identity session that keeps the staff member's real identity alongside the impersonated user, with a short, non-extending expiry.
  • Scope and consent: read-only by default, hard limits on sensitive actions, and configurable consent levels (none, policy, explicit).
  • Accountability: every action audit-logged under the real staff member, a persistent banner, and a customer-visible access history.
  • Tests: attribution, scope, expiry and isolation tests in CI.

Timeline: impersonation inside a new SaaS build fits the 4–6 week fixed scope; added to an existing product it is a bounded piece in the 6–12 week backend range. You receive: scope and audit tests in CI, handover docs and runbooks, and full IP under NDA.

Next step: a free 15-minute technical audit, then a written fixed quote. See the SaaS development service, pair it with the audit log design guide, and book the audit.

Frequently asked questions

What is user impersonation in a SaaS?

A support feature that lets staff view and sometimes act in a customer's account to reproduce an issue. Done safely, the staff member's real identity is kept in the session, access is scoped and time-limited, and every action is audit-logged under the staff member.

Should support staff share the customer's password to log in?

No. Sharing passwords creates credential sprawl, cannot be revoked cleanly, and makes every action look like the customer's. Use a dual-identity impersonation session that keeps staff and customer identities separate and attributes actions correctly.

Should impersonation be read-only?

Default to read-only, and block sensitive actions, such as viewing passwords or recovery codes, changing payout details or deleting data, even when fuller access is granted. Enforce the scope on the server for every request, not by trusting staff to be careful.

Do customers have to consent to being impersonated?

It depends on your contracts and local law; confirm with your adviser. Engineering should make every level possible, from disclosed policy access to per-session explicit consent, always show a banner while active, and record which level was used in the audit log.

How do I keep impersonation accountable?

Write every impersonated action to a tamper-evident audit log under the real staff member, with the customer recorded as "on behalf of". Log each session's start, end, reason and scope, and show the customer a history of when support accessed their account.

impersonationsupportaudit logauthorizationSaaSsecurityTypeScript

Ready to discuss your project?

Book a free 15-minute technical audit with our engineering team.