Vérification d’identité

Vérifiez qui discute en signant un JWT pour vos utilisateurs connectés. Agentkit vérifie le token et associe la conversation à un Contact.

La vérification d’identité vous permet d’indiquer à Agentkit qui est en train de discuter. Votre backend signe un JWT de courte durée pour l’utilisateur connecté, le widget transmet ce token à Agentkit, qui le vérifie et associe la conversation à un Contact.

Il s’agit d’enrichissement et de protection contre l’usurpation, jamais d’un contrôle d’accès. Un token manquant, expiré ou invalide signifie simplement que le visiteur discute de façon anonyme — le chat n’est jamais bloqué.

Remarque : les tokens d’identité contiennent des données utilisateur privées. Signez-les toujours sur votre serveur, jamais en JavaScript côté client — les signer dans le navigateur exposerait votre secret.

Fonctionnement

  1. Un utilisateur se connecte à votre application.
  2. Votre backend génère un JWT de courte durée, signé avec le secret d’identité de votre chatbot.
  3. Vous transmettez le token au widget (avant son chargement, ou au moment de l’exécution).
  4. Le widget envoie le token à chaque requête de chat.
  5. Agentkit vérifie la signature et les revendications, puis crée ou met à jour un Contact identifié par le sujet du token, et associe la conversation à ce Contact.

Activer la vérification

  1. Ouvrez votre agent et accédez à Paramètres → Identité.
  2. Activez Vérifier les visiteurs connectés (JWT).
  3. Copiez le Secret de signature.

Le secret de signature est réservé au serveur : conservez-le dans une variable d’environnement et ne l’exposez jamais dans le code client. Régénérer le secret invalide immédiatement tous les tokens signés avec l’ancien.

Spécification du token

Signez le token avec l’algorithme HS256. Les autres algorithmes (y compris alg: none et les clés asymétriques) sont rejetés.

Revendications

RevendicationObligatoireRemarques
sub (ou user_id)OuiID utilisateur immuable de votre application. Utilisez un identifiant interne stable — jamais un e-mail, un nom d’utilisateur ou un ID Agentkit. Si sub et user_id sont tous les deux présents, ils doivent correspondre.
expOuiHeure d’expiration. Utilisez des tokens de courte durée (~1 heure). Les tokens dont exp dépasse 24 heures dans le futur sont rejetés.
audRecommandéLie le token à cet agent : agentkit:chatbot:{chatbotId}. S’il est présent, il doit correspondre.
emailNonStocké sur le Contact.
nameNonStocké sur le Contact.
phonenumberNonStocké dans le champ phone du Contact.
custom_attributesNonObjet pour toute donnée supplémentaire (forfait, entreprise, ID Stripe, …).

Seuls email, name, phonenumber et custom_attributes sont lus depuis le token. Toute autre revendication de premier niveau est ignorée — placez les données supplémentaires ou d’intégration dans custom_attributes.

Limites

  • email, name, phonenumber : jusqu’à 1 024 caractères chacun.
  • custom_attributes : jusqu’à 8 192 octets, 50 clés et 5 niveaux d’imbrication.

Un token qui dépasse ces limites est vérifié comme anonyme (l’échec est journalisé) plutôt que de bloquer le chat.

Signer le token

N’importe quelle bibliothèque JWT fonctionne (jsonwebtoken, PyJWT, …) — il vous faut simplement un token HS256 avec les revendications ci-dessus. Cet exemple utilise jose, qui fonctionne aussi sur des runtimes edge (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);

Le même extrait, pré-rempli avec l’audience de votre agent, est affiché sur la page Paramètres → Identité.

# 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",
)

Transmettre le token au widget

Définissez le token avant le chargement du script du widget (par exemple, injectez-le côté serveur dans la page) :

<script>
  window.agentkitUserConfig = { token: 'YOUR_SIGNED_TOKEN' };
</script>

Dans les applications monopages, mettez à jour ou effacez l’identité à l’exécution — par exemple après une connexion ou une déconnexion :

// After the user logs in (or the token is refreshed):
window.agentkit('identify', { token: newToken });

// After the user logs out:
window.agentkit('resetUser');

Le widget attache automatiquement le token à chaque requête de chat ; vous n’avez besoin de définir aucun en-tête vous-même.

Confidentialité

Les champs de profil vérifiés (email, name, phonenumber, custom_attributes) sont stockés sur le Contact côté serveur uniquement. Ils ne sont jamais injectés dans le prompt de l’agent ni dans le contexte RAG, et ne sont jamais renvoyés par un point de terminaison public. L’agent ne « voit » pas à qui il parle.

Comportement de la vérification

La vérification ne bloque jamais un chat. Le visiteur peut toujours discuter avec l’agent ; la seule différence est de savoir si un Contact est associé.

SituationRésultat
Aucun tokenVisiteur anonyme. Aucun Contact associé. (Ce n’est pas une erreur.)
Token valideVérifié. Contact créé/mis à jour et associé à la conversation.
Signature invalide / token malforméAnonyme. Échec journalisé.
Token expiréAnonyme. Échec journalisé.
aud ne correspond pas à cet agentAnonyme. Échec journalisé.
Revendications de profil dépassant les limitesAnonyme. Échec journalisé.

Les autres contrôles d’accès s’appliquent toujours

La vérification d’identité est indépendante de qui peut charger le widget. Les restrictions de domaine et les paramètres de visibilité continuent de s’appliquer séparément.

Étapes suivantes