Skip to content
Guide

Act as a user to help them: support access

Open your app as one of your users from the dashboard, with a reason, a time limit and a ceiling on what support may do. Every action is audited and the user is told.

You get
Support that opens your app as a user, with a reason, a time limit, a ceiling on its permissions and an audit trail.
For
Backend developer, Ops
Time
About 25 min
Products
Support
Organisations and roles

Support access lets you see your app the way one of your users does, to reproduce a problem or fix it with them. You start it from the dashboard with a reason, it lasts a limited time, it can never touch the account's credentials, money or data export, every action is logged, and the user is told.

1. Turn it on

In the dashboard, Settings → Support access: turn on Let support act as a user. Choose whether the user must approve each access first, whether they get an email (on by default), the longest session (30 minutes unless you change it, at most 240) and the ceiling: permissions support access never uses. The defaults block account deletion, email, password and two-step changes, payments, refunds, data export, deleting organisations and creating organisation tokens or invites. Add your app's own, such as projects:delete.

The project owner may always start support access; give it to the members who do support on the project's Members list.

2. Give your app a start URL

Apps → your app → Support access start URL: a page of your app on the same site as its callback URL, for example https://app.acme.example/support-access. The dashboard opens it with a one-time code (60 seconds, single use, only for this app); the SDK exchanges it for the user's tokens, so no token is ever in a URL. In a browser app nothing else is needed. Show a banner while support is in:

app.ts
const auth = createAuth({ project: 'acme', env: 'prod', clientId: 'prod_…' });
await auth.ready(); // exchanges the dashboard's one-time code on the start URL

const imp = auth.impersonation(); // null for the user's own sign-in
if (imp) showBanner(`${imp.actor.email} from support, until ${new Date(imp.expiresAt!).toLocaleTimeString()}: ${imp.reason}`, () => auth.endImpersonation());

A website with a server exchanges the code with its client secret:

server.ts
app.get('/support-access', async (c) => {
  const r = await web.impersonation(c.req.url); // exchanges the one-time code with the client secret
  if (!r) return c.redirect('/');
  await saveSession(c, r.session);
  return c.redirect(r.returnTo);
});

3. Guard your API

Support access tokens are the user's own, with an act claim naming who is really acting (RFC 8693) and the project's ceiling. Your API sees user.type === 'impersonation' and user.impersonator; guards deny the ceiling and the permissions you mark destructive:

api.ts
export const access = defineAccess({
  roles: { admin: ['projects:*', 'invoices:*'] },
  destructive: ['projects:delete', 'invoices:refund'], // never during support access (unless allowDestructive)
});

app.use('/api/*', auth.middleware(), auth.impersonationAudit()); // changes under support access go to the user's timeline
app.delete('/api/projects/:id', auth.require('projects:delete'), deleteProject); // 403 for support access

4. Help a user

Open the user on the Users page and choose Act as user. Give a reason or a ticket or conversation link, the minutes and the app to open; you sign in again with your second factor if your last sign-in is older than 10 minutes. The app opens in a new tab as the user. End now ends it at once: its session and every token stop working, and apps with back-channel logout are told.

What is recorded, and what the user sees

The user's timeline in the Users panel and the audit log show the start (who, why, for how long), every app opened, every change made through Anchr.ing and your app (refused ones too), and the end. The user gets an email and sees each access on their account page: who, when and why; with consent on, they approve it there first. Your backend gets the impersonation.started and impersonation.ended webhooks.

Every option, error and token type: the SDK README.

Try it in your own test environment

Every feature works in test on the free plan, so the code above runs against your real sign-in.