Skip to content
LogoLogo

Support Staff

Support staff view as a member of any org in the deployment ("view as") without being members of that org. Two reserved roles grant it, both held at deployment scope only:

RoleMay startWhile viewing as someone
saaslayer:support-view-onlyview-only sessionsevery write is refused (403 VIEW_ONLY_IMPERSONATION); reads run as the person viewed
saaslayer:support-act-asview-only and act-as sessionsact-as also runs the person's writes; reserved operations stay refused (RESERVED_UNDER_IMPERSONATION)

Each role holds saaslayer:users:account:impersonate and the reads that find whom to view as, all at deployment scope: saaslayer:users:account:read (user-service GET /api/users?email=), saaslayer:identity:user:read (Permissions GET /users/{id}/orgs), saaslayer:orgs:org:read (GET /orgs, GET /orgs/{id}) and saaslayer:orgs:member:read (GET /orgs/{id}/members). No write of any kind. Holding impersonate makes its holder a protected target: nobody views as support staff.

Granting and revoking

Only an access admin signed in themselves grants or revokes a support role (never an API key, an IAM machine, a delegated session or an impersonated one), at deployment scope, optionally until an expiry. A customer org owner, an org-scoped role administrator and support staff themselves cannot grant, widen or revoke support access, their own included.

saaslayer users get --email support@acme.com --deployment dep_…            # find the suid
saaslayer permissions support-staff grant <suid> --mode act-as --expires-at 2027-01-01T00:00:00Z --id-token-file id.jwt --deployment dep_…
saaslayer permissions support-staff list --deployment dep_…
saaslayer permissions support-staff revoke <suid> --mode act-as --id-token-file id.jwt --deployment dep_…

The CLI calls the role assignment routes: POST /users/{id}/roles {"roleId":"saaslayer:support-act-as","expiresAt":"…"}, DELETE /users/{id}/roles/saaslayer:support-act-as, and GET /roles/{id}/assignments (platform callers only) for the list.

Sessions and modes

A session starts with session.impersonate({ targetSuid, orgId, mode }) (@saaslayer/js). orgId is the target's org; the session acts only inside it. The server checks the mode against the actor's grant and owns it from then on:

  • an omitted or unknown mode starts view-only, so an older client never acts;
  • a support-view-only holder asking for act-as is refused (403 FORBIDDEN, reason mode_not_allowed);
  • the token carries the mode in custom:as_mode; Permissions and the server SDK (HTTP and direct) treat a token whose custom:as_mode is missing or unknown as view-only;
  • refreshes keep the session's mode and end time and re-check the grant: a revoked grant, or act-as removed from it, ends the session at the next refresh with a clean token. A token already issued stays usable until its own expiry (at most the pool's token lifetime) or the session's end, whichever comes first;
  • useImpersonation() (@saaslayer/react) exposes mode and endsAt.

Members who hold impersonate in their own org keep today's rule (they must belong to the org) and may start either mode.

Settings

SettingDefaultMeaning
user-service.ImpersonationEnabledfalseimpersonation is off until the deployment turns it on
user-service.ImpersonationMaxSeconds900how long a new session lasts, 60 to 86400 seconds; fixed when it starts
user-service.ImpersonationAuditVisibleToCustomerfalserecord session start and end, with the real actor and the mode, in the customer's org audit feed

Sessions are always logged by user-service (impersonate:audit lines) whatever the visibility setting.

Writes made while viewing as someone are recorded in the org's audit log with the person viewed as the actor and the staff member as realActor. The staff member's name and email are stored, but customers should see only the deployment's support label (permissions-service.SupportLabel, default Support), as <sl-audit-log> shows it: see Staff in the audit log.