Verify your users with a signed token

Sign a token for the signed-in user on your backend and pass it to the widget. The agent then treats the conversation as that user's. For what verification changes, see Identity verification.

Before you begin

  • The agent is installed in your app. See the React quickstart.
  • Your backend has an endpoint that returns the signed-in user, such as GET /api/me.

Copy the secret

To copy the agent's secret:

  1. In the portal, go to Web Agents and select your agent.
  2. Select the Settings tab, then Identity verification.
  3. In the Secret row, select Copy.
  4. Add the secret to your backend's environment as FAUSTINE_IDENTITY_SECRET.

Warning

The secret signs identities for every user of your app. Keep it in server-side configuration only. Do not put it in a variable that your build exposes to the browser.

Sign the token on your backend

Sign a JWT with HS256 when you return the signed-in user. sub is your ID for the user and is required. name and email are optional and appear in the agent's Monitoring tab.

terminal
npm install jsonwebtoken
routes/me.js
const jwt = require('jsonwebtoken');

function faustineToken(user) {
  return jwt.sign(
    { sub: user.id, name: user.name, email: user.email },
    process.env.FAUSTINE_IDENTITY_SECRET,
    { algorithm: 'HS256', expiresIn: '1h' },
  );
}

app.get('/api/me', requireSession, (req, res) => {
  res.json({ ...req.user, faustineJwt: faustineToken(req.user) });
});

Pass the token to the widget

Call identify with the token when your app knows who the user is, and logout when they sign out.

src/auth.js
import Faustine from '@faustine-ai/web-agent';

export async function onSignedIn() {
  const me = await fetch('/api/me').then((r) => r.json());
  Faustine.identify({ jwt: me.faustineJwt });
}

export function onSignedOut() {
  Faustine.logout();
}

identify needs an install that calls init: the npm loader or the manual script tag. On a page that loads the agent with the auto-mount script tag, identify does nothing.

identify can run before the widget has finished loading. The call is queued and applied when the widget is ready. logout clears the identity and the open conversation from the browser.

The token expires at the time you set, one hour in this example. From then on the conversation runs as anonymous. For sessions that last longer, fetch a new token and call identify again, for example each time your app refreshes its own session.

In the portal, open the agent's Monitoring tab. The next conversation from that user shows their name with a Verified badge.

Troubleshooting

Symptom Cause Fix
The user shows as anonymous The token is expired, or the backend signed it with another agent's secret. Check FAUSTINE_IDENTITY_SECRET against the Secret row of this agent and sign a new token.
The user shows as Unverified The app passes userId, name or email to identify. Pass { jwt } only.
The previous user's conversation is still open after signing out The app does not call logout. Call Faustine.logout() in your sign-out handler.

Next steps

Last updated November 13, 2026