Verificação de Identidade
Verifique quem está conversando ao assinar um JWT para os usuários autenticados. O Agentkit verifica o token e vincula a conversa a um contato.
A verificação de identidade permite que você informe ao Agentkit quem está conversando. Seu backend assina um JWT de curta duração para o usuário logado, o widget entrega esse token ao Agentkit, e o Agentkit verifica o token e vincula a conversa a um Contato.
Isso é enriquecimento e prevenção contra falsificação, nunca um controle de acesso. Um token ausente, expirado ou inválido simplesmente significa que o visitante conversa de forma anônima — o chat nunca é bloqueado.
Observação: os tokens de identidade carregam dados privados do usuário. Sempre os assine no seu servidor, nunca em JavaScript do lado do cliente — assinar no navegador exporia seu segredo.
Como Funciona
- Um usuário faz login no seu aplicativo.
- Seu backend gera um JWT de curta duração, assinado com o segredo de identidade do seu chatbot.
- Você entrega o token ao widget (antes de ele carregar, ou em tempo de execução).
- O widget envia o token em cada solicitação de chat.
- O Agentkit verifica a assinatura e as claims, então cria ou atualiza um Contato identificado pelo subject do token e vincula a conversa a ele.
Ativando a Verificação
- Abra seu agente e vá em Configurações → Identity.
- Ative Verificar visitantes autenticados (JWT).
- Copie o Segredo de assinatura.
O signing secret é exclusivo do lado do servidor — mantenha-o em uma variável de ambiente e nunca o exponha no código do cliente. Regenerar o segredo invalida imediatamente todos os tokens assinados com o segredo anterior.
Especificação do Token
Assine o token com o algoritmo HS256. Outros algoritmos (incluindo alg: none e chaves assimétricas) são rejeitados.
Claims
| Claim | Obrigatório | Observações |
|---|---|---|
sub (ou user_id) | Sim | O id imutável de usuário do seu aplicativo. Use um id interno estável — não um e-mail, nome de usuário ou id do Agentkit. Se tanto sub quanto user_id estiverem presentes, eles devem coincidir. |
exp | Sim | Horário de expiração. Use tokens de curta duração (~1 hora). Tokens cujo exp está mais de 24 horas no futuro são rejeitados. |
aud | Recomendado | Vincule o token a este agente: agentkit:chatbot:{chatbotId}. Se presente, deve corresponder. |
email | Não | Armazenado no Contato. |
name | Não | Armazenado no Contato. |
phonenumber | Não | Armazenado no campo phone do Contato. |
custom_attributes | Não | Objeto para qualquer dado extra (plano, empresa, ids do Stripe, …). |
Apenas email, name, phonenumber e custom_attributes são lidos do token. Qualquer outra claim de nível superior é ignorada — coloque dados extras ou de integração dentro de custom_attributes.
Limites
email,name,phonenumber: até 1024 caracteres cada.custom_attributes: até 8192 bytes, 50 chaves e 5 níveis de aninhamento.
Um token que viola esses limites é verificado como anônimo (a falha é registrada) em vez de bloquear o chat.
Assinando o Token
Qualquer biblioteca JWT funciona (jsonwebtoken, PyJWT, …) — você só precisa de um token HS256 com as claims acima. Este exemplo usa jose, que também funciona em edge runtimes (Vercel Edge, Cloudflare Workers, Deno):
// On YOUR backend, mint a short-lived JWT for your logged-in user.
import { SignJWT } from 'jose';
const secret = new TextEncoder().encode(
process.env.AGENTKIT_CHATBOT_IDENTITY_SECRET,
);
const token = await new SignJWT({
// Optional private profile claims — stored on the Contact, never shown to the
// bot. ONLY these keys are read: email, name, phonenumber, custom_attributes.
// Put extra/integration data (Stripe ids, plan, company, …) in custom_attributes.
email: user.email,
name: user.name,
phonenumber: user.phone, // maps to the Contact's "phone"
custom_attributes: {
plan: user.plan,
stripe_id: user.stripeCustomerId,
},
})
.setProtectedHeader({ alg: 'HS256' })
.setSubject(user.id) // immutable id from YOUR system (not email/username)
.setIssuedAt()
.setExpirationTime('1h') // short-lived; this is a browser bearer token
.setAudience('agentkit:chatbot:YOUR_CHATBOT_ID')
.sign(secret);
O mesmo trecho, pré-preenchido com a audience do seu agente, é exibido na página Configurações → Identity.
# Python example using PyJWT
import jwt, os, time
token = jwt.encode(
{
"sub": user.id,
"email": user.email,
"name": user.name,
"phonenumber": user.phone,
"custom_attributes": {"plan": user.plan},
"aud": "agentkit:chatbot:YOUR_CHATBOT_ID",
"iat": int(time.time()),
"exp": int(time.time()) + 3600,
},
os.environ["AGENTKIT_CHATBOT_IDENTITY_SECRET"],
algorithm="HS256",
)
Passando o Token para o Widget
Defina o token antes de o script do widget carregar (por exemplo, injete-o no lado do servidor na página):
<script>
window.agentkitUserConfig = { token: 'YOUR_SIGNED_TOKEN' };
</script>
Em aplicativos de página única, atualize ou limpe a identidade em tempo de execução — por exemplo, depois de um login ou logout:
// After the user logs in (or the token is refreshed):
window.agentkit('identify', { token: newToken });
// After the user logs out:
window.agentkit('resetUser');
O widget anexa o token a cada solicitação de chat automaticamente; você não precisa definir nenhum cabeçalho manualmente.
Privacidade
Os campos de perfil verificados (email, name, phonenumber, custom_attributes) são armazenados no Contato exclusivamente no lado do servidor. Eles nunca são injetados no prompt do agente ou no contexto RAG, e nunca são retornados por nenhum endpoint público. O agente não "vê" com quem está falando.
Comportamento da Verificação
A verificação nunca bloqueia um chat. O visitante sempre consegue conversar com o agente; a única diferença é se um Contato é vinculado ou não.
| Situação | Resultado |
|---|---|
| Nenhum token | Visitante anônimo. Nenhum Contato vinculado. (Não é um erro.) |
| Token válido | Verificado. Contato criado/atualizado e vinculado à conversa. |
| Assinatura inválida / token malformado | Anônimo. Falha registrada. |
| Token expirado | Anônimo. Falha registrada. |
aud não corresponde a este agente | Anônimo. Falha registrada. |
| Claims de perfil excedem os limites | Anônimo. Falha registrada. |
Outros Controles de Acesso Ainda se Aplicam
A verificação de identidade é independente de quem pode carregar o widget. As configurações de restrições de domínio e visibilidade continuam se aplicando separadamente.