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

  1. Um usuário faz login no seu aplicativo.
  2. Seu backend gera um JWT de curta duração, assinado com o segredo de identidade do seu chatbot.
  3. Você entrega o token ao widget (antes de ele carregar, ou em tempo de execução).
  4. O widget envia o token em cada solicitação de chat.
  5. 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

  1. Abra seu agente e vá em Configurações → Identity.
  2. Ative Verificar visitantes autenticados (JWT).
  3. 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

ClaimObrigatórioObservações
sub (ou user_id)SimO 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.
expSimHorá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.
audRecomendadoVincule o token a este agente: agentkit:chatbot:{chatbotId}. Se presente, deve corresponder.
emailNãoArmazenado no Contato.
nameNãoArmazenado no Contato.
phonenumberNãoArmazenado no campo phone do Contato.
custom_attributesNãoObjeto 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çãoResultado
Nenhum tokenVisitante anônimo. Nenhum Contato vinculado. (Não é um erro.)
Token válidoVerificado. Contato criado/atualizado e vinculado à conversa.
Assinatura inválida / token malformadoAnônimo. Falha registrada.
Token expiradoAnônimo. Falha registrada.
aud não corresponde a este agenteAnônimo. Falha registrada.
Claims de perfil excedem os limitesAnô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.

Próximos Passos