Without an identity, every website visitor is anonymous. The chat is tied to one browser, the agent sees a placeholder name, and the customer’s history is gone when they switch from a laptop to a phone. Once your site tells the chat who is signed in, the conversation lands on the right customer, agents see the name and the plan your system already knows, and returning customers find their earlier conversations on any device.
The difficulty is trust. Anything the browser sends can be edited in the browser. So the identity has to be vouched for by your server, which knows who is signed in, with a secret the browser never sees. This guide shows how that works in Kommio as of 20 October 2026, step by step. The reference with every field and limit is Identify signed-in visitors.
How the signature works
Each website chat inbox has an identity secret (Settings › Inboxes › the inbox › Install › Identify signed-in users). Your server uses it as the key of an HMAC-SHA256 and sends the lower-case hex result to the widget along with the user’s id. Kommio computes the same HMAC and compares. There are three signatures, all with the same secret:
| Field | What your server signs | What it unlocks |
|---|---|---|
hmac (required) |
the user id |
the identity itself: the chat belongs to this customer |
email_hmac (optional) |
id, a newline, then the email trimmed and lower-cased |
the email becomes a matching identity of the contact |
attributes_hmac (required with attributes) |
id, a newline, then the attributes as canonical JSON (keys sorted, no spaces) |
signed customer attributes shown to agents as verified |
A wrong signature is refused with a 403. It is never downgraded to an anonymous visitor, because a downgrade would hide a mistake that should be fixed. An id containing a control character such as a newline is refused with a 422, since the three signatures share one secret.
Set it up in five steps
- Create the secret. In the inbox’s Install tab, open Identify signed-in users and create a secret. It is masked until revealed; revealing and rotating need the
inboxes:managepermission and each is written to the audit log. The secret goes into your server’s configuration, never into a page or a mobile app. - Sign on your server. Compute
hmacfor every signed-in user, andemail_hmacandattributes_hmacif you send those. Ready-made code for Node, Python, PHP, Go and Ruby is on the identity page; it handles the traps of each language’s JSON encoder (Go escapes<,>and&, PHP escapes/and non-ASCII characters, Python needs compact separators). - Check your code against the test vectors. Sign the published test user (secret
kommio-example-secret, idcus_9f2k) and compare your three results with the expected values on the identity page. If all three match, your canonical JSON and your email normalisation are right. - Pass the identity to the widget. Render it only for a signed-in user, either in
Kommio.init({ key, identity })or, in a single-page app, by callingKommio.identify(identity)once your sign-in completes. CallKommio.logout()when the user signs out, so the next person on a shared computer does not continue their chat. - Test with your real secret. Install › Test a signature takes what your site sends and answers, for each signature,
valid,invalid,missingorunusable, with the message that was signed. The expected value is never returned and nothing is stored. The inbox’s demo store can also sign in a test customer so you can try the chat end to end.
What Kommio does with a signed identity
A session first, a contact when there is a conversation
Since 3 October 2026 a sign-in creates no contact. Many sites identify every signed-in user on every page, and nearly all of those visitors never write. Kommio keeps what your site signed in a chat session, one per visitor and inbox and shared by all their browsers, and creates the contact the moment one is needed:
- the visitor sends a first message;
- an agent starts a chat with them from Visitors online;
- the visitor leaves an email in the offline form.
If a contact with that id already exists, because the customer wrote before or was imported, the identity matches it at once and their history is there. A session whose visitor has not been seen for 30 days is deleted (the period is the workspace setting retention.widget_sessions_days), and erasing a contact deletes its sessions.
The email and the attributes
A signed email becomes a matching identity, so the customer’s emails and chats land on the same contact, unless another contact already owns the address; then it is left for an agent to merge. An unsigned email is shown as “Email from their site” and is never used to find a contact. The same holds for an email typed into the pre-chat form: the agent sees a possible match with a one-click merge, never an automatic one.
Signed attributes (at most 30 keys, values that are strings up to 200 characters, numbers or booleans) appear in the conversation’s Customer card as verified. A key that a custom attribute declares with the source “Website sign-in” fills that attribute and is read-only for agents unless the attribute allows edits.
Your site’s values win for the fields it sends
On every signed session the name and email your site sends replace Kommio’s when they differ, because your system is the source of truth for them. Company, notes, tags and attributes set by agents are not touched. Every overwrite is in the audit log and on the contact’s Changes tab.
An anonymous chat joins the signed-in customer
A visitor who chatted before signing in keeps that chat: the anonymous contact is merged into the signed-in one, or receives the id if the customer has no contact yet. A contact that is itself known, for example by another user’s email, is never merged; the session simply switches.
What a signed identity makes possible
- Proactive chats with known customers. Only signed-in visitors appear under Visitors online and can be offered a chat by an agent; starting a website chat with any other contact is refused. See proactive messages and visitors.
- History on every device. The same id on the phone and the laptop is the same customer.
- Context agents can trust. Signed attributes are marked verified; page context set with
Kommio.setContextis shown as provided by the page, not verified. The visitor context page lists everything an agent sees.
Moving from Chatwoot
Chatwoot signs the same message the same way: a lower-case hex HMAC-SHA256 of the user’s identifier. The importer stores each Chatwoot contact’s identifier as the Kommio contact’s verified external identity, and with the option to copy channel secrets the Kommio inbox gets Chatwoot’s HMAC token as its identity secret. Your server keeps computing the same hash; only the browser call changes, from window.$chatwoot.setUser(id, { identifier_hash, name, email }) to window.Kommio.identify({ id, hmac, name, email }). Two differences: Kommio trusts an email only with email_hmac, and refuses unsigned custom attributes. The Chatwoot migration guide has the full mapping.
What is not there yet
As of 20 October 2026, syncing a contact’s name and email from signed identities without ever overwriting an agent’s edit is planned; today the site’s values win for the fields it sends, as described above. An email column in Visitors online behind the field grants is also on the roadmap.
Frequently asked questions
What is HMAC identity verification in a chat widget?
Your server computes HMAC-SHA256 of the signed-in user's id with the chat inbox's identity secret and passes the hex result to the widget with the id. Kommio recomputes it and accepts the identity only when the two match, so a visitor cannot claim to be another customer by editing JavaScript in the browser.
Does a signed-in visitor become a contact in Kommio straight away?
No. Since 3 October 2026 a signed-in visitor is held as a chat session, not a contact. The contact is created, or matched to an existing one with the same id, when the visitor sends a first message, an agent starts a chat from Visitors online, or the visitor leaves an email in the offline form. Sessions not seen for 30 days are deleted by default.
Is the email I pass to the chat trusted?
Only when it is signed. An email with email_hmac becomes a matching identity of the contact. An email without it is shown to agents as the email from your site and is never used to find or merge contacts.
Can I pass plan, seats or other customer data to agents?
Yes, as signed attributes: a flat object of up to 30 keys with string, number or boolean values, signed with attributes_hmac over its canonical JSON. Unsigned attributes are refused. Agents see them as verified in the conversation's Customer card.
We use Chatwoot's identity validation. Does the hash change?
No. Chatwoot and Kommio sign the same message, the user's identifier, with HMAC-SHA256 in lower-case hex. The Chatwoot importer can copy the HMAC token as the inbox's identity secret, so only the browser call changes from setUser to Kommio.identify.
What happens when I rotate the identity secret?
The new secret applies at once. Until your server signs with it, signed-in visitors are refused and see an error, never someone else's chat. Revealing and rotating the secret need the inboxes:manage permission and are recorded in the audit log.
Facts on this page describe Kommio as it is on the date above; anything marked planned is on the roadmap, not shipped. Corrections to [email protected].