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_id your 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

  1. Rotate the secret in Settings → Security.
  2. Deploy the new secret to your signing infrastructure.
  3. Review recent conversations and CRM changes for identities you didn't expect — check the audit log for identify activity outside your normal traffic.
  4. 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.