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
| Field | Required | Description |
|---|---|---|
productId | ✅ Yes | Product ID from the dashboard Setup tab. |
verificationSecret | ✅ Yes | Secret from the dashboard Security tab. Keep it server-side. |
userId | ✅ Yes | Stable unique user ID (string). |
name | Optional | Display name shown in Conversations and injected into the system prompt. |
metadata | Optional | Small 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 — callPOST /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.