HMAC (user_hash)
The legacy Intercom-style identity proof - an HMAC-SHA256 of the user id
The HMAC proof mirrors Intercom's legacy user_hash. It is a drop-in path if you are migrating, but it has no expiry. Use a signed JWT for new integrations.
How It Works
On your server, compute an HMAC-SHA256 of your user's id, keyed with the integration's shared secret:
user_hash = HMAC-SHA256( sharedSecret, user_id ) // hex, lowercaseimport crypto from "crypto";
const userHash = crypto
.createHmac("sha256", process.env.WEXIO_INTEGRATION_SECRET)
.update(user.id)
.digest("hex");Pass the Hash to the Widget
Pass userId and userHash together, plus any profile data. The userId cannot start with google:, passkey:, preview: or wexio-operator:.
// React
<WexioWidget
publicKey="pk_live_..."
user={{
userId: user.id,
userHash: serverComputedHash,
name: "Ada Lovelace",
email: "ada@example.com",
}}
/>// Web Component
el.identify({ userId: user.id, userHash, name: "Ada" });
// Script loader
window.Wexio("identify", { userId: user.id, userHash, name: "Ada" });The backend recomputes the HMAC with the decrypted secret and compares it in constant time. On a match, it creates a verified session keyed on your userId.
Trade-Offs Against JWT
HMAC user_hash | Signed JWT | |
|---|---|---|
| Expiry | Never - a leaked hash impersonates forever | Bounded by exp |
Trusted profile fields | No | Yes |
| Revocation | Rotate the shared secret (affects all users) | Token self-revokes at exp |
A user_hash never expires, so a leaked one is a permanent impersonation risk for that user. Use signed JWTs for new integrations. Keep HMAC for migrating existing Intercom-style installs.
Logging Out
Clear identity the same way as with any proof. See Sessions.
Related
- Signed JWT - the recommended proof.
- Integration settings - rotate the shared secret.
- Authentication - compare all proofs.