Setup · Security
Treat the identity secret like a password.
Anyone holding your identity secret can mint valid identities. The rules below keep it that way.
Rules
- Sign server-side only. The secret must never appear in browser bundles, mobile apps, or public repositories. If your signing code runs client-side, verification is theater.
- Sign stable identifiers. Hash the
user_idyour app already assigns — not emails, which can change and which you may not want hashed into logs. - Store the secret in a secrets manager (or at minimum server-only environment variables). Never commit it; never log it.
- Scope is per project. A leaked secret compromises identities for that project only — but rotate it anyway.
- Rotate on suspicion. Rotation is instant: old hashes stop validating immediately, and your next deploy starts signing with the new secret. Visitors simply re-identify after login.
If a secret leaks
- Rotate the secret in Settings → Security.
- Deploy the new secret to your signing infrastructure.
- Review recent conversations and CRM changes for identities you didn't expect — check the audit log for identify activity outside your normal traffic.
- If enforce-mode was off, consider turning it on so unsigned claims are rejected during the incident window.
What verification does not do
- It doesn't authenticate your users to HAL's dashboard — agent access is separate.
- It doesn't encrypt conversations — transport security (TLS) handles that.
- It doesn't stop anonymous chatting — anonymous visitors can still talk to you; they just can't claim an identity.
Webhook signatures, too
The same discipline applies to outbound webhooks: every delivery can carry an X-Webhook-Signature (HMAC-SHA256 of the raw body with your webhook secret). Verify it before trusting a payload — see REST API.