Bien déléguer : le Token Exchange et le pattern On-Behalf-Of
Cet article fait partie de la série Les défis d’authentification et d’autorisation de l’IA agentique. Il s’appuie sur Identité de l’agent : pourquoi votre agent IA doit être un principal à part entière.
Une fois qu’un agent existe comme son propre principal, il doit encore prouver quelque chose à chaque ressource qu’il touche : qu’il agit pour un utilisateur précis, avec un scope précis, maintenant — et non qu’il présente simplement le credential qui traînait à portée de main. C’est la faille de délégation, et elle mérite d’être prise au sérieux, car les raccourcis pris ici sont exactement ceux qui finissent en post-mortem d’incident.
Le scénario, et les trois façons de mal s’y prendre
Un agent doit lire le calendrier d’un utilisateur pour planifier une réunion, ou récupérer une fiche client depuis une API CRM interne pour le compte de l’utilisateur. Il y a une vraie décision de permission enfouie dans cette phrase — l’agent devrait pouvoir faire cette action précise, pour cet utilisateur précis, et rien de plus large — mais trois raccourcis courants jettent cette précision à la poubelle :
Stocker le credential réel et longue durée de l’utilisateur. L’agent (ou quelque chose en amont) capture le mot de passe, le cookie de session ou le refresh token longue durée de l’utilisateur et le conserve pour effectuer de futurs appels sans redemander à l’utilisateur. C’est la pire version : un secret statique à haute valeur repose désormais dans le stockage utilisé par l’agent, avec la posture de sécurité de l’agent comme seul rempart entre ce secret et un rayon d’impact bien plus large que ce qu’« une session d’un utilisateur » n’était censée représenter.
Le token pass-through. L’agent reçoit un token — le sien, ou celui de l’utilisateur — et le transmet tel quel à une API en aval sans l’échanger contre quelque chose de plus restreint. Cela paraît inoffensif car rien n’a été stocké, mais cela signifie que chaque service en aval auquel l’agent parle fait désormais confiance à un token qui a été émis pour une audience différente, souvent avec un scope plus large que ce que l’appel précis nécessite, et sans aucune trace qu’un agent — par opposition au client d’origine — était réellement celui qui le présentait.
La ré-authentification constante. L’échec inverse : redemander à l’utilisateur de se reconnecter pour chaque nouvel appel en aval dont l’agent a besoin. Cela « résout » le problème du credential en rendant la délégation impossible en pratique — personne ne se ré-authentifie dix fois pour laisser un agent terminer une tâche, donc les équipes abandonnent la fonctionnalité, ou plus souvent, retombent discrètement sur l’un des deux premiers raccourcis.
Le pattern : le token exchange
Le Token Exchange d’OAuth 2.0 (RFC 8693) existe précisément pour cette forme de problème : un client détient un token et a besoin d’un token différent — plus restreint en scope, destiné à une audience différente, ou reflétant une relation différente entre les parties — sans faire repasser l’utilisateur par une redirection navigateur.
La mécanique, à un niveau de détail qui mérite d’être réellement compris plutôt que traité comme une boîte noire : le backend de l’agent présente un subject_token (identifiant de qui l’autorité est exercée — typiquement l’utilisateur) à un token endpoint, accompagné de ses propres identifiants qui identifient l’agent effectuant la requête. La réponse est un nouvel access token, scopé pour la ressource précise en aval, dont les claims peuvent porter à la fois le sujet (sub, l’utilisateur) et l’acteur (act, l’agent) comme champs distincts — exactement le modèle de données évoqué dans l’article précédent. Élément critique, ce nouveau token est typiquement de courte durée de vie et restreint à l’audience du seul resource server pour lequel il a été demandé, ce qui signifie que la compromission d’un service en aval ne remet pas à un attaquant un credential utilisable ailleurs dans le système.

L’autre brique associée ici est le grant JWT Bearer défini dans la RFC 7523, qui s’inscrit dans le cadre plus large des assertions défini par la RFC 7521 : il définit comment une assertion — un JWT signé qui atteste de qui est impliqué — est échangée contre un access token auprès d’un authorization server. Le token exchange et les assertions JWT bearer résolvent des problèmes adjacents et sont fréquemment combinés : l’un émet ou échange le token, l’autre définit le format et les règles de validation de l’assertion qui sert de caution.
L’effet pratique d’une implémentation correcte : l’agent ne détient jamais le credential réel et longue durée de l’utilisateur pour le service en aval. Il détient le sien propre, plus restreint, de courte durée de vie, redemandé à chaque fois que nécessaire, échangé à neuf contre la ressource précise appelée. Si ce token fuite, le rayon d’impact se limite à un scope, contre une ressource, pour une fenêtre limitée — pas l’intégralité du compte de l’utilisateur.
Réduire le scope à chaque saut, pas seulement au premier
L’erreur qui subsiste même après qu’une équipe a adopté le token exchange pour le premier saut : traiter le token échangé comme suffisant pour tout ce qui suit, plutôt que de le rescoper à chaque saut suivant. Si la tâche d’un agent implique d’appeler l’API A, qui doit ensuite appeler l’API B pour le compte du même utilisateur, le token présenté à B devrait être échangé à nouveau — réduit davantage si B a besoin de moins que ce qui a été accordé à A, et portant une chaîne d’acteurs étendue si plus d’un délégué est désormais impliqué.
C’est important car le scope a tendance à ne faire que croître si personne ne le restreint activement. Un agent qui a reçu un accès en lecture à un calendrier dans le but de vérifier une disponibilité ne devrait pas remettre ce même token à un sous-service de planification qui n’a besoin que d’écrire un seul événement — s’il le fait, et que ce sous-service est compromis, l’attaquant hérite d’un accès en lecture à tout le calendrier plutôt que d’un accès en écriture à un seul événement.
Recommandations de conception
Ne laissez jamais un agent (ou le processus qui l’héberge) devenir un stockage durable de credentials tiers longue durée. Si un refresh token, une clé API ou un credential de session pour un service externe doit persister quelque part, il doit vivre dans une infrastructure spécifiquement conçue pour stocker et faire tourner des secrets — pas dans la mémoire de travail de l’agent, son contexte de prompt, ou son historique de conversation, où il risque d’être journalisé, de ressurgir dans une réponse, ou d’être conservé bien plus longtemps que ce que la tâche précise exigeait.
Traitez « l’agent transmet son propre token partout » comme un anti-pattern, pas comme une commodité. Chaque franchissement de frontière de confiance — agent vers API interne, API interne vers un autre service interne, agent vers un agent complètement différent — est une occasion, et sans doute une obligation, d’échanger contre un token scopé à ce saut précis plutôt que de réutiliser un token émis pour un autre usage.
Adoptez par défaut des durées de vie de token courtes pour l’accès délégué, et rendez le ré-échange peu coûteux. La friction qui pousse les équipes à se rabattre sur des tokens longue durée vient généralement du fait de traiter le token exchange comme une opération coûteuse et rare. S’il est rapide et peu coûteux de ré-échanger un token avant chaque appel, il y a peu de raisons de conserver un token longue durée « au cas où ».
Préservez la chaîne d’acteurs, ne l’aplatissez pas. Lorsqu’il y a plus d’un saut de délégation — utilisateur vers agent, agent vers sous-agent, sous-agent vers API — résistez à la tentation d’aplatir la chaîne jusqu’à la seule identité de l’utilisateur d’origine par souci de simplicité. La structure d’acteurs imbriqués est ce qui permet de répondre, après coup, exactement à quel maillon de la chaîne a fait quoi ; l’aplatir échange une capacité de débogage et d’audit contre un token marginalement plus simple.
Bien gérer la délégation n’exige pas d’infrastructure exotique — la RFC 8693 et la RFC 7523 sont des standards stables et largement implémentés, et la plupart des authorization servers modernes prennent en charge le token exchange comme grant type de premier ordre. La faille se situe presque toujours dans la conception applicative : recourir au raccourci de l’accumulation de credentials parce que c’est plus rapide à construire, ou transmettre un token parce que le ré-échanger « ne devrait pas avoir d’importance ». Cela en a, et c’est ce qui fait la différence entre un agent qu’on peut scoper et auditer, et un agent qui détient de fait un passe-partout.
Prochain article de la série : Human-in-the-loop, automatisé : l’autorisation asynchrone pour les actions d’agent à fort enjeu, qui traite de ce qui se passe quand même un token correctement scopé et correctement délégué ne suffit pas — parce que l’action est suffisamment sensible pour qu’un humain doive l’approuver spécifiquement.