Limit support impersonation to assigned customer accounts

Tenant isolation for user impersonation takes two checks: may this agent open this customer, and may this customer reach this tenant? With a test matrix.

A support agent assigned to one customer shouldn’t be able to open another customer’s account just because both use your SaaS. Tenant isolation means each customer’s data and actions stay separate from every other customer’s, even on shared infrastructure. For user impersonation, that takes two separate checks:

  1. Actor to target. May this staff member impersonate this user, for this customer, right now?
  2. Subject to tenant. May this customer user access the tenant, resource and operation in each request?

Most systems implement the second check already, because it’s ordinary multi-tenant authorization. The first is the one that tends to be missing. Teams ask for it regularly. One Keycloak GitHub discussion (opens in a new tab), for example, asks for service providers to impersonate “only their own users”. Your application owns both checks.

Check the assignment before issuing access

Write the policy in plain terms first. For example: active support staff may open read-only sessions for active, ordinary users of customers in their current portfolio; privileged accounts need a separate process.

Then make the code that issues the impersonation credential resolve, on the server:

  • The staff identity, from verified authentication state.
  • The mapping from that identity to your internal staff record.
  • The target user’s canonical account and customer membership.
  • The current staff-to-customer assignment, from your source of truth.
  • Any excluded targets, the requested scope and approval requirements.

Deny issuance if any of these is missing or ambiguous. An unknown assignment must never mean access to every customer.

A filtered search list makes picking the right customer easier, but it isn’t the check. Repeat the assignment check when you issue the credential, even if a search or approval succeeded earlier, because assignments can change in between.

Devora handles requests, approvals and scoped sessions, and passes the verified staff identity and target (opens in a new tab) to your backend. It doesn’t know your staff-to-customer assignments or enforce them. Devora can route requests to the right approvers, but it doesn’t restrict which customers a member can request. Put the assignment check in your issuance path.

Check the customer’s tenant access on every request

Passing the assignment check doesn’t give the customer, or the agent, any new permissions. An agent assigned to Amber still can’t read Birch’s invoices through an Amber user’s session. Support shouldn’t quietly inherit admin rights to make a diagnostic work, either.

For every protected request:

  1. Resolve the authenticated customer user.
  2. Authorize the requested tenant.
  3. Check resource ownership.
  4. Apply the customer’s normal permissions.
  5. Apply the support session’s extra restrictions, such as read-only.

User IDs, tenant IDs, headers and form fields from the browser are selectors, not proof of authorization. Validate them against server-side identity and membership. The scope and security guide (opens in a new tab) explains where Devora’s backend guard fits. It isn’t a replacement for your tenant checks.

If the customer user belongs to several tenants, decide whether the support session is limited to one of them. If it is, store that restriction in trusted server-side session state and check it on every request. Selecting one tenant in the UI doesn’t stop a request for another.

Test it with two agents and two tenants

Set up synthetic data. Agent A is assigned only to Tenant Amber, and Agent B only to Tenant Birch. User Amber belongs only to Amber, and User Birch only to Birch. Both are ordinary members, and sessions are read-only. These are the outcomes to verify:

AgentTargetAt issuanceThen requestsExpected
AUser AmberAllowed, subject to approvalRead an Amber resourceAllowed if the user’s permissions allow
AUser BirchDenied: not assigned(no credential)Denied
BUser AmberDenied: not assigned(no credential)Denied
BUser BirchAllowed, subject to approvalRead a Birch resourceAllowed if the user’s permissions allow
AUser AmberAllowedRead a Birch resource by changing the IDDenied: tenant boundary
BUser BirchAllowedRead an Amber resource by changing a tenant headerDenied: tenant boundary
AUser AmberAllowedChange an Amber resourceDenied: read-only
BUser BirchAllowedChange an Amber resourceDenied: tenant and read-only

Add a privileged user in each tenant and confirm that ordinary support can’t get a credential for them. Also try changing the target ID after approval. Issuance should reject the substitution rather than create access for the new target.

Note which layer produced each denial. A write blocked by read-only scope doesn’t prove tenant isolation, so repeat cross-tenant attempts as reads to test that boundary on its own.

Treat reassignment as an access event

An assignment check at issuance shouldn’t become permanent permission. Decide what happens when assignments change mid-session, and who implements it. For strict isolation, re-check eligibility on protected requests and revoke support access when an assignment is removed.

Change during Agent A’s Amber sessionExpected resultEvidence to collect
A’s Amber assignment removedFurther requests deniedAssignment change and denial timestamps
A moved from Amber to BirchAmber access denied; Birch needs a new approvalOld-session denial and a separate issuance decision
User Amber removed from the Amber tenantAmber resources deniedMembership lookup and denial
Session ended with the tab closedCredential rejectedRevocation record and a direct API call
Session ended while a credential was still being issuedThe late credential is rejectedRevocation keyed by session ID

Devora sends your backend a signed termination notice when it ends a session, even with no tab open. Its session lifecycle guide (opens in a new tab) recommends keying revocation by Devora session ID, so a credential issued after termination is refused too. A change in your own staff assignments is a separate event. Devora won’t see it, so connect it to your revocation process yourself.

Document how long assignment data is cached and the longest stale-access window you’ll accept. Then test the next request from a tab that’s already open. A changed label in an admin screen isn’t evidence.

Use the smallest view that answers the ticket

A tenant-scoped support panel or a sanitized fixture often answers the question without opening a customer session. Use it when it’s enough.

When account access is necessary, review the custom session prerequisites (opens in a new tab), shared security responsibilities and the general impersonation checklist. For audit design, continue with recording the agent and the customer in audit logs.

Once someone on your team owns the assignment checks, evaluate Devora in staging using the matrix above. Get engineering and security review and real test results before using it in production.

Sources

Quick answers

Common questions, answered clearly.

Direct answers to the questions teams usually ask when evaluating this approach.

Can support impersonate only their assigned customers?

Yes, if your application checks the staff member's current customer assignments on the server before it issues the impersonation credential, and reacts when assignments change. Devora does not manage staff-to-customer assignments for you.

What does tenant isolation mean for user impersonation?

It means a support session can only reach the customer it was approved for. Two checks enforce it: the staff member must be eligible to open that customer, and every request in the session must still pass the customer's own multi-tenant authorization.

Is choosing a tenant in the dashboard enough?

No. A selection only says which target was requested. Resolve the target and the assignment from trusted server-side data, and enforce the customer's own tenant access on every request.

Where should the staff-to-customer check run?

In the server-side code that issues the impersonation credential, after resolving the verified staff identity and target, and before anything is issued. Run it again at issuance even if an earlier search or approval passed.

What happens when a staff assignment changes?

Your application decides. A strict policy denies further requests, ends affected support sessions and revokes their credentials. Test cached assignments, open tabs and delayed issuance explicitly.

Put it into practice

Give your team context.Keep control of access.

Bring approvals, scoped sessions, and access history into your support workflow.