/Docs
Start free

Identity verification

Make sure name and email from setVisitor came from your backend — not a visitor’s DevTools.

Why verify

SellioWidget.setVisitor({ name, email }) runs in the visitor’s browser. Anyone can open the console and claim another person’s email. That is fine for anonymous chat; it is not fine when a contact record drives routing, CRM merges, or trust decisions.

Identity verification asks your server to HMAC-SHA256 the user id and email with a workspace secret. Sellio only trusts the identity when the signature matches.

Setup

1

Generate a secret

In Sellio: Settings → Install → Identity. Generating mints a secret for the workspace.

2

Sign on your server

HMAC-SHA256 the stable user id and email, joined by a newline, with the secret (the id alone when there is no email). Never put the secret in frontend code.

3

Pass userHash

Include userHash (and id) in setVisitor from the browser.

Sign on your server

sign.js
import { createHmac } from "node:crypto";

// On your server, never in the browser. The id and the email, joined by a
// newline, so the email is trusted too; the id alone when there is no email,
// and an empty id (a newline, then the email) when there is no id.
const userHash = createHmac("sha256", process.env.SELLIO_IDENTITY_SECRET)
  .update(user.email ? `${user.id ?? ""}\n${user.email}` : user.id)
  .digest("hex");

The email is what links a visitor to their contact, so it is only trusted when the signature covers it. A hash of the id alone still verifies the id, but an email that comes with it is shown to your team as unverified and never attaches the chat to a contact, even when the id is itself an email address. The same goes for anything a visitor types into the pre-chat form. A user without an email is signed by id alone, as above; if your users have no id, leave it empty and sign a newline followed by the email.

A name and phone number sent with a valid signature are shown as they are, beside the signed user id, since the signature vouches for the user rather than for those fields: only send ones your own server knows. One typed into the chat, or sent through setVisitor without a signature or with one that does not verify, still shows in the inbox, labeled unverified, and is never copied onto a contact. An id that came with a signature that does not verify is not kept.

⚠
Store the secret as an env var (for example SELLIO_IDENTITY_SECRET). Rotating it invalidates old hashes until you redeploy with the new secret.

Pass userHash

setVisitor.js
SellioWidget.setVisitor({
  id: user.id,
  name: user.name,
  email: user.email,
  userHash, // from your server, above
});

See also the Widget JavaScript API.

Notes

  • Verification stays off until you generate a secret, so existing installs are not broken by this feature existing.
  • The signature is HMAC over the user id and email, not a JWT. No expiry or algorithm confusion to misconfigure.
  • You can check a sample hash in Settings → Install → Identity before shipping.

Updated . Something wrong or missing? Tell us.