# Tester l’accès aux API d’un agent avant un déploiement en production

Un agent mérite l’accès aux API de production lorsqu’il se comporte correctement face à une demande refusée, mal formée, lente ou dangereuse, pas lorsqu’il renvoie une réponse réussie dans un bac à sable. Une démonstration bien préparée masque les échecs qui comptent : une approbation destinée au mauvais processus, un jeton copié dans la conversation de l’agent, une boucle de nouvelles tentatives qui épuise une limite de débit ou un journal incapable d’indiquer qui a approuvé un appel destructeur.

Testez tout le parcours d’action sur une destination hors production avant de donner à l’agent une capacité de production. Ce parcours comprend la demande de l’agent, l’autorisation, l’injection de l’identifiant, la réponse de l’API distante, l’interprétation de l’échec par l’agent et un compte rendu de chaque appel conservé après la session. Si un élément manque, vous avez testé un client API, pas un acteur autonome.

## Le point d’accès hors production doit être séparé là où une erreur ferait mal

Un point d’accès de test utile dispose d’identifiants et de données distincts, ainsi que d’une limite de dommages que vous pouvez expliquer en une phrase. Appeler un nom d’hôte de production avec un paramètre censé activer le mode test ne suffit pas si le même jeton peut encore lire des dossiers clients ou dépenser de l’argent.

Utilisez le bac à sable d’un fournisseur lorsqu’il offre un compte isolé et des identifiants de test. Utilisez un environnement dédié si le service n’a pas de bac à sable. À défaut, placez un petit service que vous contrôlez derrière un autre nom d’hôte et utilisez des données jetables. L’essentiel n’est pas l’étiquette « staging ». Il faut qu’une requête mal adressée ne puisse pas toucher les utilisateurs, les soldes ou les secrets de production.

Faites en sorte que le point d’accès prouve qu’il est hors production. Renvoyez un champ d’environnement évident dans chaque réponse réussie et faites écrire les routes destructrices uniquement dans un registre de test. Une réponse comme celle-ci évite qu’un opérateur confonde un test réussi avec une modification de production :

```json
{
  "environment": "test",
  "request_id": "req_7f1a",
  "status": "accepted",
  "resource_id": "demo-order-184"
}
```

Les données de test doivent être assez réalistes pour couvrir la pagination, les champs manquants, les permissions et les conflits. Un enregistrement parfait apprend de mauvaises habitudes à l’agent. Préparez quelques enregistrements qu’il peut lire, un qu’il peut modifier et un auquel il ne doit jamais accéder. Un vaste jeu de données n’est pas nécessaire. Il faut simplement assez de variations pour repérer le code qui suppose que chaque réponse est complète et correcte.

Ne réutilisez pas un jeton bearer de production dans un environnement de test par commodité. Des équipes présentent cela comme un raccourci temporaire, puis le laissent en place parce que chaque tâche suivante semble plus urgente. Une identité de test doit avoir un nom, un responsable, une date d’expiration et des permissions correspondant aux cas testés. Si personne ne sait expliquer pourquoi une permission est nécessaire, retirez-la.

## Le premier essai doit tester la limite d’autorisation, pas l’API

Avant de valider le comportement métier, vérifiez qu’un processus d’agent non reconnu ne peut pas agir silencieusement. Lancez un nouveau processus et faites-lui tenter une lecture inoffensive sur le point d’accès de test. Le résultat attendu est un événement d’autorisation avant l’envoi de la requête API.

Cette vérification met en évidence une distinction souvent brouillée : l’approbation d’un utilisateur n’est pas l’approbation d’un processus. Un opérateur peut faire confiance à son terminal tout en se méfiant d’un module, d’un script copié ou d’un agent lancé par une autre application. L’interface d’approbation doit indiquer quelle autorité exécutable demande à agir. Un bouton « Autoriser » dépourvu de ce contexte demande aux utilisateurs de valider un processus inconnu.

Pour ce test, relevez quatre éléments :

- Le nouveau processus reçoit une demande d’approbation avant l’appel externe.
- L’approbation identifie le processus d’une manière reconnaissable par l’opérateur.
- L’approbation ne vaut que pour l’exécution prévue, pas pour tous les processus futurs.
- La fin du processus supprime l’autorisation de session.

Refusez la demande une fois avant de l’approuver. Le refus doit laisser à l’agent un signal d’échec exploitable, et non un succès inventé. De bonnes instructions indiquent quoi faire après un refus : arrêter l’opération, signaler que l’approbation a été refusée et ne pas chercher un autre chemin vers le même point d’accès.

Redémarrez ensuite l’agent et répétez la lecture inoffensive. Si le second processus hérite de l’autorisation du premier, cherchez pourquoi. Une autorisation mise en cache semble efficace dans une démonstration, mais devient une permission silencieuse lorsqu’un agent redémarre après une mise à jour ou lorsqu’un autre lanceur exécute la même commande.

L’approbation de session de Sallyport est activée par défaut et affiche l’autorité de signature du code du processus lors du premier appel d’un nouveau processus d’agent. C’est le bon moment pour tester le jugement humain, avant qu’une requête authentifiée n’atteigne le service externe.

## L’injection d’identifiants doit prouver que l’agent n’a jamais détenu le secret

L’injection d’un identifiant ne réussit que si l’agent peut demander une action sans pouvoir récupérer l’identifiant utilisé. Masquer un jeton dans la sortie de la console ne constitue pas une protection. Un jeton qui est entré dans une variable d’environnement, une réponse d’outil, une invite, l’historique du shell ou un fichier local était disponible pour l’agent, même si personne ne l’a affiché.

Configurez un identifiant de test que le service distant peut reconnaître sans révéler sa valeur. De nombreuses API fournissent un libellé de jeton, un identifiant client ou un champ d’audit. Si ce n’est pas le cas, créez une route de test qui renvoie l’identité de l’identifiant reçu, pas l’identifiant lui-même. Le résultat doit prouver quelle identité de test a authentifié l’appel.

Pour une API à jeton bearer, la requête au niveau réseau ressemble généralement à ceci :

```http
GET /v1/test/projects/demo HTTP/1.1
Host: api.test.example
Authorization: Bearer [injected outside the agent]
Accept: application/json
```

Le texte entre crochets est une indication documentaire, pas une valeur à renseigner par l’agent. Celui-ci doit fournir la méthode, la destination et les paramètres autorisés. Le gestionnaire d’identifiants ajoute l’en-tête d’autorisation seulement après la décision d’approbation. L’authentification basic et les schémas d’en-têtes personnalisés doivent être testés de la même façon, car les erreurs de configuration ne se manifestent pas au même endroit.

Inspectez la conversation de l’agent, l’historique des requêtes d’outil, l’environnement du shell auquel il a accès et les fichiers créés pendant l’exécution. Cherchez le jeton en clair, mais aussi les fuites indirectes, comme un objet de requête contenant un en-tête d’autorisation. Une suppression après coup ne corrige pas une conception qui a donné le secret au processus.

Faites ensuite tourner l’identifiant de test et exécutez la même requête. Une seconde exécution réussie montre que le parcours d’action lit l’identifiant actuel stocké, plutôt qu’une ancienne valeur intégrée à la configuration de l’agent. Un échec peut aussi être utile si le message indique une erreur d’authentification sans afficher le secret refusé.

Ne testez pas avec un jeton capable de faire davantage que ce que le scénario exige. Des identifiants en lecture seule suffisent à prouver l’injection. Ajoutez ensuite une permission d’écriture étroitement réversible pour les tests de modification. La personne qui examine le test ne devrait jamais avoir besoin d’accéder au jeton brut pour décider s’il est réussi.

## La friction de l’approbation doit correspondre aux dommages possibles

L’approbation d’une session et l’approbation de chaque utilisation répondent à des besoins différents. L’approbation de session établit qu’une exécution précise de l’agent peut utiliser une capacité limitée. L’approbation à chaque utilisation oblige une personne à examiner chaque requête effectuée avec un identifiant sensible. Les considérer comme interchangeables produit soit une avalanche d’invites inutiles, soit un chemin sans surveillance vers des erreurs coûteuses.

Utilisez un identifiant à faible risque pour tester la limite de session. Imposez une approbation à chaque utilisation pour un identifiant capable de créer, supprimer, transférer, publier ou modifier des accès. Demandez à l’agent d’effectuer deux appels de test distincts avec cet identifiant. Vous devez voir deux décisions, et la seconde requête ne doit pas profiter de l’approbation accordée pour la première.

Le test doit inclure un refus. Approuvez la première action de test et refusez la seconde. Confirmez les faits suivants dans le rapport de l’agent et dans l’enregistrement de l’action :

1. La première action a atteint le service de test et renvoyé son identifiant de requête.
2. L’action refusée n’a jamais atteint le service de test.
3. L’agent n’a pas prétendu avoir effectué la modification.
4. La session est restée utilisable pour les opérations ne nécessitant pas l’identifiant refusé.

Ce quatrième point révèle un mode d’échec particulièrement pénible. Certaines intégrations traitent le refus d’une requête sensible comme une raison d’arrêter toutes les opérations suivantes. D’autres ignorent le refus et réessaient jusqu’à ce qu’une personne approuve par accident. Ces deux comportements compliquent inutilement le contrôle humain.

La fatigue liée aux approbations est un défaut de conception, mais supprimer les approbations n’est généralement pas la solution. Réduisez-la en regroupant le travail dans une session courte, en diminuant le nombre d’appels sensibles ou en donnant à l’agent une opération groupée plus sûre. Ne résolvez pas des invites trop nombreuses en accordant un jeton permanent et large à un processus dont le plan peut changer en cours de tâche.

## Les codes de statut HTTP doivent guider le comportement de l’agent

Un agent a besoin d’un comportement explicite pour chaque classe d’échec, car le succès HTTP et le succès de la tâche ne sont pas la même chose. La RFC 9110 définit la signification des codes de statut HTTP : une réponse 401 indique des identifiants d’authentification absents ou invalides, tandis qu’une réponse 403 signifie que le serveur a compris la requête mais refuse de l’exécuter. Traitez ces réponses différemment. Réessayer avec la même requête n’apporte généralement aucun progrès.

Préparez un tableau des échecs avant le déploiement et testez chaque ligne avec le point d’accès de test. Les actions demandées doivent être assez précises pour qu’un évaluateur puisse voir si l’agent les a suivies.

| Réponse de test | Action de l’agent | Ce que l’enregistrement doit montrer |
| --- | --- | --- |
| 401, échec d’authentification | Arrêter et signaler un problème d’identifiant | Destination, statut, référence de l’identifiant, aucun secret |
| 403, échec d’autorisation | Arrêter et signaler des permissions insuffisantes | Destination, méthode, statut, opération tentée |
| 404, ressource absente | Demander si l’identifiant est incorrect | Identifiant fourni et statut |
| 409, conflit | Lire l’état actuel avant de proposer une nouvelle écriture | Identifiant de ressource, statut, aucune nouvelle tentative aveugle |
| 429, limite de débit | Attendre selon les indications du serveur ou s’arrêter | Statut et délai de nouvelle tentative s’il est fourni |
| 500 ou 503 | Réessayer dans une limite définie, puis signaler le résultat | Nombre de tentatives, statut, résultat final |

Une réponse 400 mérite plus d’attention qu’elle n’en reçoit souvent. Elle révèle parfois un décalage entre le schéma d’outil de l’agent et le contrat réel de l’API distante. Demandez au serveur de test de renvoyer des erreurs de validation par champ, puis vérifiez que l’agent signale le mauvais argument sans inventer une valeur de remplacement. Un agent qui devine les champs peut transformer une erreur de validation inoffensive en requête adressée au mauvais compte.

Testez séparément une panne de transport et une réponse HTTP 503. Déconnectez le service de test ou dirigez une requête contrôlée vers une adresse inaccessible. L’agent doit distinguer l’absence de réponse d’une réponse du serveur. Cette différence compte lorsque l’opération a pu atteindre le service mais que la réponse a été perdue. Réessayer une création après un délai d’attente ambigu peut produire des doublons.

Utilisez des identifiants d’idempotence lorsque l’API les prend en charge. Sinon, demandez à l’agent de rechercher un résultat existant avant de répéter un appel potentiellement modificateur. Dire « réessayer trois fois » ne constitue pas un plan de récupération lorsqu’une nouvelle tentative peut débiter une carte, créer un utilisateur ou envoyer un message.

## Un déploiement qui échoue commence souvent par une boucle de nouvelles tentatives inoffensive

Un échec courant commence par un agent chargé de créer une ressource de test, puis de la vérifier. Le service accepte la création, mais une interruption réseau masque la réponse. L’agent voit une erreur, réessaie l’appel et reçoit un second résultat positif. Il récupère ensuite une seule ressource à partir d’un nom supposé et signale que tout a réussi. L’opérateur se retrouve avec des modifications en double et aucun moyen clair de savoir quelle requête a produit laquelle.

Vous pouvez reproduire ce scénario sans risque pour la production. Faites accepter la création par une route de test, enregistrez l’objet, puis fermez volontairement la connexion avant de renvoyer la réponse. Exécutez l’agent avec un identifiant de requête fixe. Le comportement sûr consiste à interroger le service de test avec cet identifiant avant de répéter la création. Si l’agent ne peut pas le faire, il doit s’arrêter et signaler un résultat ambigu.

Un contrat minimal de service de test rend le contrôle concret :

```json
POST /v1/test/jobs
{
  "request_id": "rollout-042",
  "name": "reconcile-demo"
}

GET /v1/test/jobs?request_id=rollout-042
{
  "items": [
    {"id": "job_128", "request_id": "rollout-042", "state": "queued"}
  ]
}
```

C’est aussi à ce moment que vous repérez les invites demandant à l’agent de continuer jusqu’à ce que cela fonctionne. Cette consigne semble raisonnable lorsqu’on observe un opérateur humain. Elle devient dangereuse pour un acteur capable d’effectuer des appels plus vite que quiconque ne peut le remarquer. Remplacez-la par une règle de nouvelles tentatives limitée, une vérification des doublons et une condition exigeant un examen humain.

L’OWASP API Security Top 10 signale la consommation illimitée de ressources et les problèmes d’autorisation au niveau des objets. Dans les déploiements d’agents, ces risques prennent souvent la forme d’erreurs ordinaires : une boucle qui ignore une limite et un agent qui remplace l’identifiant demandé par celui d’un objet voisin après un échec. Votre test doit inclure un objet interdit et une route limitée, car un scénario idéal ne révélera aucune de ces habitudes.

## Les enregistrements doivent expliquer la décision et l’effet externe

Un enregistrement d’appel doit permettre de reconstituer les faits sans reconstruire tout le raisonnement privé de l’agent. Conservez les éléments qui établissent l’autorité et l’effet : la session utilisée, le processus demandeur, la destination et la méthode, la référence de l’identifiant, l’approbation éventuelle d’une personne, l’heure et le résultat.

Ne placez pas systématiquement le corps brut de chaque requête dans les enregistrements. Certains contenus contiennent des données client, des jetons de tiers ou des informations que l’agent devait traiter. Un résumé sûr ou quelques champs sélectionnés peuvent suffire à l’enquête. L’identifiant de requête du service distant est particulièrement utile pour relier votre enregistrement local à son propre journal d’audit.

Séparez l’enregistrement de l’exécution de celui de l’appel. Le premier indique si un processus d’agent donné a été autorisé à agir et si une personne a ensuite révoqué cette autorisation. Le second décrit chaque action externe. Tout intégrer à une conversation fait perdre la structure nécessaire lorsqu’une session produit de nombreux appels.

Sallyport protège les journaux de session et d’activité dans un journal d’audit chiffré et chaîné par hachage. Sa commande `sp audit verify` peut vérifier cette chaîne hors ligne sur le texte chiffré, sans clé de coffre, ce qui permet de tester séparément l’intégrité des enregistrements et l’accès aux secrets.

Effectuez une vérification après un test normal, puis copiez le fichier d’audit chiffré dans un emplacement de test et modifiez quelques octets dans la copie. La commande doit signaler l’altération de la copie, tandis que l’original doit rester valide. Utilisez uniquement une copie jetable. L’équipe de contrôle apprend ainsi à reconnaître un rapport valide avant d’en avoir besoin pendant une enquête de production.

La preuve d’altération ne signifie pas que chaque opérateur peut lire tous les détails, et elle ne remplace pas les journaux de l’API distante. Elle répond à une question plus précise : la suite locale des enregistrements est-elle restée intacte ? Conservez les identifiants de requête et les horodatages du point d’accès de test afin de comparer les deux côtés.

## La révocation doit bloquer l’appel suivant, pas seulement fermer une fenêtre

Testez la révocation pendant que l’agent fonctionne encore. Approuvez une session, effectuez une requête inoffensive, révoquez la session, puis demandez au même processus d’effectuer une seconde requête. Cette seconde requête doit échouer avant d’atteindre le point d’accès hors production. Si elle réussit parce qu’une connexion existante ou un identifiant mis en cache subsiste, le déploiement en production doit être bloqué.

Testez ensuite séparément la protection du coffre. Verrouillez le magasin d’identifiants et tentez à nouveau la requête. Un coffre verrouillé doit refuser toute action, y compris une requête approuvée auparavant pour la session. C’est un contrôle plus fort que la révocation d’une seule exécution, car il arrête tous les chemins d’action dépendant du coffre.

Surveillez le point d’accès pendant les deux tests. Ne considérez pas un message de l’agent indiquant que l’accès a été refusé comme une preuve suffisante. Le journal des requêtes côté serveur doit confirmer qu’aucune seconde requête n’est arrivée. Ce contrôle simple repère les intégrations qui signalent un échec d’approbation après avoir déjà envoyé la requête HTTP.

Si votre agent peut aussi utiliser SSH, répétez le test sur un hôte jetable. Utilisez un compte sans privilèges et une commande au résultat évident, comme la création d’un fichier dans un répertoire temporaire. La révocation doit empêcher une nouvelle commande SSH comme elle empêche une requête API. Une passerelle qui traite différemment les deux canaux crée un angle mort où les opérateurs croient encore maîtriser l’action.

## La promotion exige un dossier de preuves, pas la confiance inspirée par une démonstration

Passez en production uniquement lorsqu’un évaluateur peut examiner un dossier de test compact et déterminer si l’agent est resté dans son autorité prévue. Ce dossier doit contenir l’identité et les permissions de test, la limite du point d’accès, le comportement attendu des approbations, des résultats représentatifs de réussite et d’échec, le résultat de la vérification des enregistrements et celui de la révocation.

Ne transférez pas toutes les permissions de test avec l’agent. Créez séparément un identifiant de production et commencez par le plus petit ensemble d’opérations nécessaire à la première tâche réelle. Désignez un opérateur capable d’approuver ou de révoquer les sessions et précisez les états de réponse qui imposent à l’agent de s’arrêter. Si l’équipe ne peut pas nommer cette personne, elle a confié le contrôle opérationnel au hasard.

Exécutez la première tâche de production avec les approbations activées et examinez immédiatement les enregistrements. Comparez le nombre réel de requêtes, les destinations et les résultats avec le test. Si l’agent contacte un point d’accès imprévu, demande un identifiant plus large ou réessaie différemment avec les données de production, arrêtez le déploiement et reproduisez ce comportement hors production.

Le premier déploiement en production doit être volontairement banal. L’agent effectue quelques appels prévus, une personne peut l’arrêter, l’identifiant ne pénètre jamais dans son contexte et chaque effet externe possède un enregistrement correspondant à l’identifiant de requête du service. C’est une preuve suffisante pour élargir progressivement l’accès. Une démonstration soignée ne l’est pas.
