Verificação de identidade: prove quem é o visitante do chat

Se o seu site já sabe quem está navegando, ele pode contar isso ao chat. O problema é que contar não prova nada: os dados que o site envia no código do widget são texto puro, e qualquer visitante consegue trocar o e-mail por outro no navegador. A verificação de identidade resolve isso com uma assinatura que só o seu servidor consegue gerar. Com ela, o agente de IA pode consultar dados privados da pessoa com segurança, e o seu cadastro para de aceitar identidade forjada.

O caminho todo tem cinco passos e roda uma vez por chat. A tela fica em Administração › Configurações › Canais › Chat › Instalar no site, na linha Verificação de identidade, logo abaixo do código do widget. Ela também abre pelo editor de APIs do agente, quando alguma ação usa dados do visitante — e, quando há algo a corrigir, o mesmo lugar mostra um alerta em vez da linha comum.

1. Copie o segredo do chat

Cada chat tem o seu próprio segredo. Rotacionar o do aplicativo não derruba o do site institucional, então dá para tratar cada lugar de forma independente.

Clique no olho para revelar e em Copiar. Guarde o valor no servidor do seu site, num arquivo de variáveis de ambiente (.env). Nunca coloque o segredo no HTML, no JavaScript da página ou em qualquer lugar que o visitante consiga abrir: quem tem o segredo consegue forjar qualquer identidade.

Se ele vazar, o link Gerar um novo segredo troca a chave na hora. As assinaturas antigas param de valer até você atualizar o valor no seu servidor.

Quem pode ver o segredo. Só quem tem permissão de gerenciar canais. Para quem só visualiza, os passos aparecem sem o valor — ver a configuração é uma coisa, poder assinar identidades é outra. A mesma régua vale fora da tela: pela API (e por um assistente conectado via MCP) o segredo só vem para credenciais com essa permissão no escopo, em GET /chat-channels.

2. Gere a assinatura no seu backend

Para o usuário que você já autenticou, monte os dados dele e assine com o segredo, usando HMAC-SHA256. São duas variáveis: auth (os dados em base64) e sig (a assinatura).

PHP / Laravel

$secret = env('CHAT_WIDGET_SECRET'); // copie da tela → seu .env
$payload = ['user_ref' => (string) $user->id, 'email' => $user->email, 'name' => $user->name];

$auth = base64_encode(json_encode($payload));
$sig = hash_hmac('sha256', $auth, $secret);

Node.js

const crypto = require('crypto')
const secret = process.env.CHAT_WIDGET_SECRET // copie da tela → seu .env
const payload = JSON.stringify({ user_ref: String(user.id), email: user.email, name: user.name })

const auth = Buffer.from(payload).toString('base64')
const sig = crypto.createHmac('sha256', secret).update(auth).digest('hex')

Python

import base64, hmac, hashlib, json, os
secret = os.environ["CHAT_WIDGET_SECRET"].encode() # copie da tela → seu .env
payload = json.dumps({"user_ref": str(user.id), "email": user.email, "name": user.name}).encode()

auth = base64.b64encode(payload).decode()
sig = hmac.new(secret, auth.encode(), hashlib.sha256).hexdigest()

O ponto que importa: esse código roda no servidor, para cada usuário logado. Se ele rodar no navegador, o segredo vai junto e a verificação perde o sentido.

Mande sempre o user_ref

O user_ref é o id da pessoa no seu sistema. Ele é opcional, mas mandar faz diferença em tudo que precisa reconhecer a mesma pessoa em momentos diferentes: os modelos que ela salva no chat, o histórico de conversas, o vínculo com o WhatsApp e, quando você usa Subcontas, o repasse de créditos e o limite mensal por pessoa (que só é inviolável com a assinatura, porque no token simples o user_ref vai em claro).

Sem ele o chat se vira pelo e-mail, e o e-mail tem dois problemas conhecidos. Ele muda (a pessoa troca de endereço, a empresa migra de domínio) e a pessoa perde o que salvou. E ele é compartilhado: um contato@empresa.com.br costuma ser três pessoas, e as três passam a se enxergar como a mesma.

É a mesma recomendação que as outras plataformas de atendimento fazem, e vale mesmo que hoje você use só o e-mail: quando você começar a mandar o user_ref, o que a pessoa já tinha salvo é transferido para ele automaticamente, sem ninguém perder nada.

Use um id que não muda: a chave primária do usuário no seu banco serve bem. Não use o e-mail nesse campo.

O que cabe no payload assinado

Estes são todos os campos que a assinatura carrega. O que não estiver aqui é ignorado — e nada além disso é lido como identidade.

CampoO que éPara que serve
user_refO id da pessoa no seu sistemaReconhece a mesma pessoa em momentos e aparelhos diferentes. Mande sempre.
emailE-mail da pessoaVira cadastro confiável e chega às ações do agente como identidade provada.
nameNome da pessoaAparece para o atendente e nas variáveis do fluxo.
company_refO id da empresa dela no seu sistemaAgrupa todo mundo daquela empresa no mesmo cliente. Depende do campo Origem desses ids.
subaccount_refA referência externa da subcontaAmarra a conversa à subconta certa, para o consumo de IA ser cobrado dela. Só use se você usa Subcontas.

Dois avisos que evitam retrabalho:

  • company_ref e subaccount_ref são coisas diferentes e não se substituem. O primeiro organiza o seu cadastro de clientes; o segundo é o que amarra a cobrança de IA. Quem usa Subcontas quase sempre manda os dois.
  • subaccount_ref precisa bater com a referência externa que a subconta já tem cadastrada. Se não houver subconta com aquela referência, a conversa segue sem vínculo — não é criada uma subconta nova.

3. Coloque a assinatura no widget

O seu servidor injeta os dois valores prontos no código de instalação, em data-auth e data-sig:

<script src="https://SEU-APP/widget/chat.js"
data-key="a-chave-do-seu-chat"
data-auth="<?= $auth ?>"
data-sig="<?= $sig ?>"></script>

Para o visitante que não está logado, é só não enviar data-auth e data-sig. A conversa acontece normalmente, apenas sem identidade confirmada.

4. Teste a assinatura

Rode o código do passo 2 e cole na tela o auth e o sig que ele gerou. A validação é na hora e diz qual visitante foi reconhecido. Se der errado, a tela explica o motivo em vez de só recusar.

Passou, o chat ganha o selo Verificação de identidade validada, com a data. Esse selo é o que libera o passo 5.

O mesmo teste existe por API, sem abrir o painel — útil no terminal, num script de CI, ou para uma IA de programação validar o próprio código durante a integração:

curl -X POST https://SUA-API/api/v1/public/chat/verify-identity \
-H "Content-Type: application/json" \
-d '{"key": "a-chave-do-seu-chat", "auth": "...", "sig": "..."}'

A resposta traz valid: true com a identidade reconhecida, ou valid: false com o motivo (assinatura que não confere, base64 inválido). Passou por aqui, o selo é carimbado do mesmo jeito que no teste da tela.

E se quem vai integrar é uma IA, comece pelo guia pronto que fica junto do código de instalação (o botão “Copiar guia”): ele já sai com a chave, os endereços e este teste preenchidos, e inclui a lista do que a IA não deve inventar.

5. Exija a assinatura

Com a exigência ligada, e-mail sem assinatura deixa de virar cadastro. A conversa continua acontecendo, só fica anônima. É o que impede alguém de digitar o e-mail de um cliente real e herdar o cadastro dele, e o que evita que um chat falso encha a sua base.

A trava só fica disponível depois que a assinatura foi validada no passo 4. É proteção contra o tiro no pé: ligada antes, nada passaria e você se cortaria do seu próprio cadastro. Ela vale também para o formulário de recado, que não é assinado.

Agrupar as pessoas por empresa

Se o seu sistema tem empresas com vários usuários, assine também um company_ref no passo 2, com o id da empresa lá do seu lado. Todo mundo daquela empresa cai no mesmo cliente aqui, mesmo quem usa e-mail pessoal, que o agrupamento por domínio nunca alcançaria.

Falta dizer de qual sistema esses ids vieram. Isso é configuração, no campo Origem desses ids, e nunca viaja no payload assinado: se viajasse, um integrador poderia se declarar de outra origem e ler cadastro alheio. Use o mesmo valor com que essas empresas foram cadastradas aqui, por importação ou por API. Em branco, o company_ref é ignorado. Empresa que ainda não existe na plataforma não é criada.

O que muda depois

Sempre que uma ação do agente de IA recebe a identidade do visitante, a plataforma anexa junto um campo verified, com true ou false. A regra de ouro da sua API é simples: só devolva dados privados quando vier true. Assim um e-mail forjado, que chega sem assinatura, nunca abre os dados de outra pessoa.

Nos fluxos, a mesma informação aparece como a variável visitor.verified. Dá para desenhar um caminho que só segue para a consulta de dados quando a identidade está confirmada, e manda o resto para uma triagem comum.

Limites e regras

  • Rotação não tem convivência: gerou um segredo novo, o antigo para de valer na hora e o selo de validação zera. Para trocar sem derrubar quem está logado, crie um segundo chat (o segredo é por chat), valide nele e só então mude o site.
  • A exigência de assinatura só liga depois da validação — é proteção contra o tiro no pé.
  • Falhar ao assinar não recusa ninguém: se o seu servidor não gerar o par a tempo, a pessoa conversa como anônima. O que ela perde são as respostas que dependem de dado privado.
  • Assinatura é por chat, não por marca nem por conta. Cada chat tem o seu segredo, e é isso que permite tratar site institucional e área logada de formas diferentes.
  • O payload é lido inteiro, mas só os campos da tabela acima têm efeito. Campo desconhecido é ignorado, não dá erro.

Dúvidas frequentes

Preciso disso para usar o chat? Não. O chat funciona sem nada disso. A verificação só é necessária quando alguma resposta depende de dados privados da pessoa, ou quando você quer que a identidade recebida vire cadastro confiável.

E se eu enviar só data-name e data-email, sem assinar? Funciona, e o atendente vê os dados. Eles valem como texto informado, não como identidade provada, então não devem liberar nada sensível.

O segredo é o mesmo da chave do chat? Não. A chave (data-key) é pública e fica no HTML. O segredo é privado e nunca sai do seu servidor.

Tenho mais de um chat. Preciso repetir tudo? Sim, uma vez por chat, porque o segredo é por chat. É o que permite rotacionar um sem derrubar os outros.