DocsCustomer impersonation

Customer impersonation

Operate as a customer from the CLI or web UI. Same auth, different scope.

Overview

Most of the day-to-day in agency mode is "operate as a customer". You don't log out and back in as the customer. There's no customer login at all today. Instead, you stay signed in as your agency self and tell Oya which customer to scope every request to.

From the CLI

Pin a customer as your active target with oya account use:

bash
oya account use acct_8f3c… oya account whoami # → Active target: acct_8f3c… (Acme Corp) # Now every command scopes to Acme: oya agent list # lists Acme's agents, not yours oya agent runs <id> # Acme's run history oya template deploy … # deploys to Acme # Switch back to operating as yourself: oya account use --clear

The active target persists in ~/.oya/config.json across shells. The CLI sends an X-Target-Account-Id header on every authenticated request; the backend validates it against your accessible_account_ids() set before allowing the request to proceed.

Tip
If you forget you have an active target pinned, the most common "why is this command operating on the wrong account?" cause is a stale oya account use from an earlier session. oya account whoami shows it in one line.

From the web UI

The web app uses a short-lived signed JWT to enter a customer's context. The flow:

  • 1. Open the agency dashboard at /agency.
  • 2. Pick a customer from the list. The backend issues a 1-hour HS256 JWT encoding the target account ID and your admin user ID (audit trail).
  • 3. The frontend redirects with ?impersonate=<token>, which is stored client-side and forwarded on every request as X-Impersonate-Token.
  • 4. Every API endpoint resolves the target account from the token, not the URL.
Note
The same impersonation primitive is used by Oya admins to support customers. Agency impersonation is the same code path with a different scope check: agencies can only impersonate their own customers; admins (@oya.ai) can impersonate any user.

What you can and cannot do

You can

  • Create, edit, deploy, and delete agents on the customer account.
  • Connect gateways (Slack, Gmail, etc.) on behalf of the customer.
  • Upload KB entries, attach skills, install routines.
  • View runs, threads, and traces.
  • Trigger ad-hoc runs.

You cannot

  • Switch into a customer that isn't in your accessible_account_ids set. Attempts get a 403.
  • Issue admin-only operations (delete other agencies, impersonate non-customers, see internal Oya billing tables).
  • Skip the audit trail. Every impersonated request logs both the target account ID and the admin user ID who initiated it.

Audit trail

Each impersonation token encodes the admin user ID (admin_sub) alongside the target account. Backend logs every request with both IDs so "who did what on which customer" is reconstructable. The impersonation JWT itself has a 1-hour TTL: long enough for a support session, short enough to limit blast radius if a token leaks.