# Accès API des agents IA : jetons directs ou actions médiées ?

Un agent de programmation IA ne devrait pas recevoir un jeton SaaS général simplement parce qu’il doit appeler une API. Transmettre directement un jeton fait du processus de l’agent un détenteur d’identifiants, avec toutes les voies habituelles de fuite : une commande verbeuse, un processus enfant, un paquet de diagnostic téléversé, le résultat d’un outil ou une instruction demandant à l’agent d’afficher sa configuration.

Cela ne signifie pas que chaque appel API doit devenir une cérémonie. Il faut séparer **l’autorité d’effectuer une action** de **la possession de l’identifiant qui l’autorise**. Donnez à l’agent un moyen limité de demander un travail utile, gardez l’identifiant auprès du composant qui l’exécute et faites intervenir une personne lorsque les conséquences le justifient.

Cette distinction se brouille parce qu’une commande curl réussie semble inoffensive. Le problème commence lorsque l’agent peut créer un déploiement en production, fermer un ticket client, modifier une issue ou exécuter une commande distante. À ce stade, un jeton n’est plus un détail de configuration. C’est une autorité opérationnelle sans jugement associé.

## La transmission directe du jeton fait de l’agent une frontière d’identifiants

Lorsque vous placez `SAAS_TOKEN` dans l’environnement d’un agent, un fichier de configuration, une définition d’outil ou un magasin de secrets accessible depuis les instructions, l’agent peut effectuer des requêtes authentifiées sans qu’un autre composant décide si chaque requête correspond à la tâche. Le jeton peut avoir des portées raisonnables, mais il devient tout de même disponible pour chaque comportement de ce processus et souvent pour les programmes qu’il lance.

Les développeurs affirment souvent que l’agent ne peut pas « voir » une variable d’environnement. Cette affirmation ne résiste pas à l’usage courant des outils. Un agent peut demander à un shell d’inspecter son environnement, appeler un script qui en hérite, lancer un outil de test avec des journaux de débogage ou écrire un instantané de configuration dans un dépôt. Le chemin d’exposition exact dépend de l’agent et de ses outils. L’hypothèse prudente est donc simple : si le processus peut utiliser directement un jeton bearer, il peut généralement provoquer son apparition à un endroit que vous n’aviez pas prévu.

Un jeton bearer a une autre propriété gênante. Le service SaaS ne peut pas distinguer l’agent prévu d’une personne qui a copié la chaîne. La spécification RFC 6750, OAuth 2.0 Bearer Token Usage, indique que les jetons bearer doivent être protégés contre toute divulgation au repos et en transit, car leur possession suffit à les utiliser. Ce n’est pas une formulation théorique. Dès qu’un agent en imprime un dans un journal de build, le service voit un appelant valide, pas une erreur.

L’accès direct brouille aussi la responsabilité. Les journaux d’audit du service peuvent identifier un compte robot, mais indiquent rarement quelle exécution de l’agent a formé la requête, quelles instructions elle a reçues, quel utilisateur l’a lancée ou si une personne a approuvé l’effet obtenu. Vous obtenez un événement API après coup, mais pas la trace de décision qui l’explique.

Un jeton direct peut être acceptable dans un bac à sable local jetable lorsque toutes les conditions suivantes sont réunies :

- Le jeton expire rapidement et possède uniquement la portée minimale, hors production.
- La cible ne contient aucune donnée client, employé ou de production.
- L’agent s’exécute dans un environnement isolé que vous pouvez supprimer.
- Une personne peut révoquer l’identifiant sans interrompre un travail partagé.

Les équipes transforment cette exception en pratique courante parce que copier un jeton est rapide. La rapidité est réelle, mais le nettoyage l’est aussi lorsque le jeton se retrouve dans un artefact ou qu’un agent suit une instruction malveillante intégrée à la description d’une issue.

## Les portées limitent les permissions, mais ne contrôlent pas l’intention

Les portées OAuth, les rôles API et les permissions de dépôt répondent à la question « que peut faire cette identité ? ». Ils ne répondent pas à la question « cette requête doit-elle avoir lieu maintenant ? ». Ce sont deux contrôles différents. Les traiter comme interchangeables laisse une grande faille.

Prenez un jeton de suivi d’issues autorisé à modifier les issues d’un projet. Cette portée peut convenir à un agent chargé de trier les bugs. Une injection d’instructions dans une issue importée peut tout de même demander à l’agent de fermer toutes les issues ouvertes, de modifier les priorités ou de publier des commentaires trompeurs. Chaque requête respecte la portée. Chaque requête reste incorrecte.

Le même problème existe avec une plateforme de déploiement. Un jeton limité à une application ne sait pas si l’agent doit déployer le commit actuel, restaurer une version, modifier une variable d’environnement ou supprimer un environnement de prévisualisation. Le service voit des appels API autorisés. Seul votre workflow peut décider si ces appels correspondent à une tâche et à une cible acceptable.

Les bonnes pratiques actuelles de sécurité OAuth 2.0 de l’IETF recommandent des jetons d’accès de courte durée, des jetons liés à l’émetteur lorsque c’est possible et des privilèges plus étroits afin de réduire les dégâts causés par les jetons bearer. Ce sont de bonnes pratiques. Elles réduisent la durée d’utilisation et la portée d’un identifiant copié. Elles n’ajoutent pas d’approbation pour une action destructive correctement limitée et n’expliquent pas l’intention de l’agent.

Ne réagissez pas en créant un immense catalogue de règles censé anticiper chaque point d’accès et chaque argument. Les équipes construisent ces catalogues, puis passent des mois à maintenir des exceptions pour les nouvelles API et les procédures de mise en production inhabituelles. Une interface d’action limitée, accompagnée d’une approbation humaine au bon moment, résiste généralement mieux au travail réel qu’un langage de règles que personne ne peut lire avec assurance.

## Les outils de suivi d’issues ont besoin de chemins d’écriture qui préservent le jugement humain

Les outils de suivi d’issues semblent peu risqués jusqu’à ce qu’un agent commence à modifier des éléments en volume. Fermer une issue peut supprimer un signalement client. Modifier des étiquettes peut casser les rapports de triage. Publier un commentaire peut exposer un raisonnement interne à des collaborateurs externes. Ajouter un utilisateur à un ticket peut élargir l’accès à un contexte sensible.

Séparez le travail de l’agent entre observation et modification. Laissez-le récupérer des issues, rechercher des étiquettes, examiner les pull requests liées et préparer une mise à jour. Faites passer la modification finale par une action qui indique le projet, l’issue, les champs modifiés et le contenu du commentaire. Le réviseur doit voir le contenu réel avant que le service le reçoive.

Un contrat de requête rend cette frontière concrète. L’agent doit envoyer une intention structurée, pas assembler une ligne de commande contenant un identifiant.

```json
{
  "service": "issue-tracker",
  "action": "update_issue",
  "issue": "APP-184",
  "changes": {
    "labels_add": ["needs-reproduction"],
    "comment": "I reproduced this on the current release and attached the failing test."
  }
}
```

L’exécuteur doit injecter son propre identifiant et renvoyer un résultat limité :

```json
{
  "ok": true,
  "issue": "APP-184",
  "updated_fields": ["labels", "comment"],
  "request_id": "service-request-id"
}
```

Ne renvoyez pas l’en-tête Authorization brut, une trace HTTP complète ou un objet de débogage contenant des secrets. Cela semble évident, jusqu’à ce que quelqu’un active les diagnostics HTTP détaillés pendant une intégration difficile. Gardez les diagnostics derrière un parcours de dépannage piloté par une personne, avec une suppression des secrets que vous testez au lieu de la supposer efficace.

Un agent peut encore prendre une mauvaise décision après l’approbation d’une session par une personne. C’est pourquoi les modifications destructives d’issues méritent une option d’approbation distincte. L’autorisation de session indique si ce programme en cours d’exécution peut utiliser l’intégration. L’approbation par appel indique si cette modification précise doit avoir lieu. La distinction compte surtout lorsque l’agent peut lire du texte non fiable provenant de tickets, de documents ou de commentaires de pull request.

## Les API de déploiement ont des conséquences qui dépassent le bouton de mise en production

Une API de déploiement expose souvent davantage que « déployer cette version ». Elle peut modifier des variables d’environnement, déclencher des builds, redémarrer des charges de travail, créer des domaines, restaurer des versions, récupérer des journaux ou supprimer des ressources. Un jeton de déploiement étendu devient une télécommande pratique pour un agent qui a déjà élaboré un plan erroné.

Utilisez différentes catégories d’actions pour les déploiements. Lire l’état d’un build et récupérer les métadonnées publiques d’un déploiement sont généralement des opérations courantes. Promouvoir un artefact en production, restaurer une version, modifier une référence de secret et supprimer un environnement ont des conséquences différentes. Ne regroupez pas ces opérations derrière une approbation unique appelée « accès au déploiement ».

Une requête raisonnable demande une référence d’artefact immuable et une cible explicite. Refusez les entrées vagues comme « latest » lorsque le service peut utiliser un commit, un condensé d’image ou un identifiant de build. Les étiquettes modifiables créent un décalage entre l’approbation et l’exécution : le réviseur approuve une chose, tandis que l’action en exécute une autre.

```json
{
  "service": "deployment-platform",
  "action": "promote_release",
  "application": "billing-api",
  "environment": "production",
  "artifact": {
    "git_commit": "8cf4f3a",
    "build_id": "build-4921"
  },
  "reason": "Fixes the confirmed invoice retry failure"
}
```

L’exécuteur doit vérifier que les identifiants approuvés correspondent à la requête envoyée. Il doit aussi enregistrer l’identifiant de réponse du service et l’environnement cible. Enregistrer seulement « déploiement réussi » vous laisse très peu d’éléments à examiner à 2 heures du matin lorsque quelqu’un demande quel artefact a été déplacé et qui l’a autorisé.

Ne demandez pas à l’agent d’extraire les informations d’un tableau de bord web pour éviter de concevoir une API. L’automatisation du navigateur masque les détails lors de la vérification, tombe en panne sans avertissement et peut cliquer sur une page dont l’état est obsolète. Si la plateforme propose une API, utilisez une action médiée limitée au-dessus de cette API. Si elle ne propose qu’un tableau de bord, acceptez que certaines opérations restent humaines jusqu’à la création d’un connecteur fiable.

## Les outils de support client exigent de minimiser les données avant l’automatisation

Les systèmes de support client combinent actions opérationnelles et données personnelles. Un ticket peut contenir des informations de compte, des coordonnées, des pièces jointes, un historique de commandes, des journaux et des messages chargés émotionnellement. L’accès direct d’un agent soulève deux questions : peut-il lire des éléments dont il n’a pas besoin et peut-il envoyer une réponse nuisible au nom de votre entreprise ?

Ne résolvez pas le problème en envoyant par défaut des transcriptions complètes à un agent. Récupérez uniquement les champs nécessaires à la tâche. Pour classer un ticket, l’agent peut avoir besoin du sujet, d’un corps de message expurgé et du domaine produit. Il n’a probablement pas besoin de toutes les notes internes précédentes, des données de facturation ou des pièces jointes.

Les actions d’écriture exigent une vérification plus stricte que la classification. Un modèle utile consiste à préparer d’abord, puis à envoyer. L’agent crée une proposition de réponse avec des références vers le ticket et les sources internes utilisées. Une personne vérifie le ton, les affirmations factuelles, les détails propres au compte et l’absence de divulgation accidentelle de notes internes. L’exécuteur ne publie ensuite le message qu’après cette vérification.

La fermeture, la fusion ou la réattribution de tickets exigent également une sémantique d’action explicite. « Résoudre le ticket » est trop vague si cette action envoie silencieusement un e-mail de clôture, modifie le délai d’un accord de niveau de service ou supprime un brouillon. Votre schéma de requête doit identifier l’effet de bord que le service de support va produire.

C’est ici qu’un compte de service étendu est particulièrement tentant. Il évite les contraintes de permissions et permet à l’agent de traiter n’importe quelle file. Il signifie aussi qu’une seule instruction défectueuse peut franchir les frontières entre comptes. Attribuez des identités de service aux files ou aux équipes lorsque le fournisseur le permet, puis limitez l’interface d’action médiée aux opérations réellement nécessaires à cette équipe.

## SSH est une autorité d’exécution, pas un identifiant API avec une syntaxe différente

SSH mérite un traitement distinct, car une clé privée peut donner accès à un shell, au transfert de fichiers, au transfert de ports et à des outils qui possèdent leurs propres identifiants. Une API de déploiement peut proposer un ensemble fini d’opérations. Un shell distant peut composer de nouvelles opérations à la volée.

Donner une clé privée SSH à un agent de programmation crée deux risques à la fois. La clé peut fuiter et l’agent peut générer des commandes distantes arbitraires. Restreindre le compte aide, mais un compte restreint ayant accès à des scripts de déploiement, à des identifiants CLI cloud ou à la configuration de production peut encore faire bien davantage que ne le suggérait la tâche initiale.

Utilisez un médiateur qui conserve la clé privée et reçoit l’hôte, la commande et les arguments demandés. Faites enregistrer par l’action l’hôte résolu et la commande exacte après traitement des arguments. N’approuvez pas une chaîne shell que l’agent pourrait ensuite réinterpréter avec des guillemets imbriqués, une substitution de commande ou un script distant récupéré depuis une branche non fiable.

Pour les hôtes sensibles, préférez des opérations distantes fixes à un accès shell général. Une commande comme `release-status --service billing-api` est plus facile à vérifier que `bash -lc '...'`. Si vous devez autoriser une commande générale, affichez-la exactement comme elle sera exécutée et exigez une approbation à chaque appel. Traitez `sudo`, l’installation de paquets, la lecture de fichiers secrets, la redirection du shell et les commandes de copie vers l’extérieur comme des cas à risque élevé, pas comme de la maintenance courante.

La vérification de l’hôte SSH compte également. Le client doit comparer la clé d’hôte du serveur à une entrée connue gérée. Accepter automatiquement l’empreinte d’un nouvel hôte permet à une erreur de réseau ou de DNS de devenir un événement d’utilisation des identifiants. Cela annule l’intérêt de dissimuler soigneusement la clé privée.

## Les actions médiées contiennent les identifiants et créent un point de décision

Un système d’actions médiées garde le jeton SaaS ou la clé privée SSH dans un exécuteur et fournit à l’agent une interface pour lui demander d’effectuer un travail défini. L’exécuteur ajoute les identifiants, envoie la requête et renvoie le résultat. L’agent ne reçoit jamais de secret, pas même un espace réservé qu’il pourrait remplacer accidentellement dans une commande.

Cela modifie le mode de défaillance. Un agent ayant un accès direct qui accepte une instruction malveillante peut à la fois décider d’une action et l’exécuter avec un identifiant réutilisable. Un agent médié peut encore demander une mauvaise action, car aucun contrôle de sécurité ne rend le jugement d’un modèle de langage parfait. Mais l’exécuteur peut identifier l’appelant, demander à une personne d’approuver l’appel, garder les identifiants hors de portée de l’agent et enregistrer la requête ainsi que le résultat.

Sallyport utilise ce modèle pour les appels d’API HTTP et les commandes SSH : un agent compatible MCP se connecte avec `sp mcp`, tandis que l’application macOS conserve les identifiants API et SSH dans son coffre-fort chiffré et exécute elle-même les actions. Le verrou du coffre-fort refuse toute action lorsqu’il est verrouillé, ce qui est le comportement approprié lorsque la personne responsable s’est éloignée de la machine.

Ne confondez pas un médiateur avec un proxy man-in-the-middle. Un proxy observe ou relaie un trafic général. Une passerelle d’action reçoit une demande d’action précise, applique ses contrôles d’autorisation, utilise un identifiant qu’elle conserve et renvoie un résultat. Cette forme plus étroite est utile, car elle fournit un point d’approbation et une trace d’audit au lieu d’essayer d’interpréter tout le trafic une fois que l’agent l’a déjà formé.

Les meilleures interfaces médiées sont volontairement simples. Elles exposent un petit nombre de verbes compréhensibles, acceptent des paramètres structurés, refusent les cibles ambiguës et fournissent assez d’informations pour vérifier l’effet. Un point d’accès universel qui accepte des URL, des en-têtes et des corps arbitraires peut recréer discrètement l’accès direct en ajoutant seulement quelques étapes.

## La conception des approbations échoue lorsque les personnes ne peuvent pas évaluer la requête

Une demande d’approbation doit aider une personne à décider, pas seulement l’interrompre. « L’agent demande l’accès à l’outil de support » demande au réviseur d’approuver un avenir inconnu. « Publier cette réponse sur le ticket 4821 au nom de l’équipe support » lui donne une action concrète à examiner.

Pour le premier appel d’un nouveau processus agent, affichez l’identité du processus et son autorité de signature. L’identité du processus n’est pas décorative. Sur une machine de développement, plusieurs terminaux, extensions et programmes auxiliaires peuvent demander la même intégration. Le réviseur doit savoir quel programme signé fait la demande avant d’accorder une session.

Choisissez ensuite le bon niveau d’autorisation :

- Utilisez une approbation de session pour les tâches à faible impact qui nécessitent des lectures répétées ou des appels courants pendant une exécution d’agent.
- Utilisez une approbation par appel pour les messages externes, les changements d’état, les déploiements, les commandes distantes et les actions aux effets irréversibles.
- Verrouillez le magasin d’identifiants lorsque vous vous absentez, afin que chaque action échoue au lieu d’attendre une approbation sans surveillance.
- Révoquez la session actuelle lorsque la tâche change, que l’agent se comporte étrangement ou que vous ne reconnaissez plus le processus.

La fatigue liée aux approbations est un défaut de conception. Si une personne doit approuver chaque lecture inoffensive, elle s’habituera à cliquer sans regarder. Si une approbation accorde à un agent toute une après-midi de modifications en production, l’interface a caché trop d’autorité derrière la commodité. Séparez les types d’action selon leurs conséquences, puis rendez l’activité courante discrète et l’activité importante précise.

Évitez les textes d’approbation qui répètent la description vague de l’agent. La couche d’action possède déjà des champs structurés. Utilisez-les. Affichez le service, le compte ou le rôle authentifié, le projet ou l’hôte cible, l’opération et tout contenu destiné à sortir de l’organisation. Masquez les identifiants et les champs privés dont le réviseur n’a pas besoin.

## Les journaux doivent relier une exécution d’agent à chaque effet externe

Les journaux des fournisseurs de services ne suffisent pas pour le travail des agents, car ils commencent à la frontière de l’API. Les transcriptions des agents ne suffisent pas non plus, car elles peuvent omettre la requête réelle ou être modifiées. Il faut à la fois un enregistrement au niveau de l’exécution et un enregistrement au niveau de l’appel, reliés par une référence fiable.

Un journal d’exécution doit identifier le processus agent, le début et la fin de sa session, l’approbation qui l’a autorisé et un moyen de le révoquer immédiatement. Un journal d’appel doit enregistrer la demande d’action, le résultat de l’autorisation, le résultat de l’exécution, la cible et l’identifiant de requête du service lorsqu’il existe. Gardez les corps sensibles hors des affichages courants lorsqu’ils contiennent du contenu client, mais conservez suffisamment de preuves protégées pour enquêter sur un incident.

L’intégrité contre les modifications compte si les journaux doivent répondre à un litige. Un simple fichier texte local peut montrer un historique utile, mais un utilisateur ou un processus compromis peut le réécrire. Une chaîne de hachage fait dépendre chaque enregistrement du précédent, de sorte que les modifications ultérieures interrompent la vérification. Cela ne rend pas le journal infaillible. Cela rend les réécritures indétectables plus difficiles et fournit à l’enquêteur une propriété d’intégrité vérifiable.

Sallyport produit ses journaux Sessions et Activity à partir d’un journal d’audit chiffré, chaîné par hachage et insensible à l’écriture. Vous pouvez vérifier hors ligne la chaîne de texte chiffré avec `sp audit verify`, sans la clé du coffre-fort. Une vérification saine devrait produire une sortie de ce type :

```text
Audit chain: valid
Records checked: 184
First sequence: 1
Last sequence: 184
```

Si la vérification signale une séquence interrompue ou une différence de hachage, conservez les fichiers et enquêtez avant de vous fier au journal. Ne « réparez » pas un journal suspect en supprimant sa fin corrompue. Vous pourriez supprimer la seule preuve du moment et de la manière dont l’enregistrement a changé.

## Une migration hors des jetons directs doit commencer par l’identifiant le plus risqué

N’essayez pas de repenser toutes les intégrations en une semaine. Commencez par l’identifiant dont l’utilisation abusive serait la plus difficile à corriger : autorité de déploiement en production, accès étendu au support client ou clé SSH donnant accès à des systèmes partagés. La migration doit retirer les secrets utilisables de l’agent avant de chercher à perfectionner chaque workflow.

Suivez cette séquence pour chaque intégration :

1. Répertoriez les endroits où l’agent obtient aujourd’hui l’identifiant. Incluez les variables d’environnement, les fichiers de dépôt, les secrets CI, les profils shell, la configuration des outils et les instructions copiées.
2. Listez les opérations que l’agent effectue réellement, puis séparez les lectures, les brouillons, les modifications et l’exécution distante. La plupart des jetons directs autorisent bien plus que cette liste.
3. Créez des demandes d’action structurées pour les opérations nécessaires. Associez chaque écriture à une cible nommée et chaque déploiement à une référence d’artefact immuable.
4. Déplacez l’identifiant dans un exécuteur que l’agent ne peut pas lire. Faites tourner l’ancien identifiant après avoir vérifié que le nouveau chemin fonctionne.
5. Testez volontairement les échecs : verrouillez le coffre-fort, refusez une approbation, révoquez une session, envoyez une cible invalide et lancez la vérification d’audit. Une démonstration du parcours normal ne prouve presque rien.

L’étape de rotation révèle une erreur fréquente : les équipes ajoutent un médiateur mais laissent l’ancien jeton dans l’environnement de l’agent « en secours ». Il reste alors deux chemins vers la même autorité et le moins contrôlé finira par être utilisé. Supprimez le secours. Si le chemin médié ne prend pas encore en charge une opération nécessaire, documentez l’exception temporaire, limitez sa portée et sa durée et désignez une personne responsable de sa suppression.

La transmission directe d’un jeton est facile parce qu’elle confie la décision difficile à une chaîne présente dans l’environnement du processus. Pour les bacs à sable jetables, ce compromis peut être raisonnable. Pour les services qui touchent aux clients, aux déploiements ou à une infrastructure partagée, gardez les identifiants hors de l’agent et rendez l’action visible avant son exécution.
