Security

Identity & User Context

Tell the agent who's talking. Your backend asks Widgent for a signed token — the widget sends it with every message.

Why identify users?

Without identity, every conversation is anonymous. With a Widgent-signed token you get:

  • The agent can address the user by name and personalize responses.
  • Your tools receive the stable user ID and optional metadata — no separate lookup needed.
  • Audit logs are tied to real users, not session IDs.
  • You can scope tool permissions per user.

Step 1 — Create a server endpoint

Add a small endpoint to your backend that calls POST /v1/auth/user-token using your Widgent Verification Secret from the Dashboard → Security tab.

Node.js / Express
// GET /api/widgent-token
app.get('/api/widgent-token', requireAuth, async (req, res) => {
  const response = await fetch('https://api.widgent.app/v1/auth/user-token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      productId: process.env.WIDGENT_PRODUCT_ID,
      verificationSecret: process.env.WIDGENT_VERIFICATION_SECRET,
      userId: req.user.id,
      name: req.user.name,
      metadata: { plan: req.user.plan },
    }),
  });

  if (!response.ok) return res.status(500).json({ error: 'Token generation failed' });
  const { token } = await response.json();
  res.json({ token });
});
Python / FastAPI
import os, requests

@app.get("/api/widgent-token")
def widgent_token(current_user = Depends(get_current_user)):
    response = requests.post("https://api.widgent.app/v1/auth/user-token", json={
        "productId": os.environ["WIDGENT_PRODUCT_ID"],
        "verificationSecret": os.environ["WIDGENT_VERIFICATION_SECRET"],
        "userId": str(current_user.id),
        "name": current_user.name,
        "metadata": {"plan": current_user.plan},
    })
    response.raise_for_status()
    return response.json()

Step 2 — Register the token fetcher

Register a function that fetches the token from your backend after the widget fires widgent:ready.

// Initialize the widget first
window.widgent.init({
  productId: 'YOUR_PRODUCT_ID',
  serviceKey: 'YOUR_SERVICE_KEY',
});

// Then register the token fetcher
window.addEventListener('widgent:ready', () => {
  window.widgent('setIdentityTokenFetcher', async () => {
    const res = await fetch('/api/widgent-token');
    if (!res.ok) return '';
    const { token } = await res.json();
    return token;
  });
});

Return an empty string for anonymous sessions. The widget calls this fetcher on load and before the token expires.

Token request reference

FieldRequiredDescription
productId✅ YesProduct ID from the dashboard Setup tab.
verificationSecret✅ YesSecret from the dashboard Security tab. Keep it server-side.
userId✅ YesStable unique user ID (string).
nameOptionalDisplay name shown in Conversations and injected into the system prompt.
metadataOptionalSmall key-value object for role, plan, or account context.

Security notes

  • Your Verification Secret is never sent to the browser — keep it server-side only.
  • Do not sign JWTs manually with jose, jsonwebtoken, or similar libraries — call POST /v1/auth/user-token.
  • Widgent verifies the returned token's signature on every request.
  • Expired tokens result in an anonymous session — the widget continues to work but loses user context.
  • CORS is scoped per product — only requests from your registered domain are accepted.