Back to all posts

Le courtier détient vos clés. Pas votre agent IA.

Un petit robot se tient devant un comptoir de courtier lustré ; derrière une grille métallique, des clés étiquetées (Slack, GitHub, Notion, Gmail) sont accrochées à des crochets. Le robot glisse un bordereau papier par le guichet, dans une transaction calme et polie.

La sécurité des agents IA commence par une règle : votre agent IA ne devrait jamais détenir vos identifiants. Voici le modèle du courtier, vieux de 38 ans, qui l'impose.

Les agents IA sont des adjoints confus. C'est un modèle de sécurité vieux de 38 ans, et la réponse est tout aussi ancienne : placez un courtier — une couche intermédiaire de confiance, observable, déterministe, auditable, infalsifiable, à portée réduite, pilotée par des politiques et non-IA — entre l'agent et les API SaaS qu'il doit appeler, et faites-lui détenir les identifiants que votre agent ne devrait pas avoir.

En 1988, Norm Hardy a publié un court article décrivant un incident réel survenu à l'époque où il travaillait chez Tymshare. Un compilateur Fortran nommé FORT vivait dans un répertoire système appelé SYSX. Pour collecter des statistiques d'usage, le compilateur devait écrire dans (SYSX)STAT ; le système d'exploitation lui avait donc accordé une « licence de fichiers maison », l'autorisant à écrire n'importe quel fichier dans SYSX. Le fichier de facturation du système, (SYSX)BILL, s'y trouvait aussi. Un utilisateur invoquant le compilateur pouvait indiquer un nom de fichier destiné à recevoir une sortie de débogage facultative. Un jour, un utilisateur a indiqué (SYSX)BILL. Le compilateur a demandé au système d'ouvrir ce fichier en écriture ; le système, constatant la licence de fichiers maison, l'a autorisé. Les données de facturation ont été écrasées. Le compilateur a fait exactement ce pour quoi il avait été conçu. La faille était architecturale.

Hardy a nommé cela le problème de l'adjoint confus : un programme privilégié (l'adjoint) détient sa propre autorité ; un appelant moins privilégié lui demande de faire quelque chose ; l'adjoint se trompe sur l'autorité au nom de laquelle il agit et utilise la sienne. La correction consiste à retirer entièrement cette autorité à l'adjoint et à la placer derrière une couche distincte qui arbitre l'appel à la demande. Cette couche, c'est le courtier.

Trente-huit ans plus tard, chaque agent IA que votre entreprise fait tourner est un adjoint confus. Et la plupart tournent sans courtier.

Pourquoi les agents IA aggravent le problème de sécurité

Le FORT de Hardy avait un seul canal d'entrée : la ligne de commande. Un agent IA moderne en a des dizaines : corps d'e-mails, pages web récupérées, PDF téléversés, sorties d'outils de serveurs MCP, messages d'agents pairs dans un système multi-agents. Tout ce qui atterrit dans la fenêtre de contexte peut émettre des instructions, et par conception l'agent les traite toutes comme légitimes.

Cela brise une hypothèse dont dépend le contrôle d'accès traditionnel : l'appelant contrôle l'entrée. Dans une application web, l'appelant (la session authentifiée) et l'entrée (le corps de la requête HTTP) viennent du même endroit. Pour un agent, l'appelant est quiconque façonne le prompt, ce qui signifie qu'un attaquant capable d'écrire un e-mail ou de semer un résultat de recherche est lui aussi un appelant.

En novembre 2025, les chercheurs en sécurité de PromptArmor ont montré à quoi cela ressemble en production. Ils ont dissimulé des instructions malveillantes en police d'un pixel dans un guide d'intégration. Lorsqu'un développeur y a pointé l'IDE Antigravity de Google, l'agent a contourné sa propre protection de fichiers basée sur .gitignore en passant par un cat en ligne de commande. Puis il a divulgué le contenu de fichiers .env vers une URL webhook.site contrôlée par l'attaquant, via le sous-agent navigateur d'Antigravity lui-même. L'utilisateur avait tout configuré correctement. Le sandbox a tenu. L'agent était simplement incapable de distinguer ce que l'utilisateur avait demandé de ce que l'entrée lui disait de faire.

Même forme que le FORT de Hardy, des décennies plus tard : autorité large, entrée non fiable, aucun moyen de séparer les deux.

La communauté a des réponses. Elles sont juste éparpillées.

Ce n'est pas un problème nouveau. La communauté sécurité écrit des réponses depuis des décennies :

La sécurité par capacités (Dennis & Van Horn, 1966 ; plus tard le langage E et les travaux de Mark Miller sur Caja chez Google). Le principe : n'accordez pas d'autorité ambiante fondée sur l'identité ou l'emplacement ; transmettez des capacités explicites et infalsifiables pour chaque ressource que le programme a le droit de toucher. Une capacité associe ce que vous pouvez faire à ce sur quoi vous pouvez le faire, et elle ne peut être confondue avec rien d'autre.

Les identifiants intermédiés (codifiés par l'OWASP LLM Top 10). Ne mettez pas de jetons d'API dans le contexte du LLM. Une couche intermédiaire de confiance effectue l'appel pour le compte de l'agent ; le modèle décide quoi faire, le courtier gère comment. Une injection de prompt qui demande au modèle d'afficher ses identifiants n'obtient rien d'utile. Les identifiants n'y sont pas.

Le modèle du jeton fantôme (Curity, à l'origine pour OAuth dans les microservices). L'agent détient une poignée de session opaque, pas le véritable jeton porteur. Un proxy valide la poignée, substitue le véritable identifiant à la frontière réseau et transmet en amont. Si l'agent divulgue son environnement, l'attaquant récupère une chaîne qui expire à la fin de la session.

L'injection d'identifiants juste-à-temps (systèmes d'identité de charge de travail comme Aembit). Émettre un identifiant à durée de vie courte et à portée réduite pour chaque appel plutôt que de délivrer des jetons durables.

Rien de tout cela ne manque à la littérature. Cela manque aux valeurs par défaut. La plupart des plateformes d'agents remettent encore un jeton OAuth au modèle, sans courtier au milieu, en espérant que tout se passe bien.

Comment fonctionne le courtier de Zero

Nous n'avons inventé aucun des modèles ci-dessus. Nous les avons câblés dans un courtier unique qui tourne par défaut pour chaque agent sur Zero. C'est la couche intermédiaire de confiance que décrivent ces modèles, conçue pour une plateforme d'agents IA. Chaque appel qu'un agent adresse à un connecteur passe par lui. Chaque connecteur correspond à un SaaS externe (Slack, GitHub, Notion, etc.).

Architecture du courtier : l'agent dans une microVM Firecracker à gauche, le courtier au milieu (montrant l'isolation des identifiants, la barrière de politique des connecteurs et une boucle opérationnelle avec audit), relié aux API SaaS à droite. Une ligne pointillée de frontière des jetons indique que les véritables identifiants ne passent jamais du courtier à l'agent. Le courtier se place entre chaque agent et chaque connecteur. Les véritables identifiants vivent uniquement du côté courtier de la ligne pointillée.

Voyez-le comme trois couches.

1. Isolation des identifiants

Le sandbox de l'agent ne détient jamais de véritable identifiant de connecteur. Quand vous connectez un SaaS à Zero, le jeton OAuth ou la clé d'API vit du côté courtier. Le sandbox reçoit une chaîne fictive, suffisamment proche d'un secret d'environnement pour que les outils existants continuent de fonctionner, mais qu'aucun SaaS en amont n'accepterait.

Quand l'agent adresse une requête à un hôte de connecteur enregistré, le courtier fait correspondre la requête, résout le modèle d'authentification du connecteur et injecte le véritable identifiant à la frontière réseau. La requête part en amont avec une authentification valide ; l'agent n'a jamais rien détenu d'utile. Un agent victime d'injection de prompt qui vide ses variables d'environnement remet à l'attaquant une valeur fictive, pas le jeton SaaS.

C'est le modèle du jeton fantôme, appliqué aux agents IA.

2. Barrière de politique des connecteurs

Un connecteur dans Zero doit être plus qu'un interrupteur marche/arrêt. Chaque connecteur décrit les bases d'API qu'il couvre et la manière dont l'authentification doit être injectée. Là où le service en amont publie une correspondance stable entre portées et points de terminaison, il peut aussi décrire quelle permission nommée couvre chaque méthode et chaque chemin. La slack-api-ref de Slack en est un bon exemple.

Ainsi, quand un agent connecté à Slack appelle chat.postMessage, le courtier peut associer cette requête à chat:write. Quand il lit des journaux d'audit, c'est admin.analytics:read. Pour chaque agent, permission_policies définit le comportement de ces permissions nommées : autoriser, refuser ou demander. La politique est appliquée au niveau du courtier avant l'injection d'authentification, et non comme une suggestion faite au modèle. Si l'agent tente un appel couvert par une permission refusée, peut-être parce qu'il a subi une injection de prompt, l'appel n'atteint jamais le réseau en amont.

Tous les connecteurs n'atteignent pas cette résolution aujourd'hui. Certaines API en amont ne publient pas de correspondance stable entre portées et points de terminaison. La surface GraphQL de GitHub en est le cas canonique : le côté REST peut être cartographié, le côté GraphQL pas encore. Pour ces connecteurs, le courtier contrôle toujours l'injection d'identifiants et le chemin réseau, tandis que la barrière de permissions retombe sur la politique plus grossière, au niveau du connecteur ou de l'hôte, que la plateforme peut réellement appliquer. Nous complétons ces éléments à mesure que les données en amont deviennent disponibles. Nous ne revendiquons pas une couverture que nous n'avons pas construite.

Les jetons ne portent pas d'autorité ambiante. L'autorité est intermédiée par agent, à la résolution que l'amont permet. C'est la moitié « capacités » de la réponse.

3. Boucle opérationnelle et audit

Le moindre privilège ne fonctionne que si le mode de défaillance est utilisable. Les agents évoluent. Au bout de six semaines, un agent de recherche qui commençait par lire dans Notion peut avoir besoin d'y réécrire un résumé. Les modes de défaillance courants ailleurs : l'agent tourne silencieusement sans la nouvelle permission et casse, ou l'opérateur sur-attribue dans la panique et ne revient jamais en arrière.

Une requête de connecteur refusée renvoie un 403 structuré : connecteur, méthode, chemin, URL de base, et les noms de permissions correspondants quand le courtier peut les identifier. Le prompt système de l'agent lui indique comment diagnostiquer le refus et comment demander exactement la permission qu'il vient de heurter, en produisant une URL d'attribution en un clic pour l'utilisateur ou l'administrateur. Cela maintient le chemin d'escalade rattaché à la permission précise demandée au lieu de virer au « accordez tout ».

Les demandes de changement de permission sont mises en file d'attente. Les propriétaires et les administrateurs peuvent les approuver ou les rejeter depuis le tableau de bord ; les demandes approuvées mettent à jour la politique de l'agent, et la tentative suivante passe. La plupart des plateformes sautent cette boucle. Sans elle, le « moindre privilège » reste sur le slide au lieu de tourner en production.

Ce même chemin de courtage alimente l'audit. Les journaux réseau par exécution enregistrent l'activité réseau du sandbox en HTTP, TCP, DNS et à travers des observations de paquets de plus bas niveau pour le trafic non-TCP. Les requêtes rattachées à un connecteur comportent des métadonnées structurées du courtier : connecteur, permission correspondante quand elle existe, issue autoriser/refuser, métadonnées de résolution d'authentification et indicateur de facturation. Si quelqu'un demande plus tard « qu'a fait cet agent mardi à 15 h ? », vous reconstruisez la réponse à partir de ces enregistrements. La prévention laisse passer des choses. La piste d'audit, c'est ce qui vous permet de savoir lesquelles.

Ce que nous n'avons pas résolu

Même avec tout ce qui précède, un agent disposant légitimement de chat:write peut toujours être amené à publier un message embarrassant dans un canal auquel il a déjà accès. Le courtier réduit le rayon de l'explosion ; il ne l'élimine pas.

L'autre moitié de la réponse, c'est l'approbation des actions à fort enjeu, la validation des sorties et le fait de traiter par défaut les retours d'outils comme non fiables. Ce travail est sur la roadmap, pas encore dans le produit. Quiconque prétend avoir résolu l'adjoint confus de bout en bout est en train de vous vendre quelque chose.

Ce devrait être le plancher, pas une fonctionnalité

La sécurité par capacités existe depuis les années 1970. Les identifiants intermédiés figurent dans l'OWASP LLM Top 10. Les jetons fantômes précèdent l'ère des LLM. Rien de tout cela ne manque parce que personne ne connaissait la réponse. Cela manque parce que les premières plateformes d'agents ont optimisé pour « faire marcher la démo » et repoussé la sécurité à une release ultérieure, qui souvent n'est jamais venue.

La prochaine génération de plateformes devrait viser plus haut. Les jetons ne devraient pas entrer dans le contexte du modèle. L'autorité devrait être énumérée par agent. L'élévation de privilège devrait passer par un humain. Chaque action devrait être auditable de bout en bout. Rien de tout cela n'est nouveau. Tout cela devrait être la base.

Quand vous choisissez une plateforme d'agents, « est-ce sécurisé ? » ne vous mène nulle part. Tous les fournisseurs répondent oui. Une meilleure question : montrez-moi votre courtier, et expliquez-moi ce qui se passe quand un agent demande une portée dont il ne dispose pas.


Le courtier se place devant chaque agent sur Zero, par défaut. L'inventaire des connecteurs, les correspondances de portées, les politiques de permissions et la logique du courtier vivent tous dans le dépôt source de Zero. Vous avez trouvé un connecteur que nous n'avons pas couvert ? Ouvrez une issue.


Références

Fondations

  • Norm Hardy, The Confused Deputy: (or why capabilities might have been invented), ACM SIGOPS Operating Systems Review 22(4), 1988. DOI 10.1145/54289.871709
  • Dennis & Van Horn, Programming Semantics for Multiprogrammed Computations, CACM 1966 (l'article fondateur des systèmes à capacités)
  • Mark Miller et al., Caja : sécurité par capacités pour le web, Google
  • OWASP LLM Top 10
  • Curity, Phantom Token Pattern

Incidents réels cités

Stay in the loop

// Get the latest insights on AI teammates and collaboration.

SubscribeJoin Discord