OpenAgentOpenAgent

Identity verification

Sign the user's ID with an HMAC on your server and the widget carries a verifiable identity: personalized answers, contact auto-sync, and optional hard enforcement.

View as Markdown

If visitors are signed in to your app, tell the agent who they are — verifiably. Your server computes user_hash = HMAC-SHA256(user_id) with the agent's signing secret; the page calls identify; the widget attaches user_id, user_hash, and user_metadata to every message. OpenAgent recomputes the HMAC server-side, so nobody can impersonate a user from the browser.

Never compute the hash in the browser

The signing secret lives in server-side env only. Shipping it to the client lets anyone impersonate any user. Find and rotate the secret under the chat service's Embed → Identity verification.

1. Sign on your server

const crypto = require('crypto');
const secret = process.env.BOOKBAG_SECRET;
const userId = String(currentUser.id);
const userHash = crypto.createHmac('sha256', secret).update(userId).digest('hex');
import hmac, hashlib, os
secret = os.environ['BOOKBAG_SECRET']
user_id = str(current_user.id)
user_hash = hmac.new(secret.encode(), user_id.encode(), hashlib.sha256).hexdigest()
$secret = getenv('BOOKBAG_SECRET');
$userId = (string) $currentUser->id;
$userHash = hash_hmac('sha256', $userId, $secret);

2. Identify in the browser

window.bookbag('identify', {
  user_id: 'user-123',
  user_hash: 'the-hash-from-your-server',
  user_metadata: { name: 'Jane Doe', email: 'jane@example.com' }
});

Re-call identify after sign-in/sign-out; identify(null) clears it. The widget always uses the most recent identity.

3. Optionally require it

Turn on Require verified identity and chats without a valid signature are refused with 401 identity_unverified. Roll out in order: ship identify(), confirm it works, then require it — the other order rejects everyone.

What identity unlocks

  • Contact auto-sync — a verified chat upserts the contact whose external_id equals user_id, from user_metadata. Never a duplicate.
  • Personalization — the agent greets by name and answers from the contact's known details.
  • Tool context — tools can use {{contact.email}}, {{contact.name}}, {{contact.external_id}}, {{contact.attr.<key>}}.