Security
Authentication
The widget uses JWTs signed by your backend to authenticate users. Your server is the only source of truth for identity.
How It Works
1. When you create a tenant, you receive a JWT shared secret.
2. Your backend signs a JWT for each user session using this secret.
3. The widget sends this JWT with every request to the Support Gateway.
4. The Gateway verifies the signature and extracts user identity — no passwords or API keys touch the browser.
JWT Payload
| Field | Type | Description |
|---|---|---|
| tenantId | string | Your tenant ID (ten_xxx) |
| userId | string | Unique user identifier (usr_xxx) |
| userEmail | string | User email address |
| userRoles | string[] | User roles (e.g., ["user", "admin"]) |
| plan | string | User subscription plan (e.g., "pro") |
| iat | number | Issued-at timestamp (auto-set by library) |
| exp | number | Expiration timestamp (recommended: 1 hour) |
Sign a Token — Node.js
JavaScript
import jwt from 'jsonwebtoken';function createWidgetToken(user, tenantConfig) { const payload = { tenantId: tenantConfig.tenantId, // "ten_xxx" userId: user.id, // "usr_xxx" userEmail: user.email, // "[email protected]" userRoles: user.roles, // ["user", "admin"] plan: user.plan, // "pro" }; return jwt.sign(payload, tenantConfig.jwtSecret, { algorithm: 'HS256', expiresIn: '1h', });}Sign a Token — Python
Python
import jwtfrom datetime import datetime, timedelta, timezonedef create_widget_token(user, tenant_config): payload = { "tenantId": tenant_config["tenant_id"], "userId": user["id"], "userEmail": user["email"], "userRoles": user["roles"], "plan": user["plan"], "iat": datetime.now(timezone.utc), "exp": datetime.now(timezone.utc) + timedelta(hours=1), } return jwt.encode(payload, tenant_config["jwt_secret"], algorithm="HS256")Token Refresh
When a token expires, the widget calls your onTokenRefresh callback to get a fresh one. This happens transparently — the user never sees a login screen.
JavaScript
AISupportWidget.init({ tenantKey: 'ten_your_key', jwt: initialToken, onTokenRefresh: async () => { // Called automatically when the current token expires (401) const res = await fetch('/api/support/token', { method: 'POST', credentials: 'include', }); const { token } = await res.json(); return token; },});Security Notes
- Always use
HS256algorithm. The Gateway rejects others. - Keep expiration short (1 hour max). Use
onTokenRefreshfor renewal. - Never expose the JWT secret in client-side code. Sign tokens server-side only.
- The
tenantIdin the JWT must match your tenant. Cross-tenant tokens are rejected.