skip to main content
Browse documentation

Authenticating your users

The four ways the widget can authenticate your own end users, and how to choose the one that fits your stack.

When someone uses the chat in your app, Syncanix needs to know who they are — so the assistant acts as that person and nobody else. You stay in control of identity: Syncanix verifies a token your own system issues, rather than asking your users to create a separate Syncanix account.

The four auth modes

Pick one based on how your app already handles authentication. They range from a few lines of backend code to a fully proxied setup where the widget never sees a token.

Signed session token (default)

Your backend mints a short-lived signed token for the logged-in user with a shared secret, and hands it to the widget. It’s the fastest path — a few lines of server code — and fits most apps that already have their own login. Generate the shared secret on the dashboard’s Identity federation page: it is revealed exactly once, and you can rotate it at any time.

Identity-provider adapter (recommended)

If you already use Auth0, Clerk, Amazon Cognito, or WorkOS, the widget reads the token your provider’s SDK already issues in the browser, and Syncanix verifies it server-side against your provider’s public keys. No new secret to manage, and step-up re-verification works out of the box.

OAuth token exchange

For enterprise setups, Syncanix supports the standard token-exchange flow (RFC 8693): your authorization server swaps an existing token for a narrowly scoped one bound to the chat session. Best when your security team wants every downstream token explicitly issued and audited.

Backend-for-frontend (BFF)

The most locked-down option: a small proxy you run sits between the widget and Syncanix, so tokens never reach the browser at all. Choose this when policy forbids any token in client-side code.

Signed session token, end to end

The fastest integration is a small token endpoint in your backend plus two lines on your page. Here is the complete setup.

  1. Generate the shared secretIn the dashboard, open Settings → Identity federation and generate the session-token secret. It is shown exactly once — store it in your secret manager, for example as SYNCANIX_SESSION_SECRET.
  2. Add a token endpoint to your backendBehind your existing login, sign a short-lived token for the current user with the shared secret.
  3. Hand the token to the widgetRegister a token provider that fetches from your endpoint — the widget calls it before each turn.

A Node example with the jose library (any JWT library in any language works the same way):

import { SignJWT } from 'jose';

const secret = new TextEncoder().encode(process.env.SYNCANIX_SESSION_SECRET);

app.get('/api/chat-token', requireLogin, async (req, res) => {
  const token = await new SignJWT({ tenant: process.env.SYNCANIX_WORKSPACE_ID })
    .setProtectedHeader({ alg: 'HS256' })
    .setSubject(req.user.id)
    .setAudience('syncanix-tools')
    .setIssuedAt()
    .setExpirationTime('10m')
    .sign(secret);
  res.json({ token });
});

Whatever library you use, the token must carry exactly these claims:

  • aud — the fixed string syncanix-tools.
  • sub — your user’s stable id; this is who the assistant acts as.
  • tenant — your workspace ID (you can read it from your MCP connection URL on the dashboard’s MCP page).
  • exp and iat — expiry at most 15 minutes after issue; shorter is better.

Then wire the widget to your endpoint:

window.syncanix?.setTokenProvider(async () => {
  const res = await fetch('/api/chat-token');
  const { token } = await res.json();
  return token;
});

Which one should you pick?

Want the fastest start
Use the signed session token — a small backend endpoint is all you need.
Already use a hosted identity provider
Use the identity-provider adapter — it reuses what you have and unlocks step-up.
Have strict security requirements
Use OAuth token exchange or the BFF, depending on whether tokens may touch the browser at all.

Next steps