8 min de lecture

Comment les demandes d’approbation des agents évitent d’autoriser la mauvaise exécution

Les demandes d’approbation d’agents ont besoin de l’identité du processus et de la session pour que les réviseurs autorisent la bonne action lorsque plusieurs exécutions partagent une file.

Comment les demandes d’approbation des agents évitent d’autoriser la mauvaise exécution

Une file d’approbation pour agents autonomes n’est pas une pile de boutons d’autorisation. C’est un système d’attribution en temps réel. Lorsque deux exécutions d’agents ou plus peuvent demander le même identifiant, appeler la même API ou ouvrir la même connexion SSH, le réviseur doit pouvoir répondre à une question précise avant d’approuver : quel processus en cours me demande d’autoriser exactement cette action ?

La plupart des interfaces d’approbation échouent parce qu’elles donnent l’impression que chaque carte vient d’un acteur générique appelé « l’agent ». Ce libellé est inoffensif pendant une démonstration avec une seule fenêtre de terminal. Il devient dangereux lorsqu’un agent de programmation répare un incident de production pendant qu’un autre prépare une mise en production, les deux utilisant le même client et demandant l’accès au même service. Le réviseur voit une destination familière, reconnaît globalement la tâche et approuve l’action prévue pour la mauvaise exécution.

L’approbation est une décision d’attribution

Un réviseur n’approuve pas une requête HTTP isolément. Il approuve une requête parce qu’elle appartient à un travail précis qu’il s’attend à voir en cours. Si l’interface ne peut pas préserver ce lien, le bouton d’approbation devient une supposition déguisée en contrôle humain.

Traitez chaque approbation comme une déclaration en cinq parties :

  1. Un exécutable ou processus d’agent précis l’a initiée.
  2. Une session précise de ce processus est toujours active.
  3. Cette session se rattache à une tâche ou un élément de travail nommé.
  4. Elle souhaite effectuer une action externe concrète.
  5. Le réviseur autorise ou refuse cet ensemble précis.

Le cinquième point compte davantage qu’il n’y paraît. « Autoriser l’accès à l’API de déploiement » n’est pas une déclaration complète. Un réviseur peut accepter que l’exécution de mise en production lise un enregistrement de build, tout en refusant qu’une exécution de débogage indépendante modifie un paramètre de mise en production. La destination seule ne suffit pas à transmettre le sens.

Cette distinction s’estompe parce que le même client d’agent crée souvent les deux exécutions. La ligne de commande peut être identique. L’autorité de signature du code peut être identique. Le chemin du dépôt peut être identique. L’agent peut même produire des demandes presque identiques. Rien de tout cela ne fait de deux invocations simultanées un même sujet de sécurité.

J’ai vu des équipes ajouter davantage de mots au résumé de l’action alors que le vrai défaut était l’absence d’attribution. Elles remplacent « POST /deployments » par « POST /deployments pour déclencher le déploiement de staging de la version 1.8.4 ». Cela explique mieux l’opération, mais laisse toujours au réviseur deux cartes qui se présentent comme des déploiements de staging. Une meilleure formulation ne peut pas réparer une limite de session absente.

L’interface d’approbation doit rendre visible la hiérarchie des identités. L’action est l’objet principal. Le processus initiateur et la session active expliquent pourquoi cette action est apparue. Le libellé de tâche aide le réviseur à reconnaître l’intention, mais ne remplace aucun des deux identifiants techniques.

Un processus signé n’est pas une session en cours

Une identité de signature du code peut indiquer qui a signé le code, mais pas au réviseur quelle invocation de ce code a produit une demande en attente. La documentation d’Apple sur la signature du code établit la même distinction avec d’autres termes : les exigences du code établissent l’identité du code, tandis qu’une exigence désignée décrit ce qui compte comme le même code au fil des versions. Il s’agit d’un élément utile sur l’appelant, mais pas d’un substitut à l’identifiant d’exécution.

Cela compte lorsque la demande d’approbation commence par quelque chose comme :

Request from: Acme Agent CLI
Signed by: Example Engineering, Team ABCD1234

C’est un bon début. Le réviseur peut vérifier si un client attendu demande l’accès. Mais cela ne permet pas de savoir s’il s’agit de l’assistant de mise en production lancé il y a cinq minutes, de l’assistant de test laissé ouvert depuis ce matin ou d’une commande copiée dans un deuxième terminal.

L’identité du processus et celle de la session répondent à des questions différentes :

ChampQuestion à laquelle il répondCe qu’il ne permet pas de savoir
Autorité de signature du codeQui a produit cet exécutable ?Quelle invocation est concernée ?
Chemin de l’exécutableQuel client installé l’a lancé ?Quelle tâche effectue-t-il ?
Identifiant du processusQuel processus local possède actuellement la connexion ?Un humain peut-il le reconnaître après un redémarrage ?
Identifiant de sessionQuelle exécution délimitée a produit cette demande ?L’action demandée est-elle pertinente ?
Libellé de tâcheQu’a demandé l’utilisateur à cette exécution ?Le libellé est-il exact ou constitue-t-il une preuve suffisante ?

Ne masquez pas les deux premières lignes simplement parce que vous ajoutez la quatrième. Le réviseur a besoin de l’autorité du processus pour repérer un client inattendu. Il a besoin de l’identifiant de session pour distinguer des clients attendus exécutés en parallèle. Il a besoin du libellé de tâche pour relier un identifiant technique à une représentation mentale du travail.

La règle pratique est simple : affichez l’identité du processus comme provenance et l’identité de la session comme unité autorisée.

Sur macOS, un identifiant de signature du code seul constitue un libellé d’approbation particulièrement faible. Apple précise que plusieurs signataires peuvent revendiquer les identifiants de signature et recommande d’associer une vérification de l’identifiant à la catégorie de validation et, pour le code qui n’est pas celui d’Apple, à un identifiant d’équipe. Une carte qui affiche uniquement un nom de bundle convivial ou un identifiant revendiqué fournit au réviseur moins d’éléments que la plateforme ne peut en offrir.

N’affichez pas le langage brut des exigences comme libellé principal. Il est précis, mais la plupart des réviseurs ne peuvent pas le lire assez vite pour prendre une décision. Présentez l’autorité de signature en termes simples, gardez l’exigence technique disponible dans les détails et associez-la à un nom d’exécutable reconnaissable. Placez ensuite l’identifiant de session à un endroit visible sans avoir à développer la carte.

Donnez à chaque exécution une identité de session qui survive dans la file

Un identifiant de session doit être créé avant le premier appel protégé, rester stable pendant toute la durée de l’exécution et disparaître de l’ensemble des autorisations lorsque l’exécution se termine. Toute solution moins rigoureuse crée de l’ambiguïté sous charge.

Générez un identifiant opaque à forte entropie au moment de la connexion ou de l’enregistrement du processus. Stockez sa valeur complète dans l’enregistrement d’audit, mais affichez un préfixe court et sans ambiguïté dans la demande. La forme affichée doit être assez longue pour que deux sessions actives aient peu de chances de la partager, et l’interface doit rendre immédiatement visibles les éventuelles collisions. Ne déduisez pas l’identifiant de l’heure actuelle, de la position dans la file, du nom du dépôt ou du seul identifiant de processus.

Un enregistrement interne utile pourrait ressembler à ceci :

{
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "display_id": "7TQ4N8M2",
  "process": {
    "pid": 84172,
    "executable": "/usr/local/bin/agent-cli",
    "signing_authority": "Example Engineering (Team ABCD1234)"
  },
  "task": {
    "label": "Prepare the staging release notes",
    "workspace": "/Users/maya/work/app"
  },
  "started_at": "2026-07-22T16:42:11Z"
}

Le libellé de tâche doit venir d’une instruction visible par un humain ou d’un titre de session défini volontairement, pas d’une phrase générée par un modèle qui change à chaque appel d’outil. Un modèle peut proposer le libellé, mais le système doit le figer au démarrage de la session. Si une session passe de « préparer les notes de mise en production » à « faire tourner l’identifiant du webhook de production », le réviseur mérite un changement de tâche explicite ou une nouvelle session. Réécrire silencieusement le libellé rend l’historique plus difficile à lire et permet à l’exécution d’emprunter la légitimité d’une tâche antérieure et plus sûre.

Utilisez un cycle de vie aux limites nettes :

  • Créez la session avant toute action nécessitant des identifiants.
  • Associez chaque demande, approbation, refus, annulation et résultat à cette session.
  • Fermez la session lorsque le processus initiateur se termine ou perd sa connexion valide.
  • Révoquez immédiatement la session lorsque le réviseur choisit la révocation.
  • Refusez les approbations en attente après la fermeture ou la révocation, même si une carte reste visible pendant un instant.

Le dernier point évite une course subtile mais fréquente. Un réviseur voit une carte provenant de l’exécution A. L’exécution A se termine. Une nouvelle exécution B démarre, demande une action similaire et l’ancienne carte accepte encore les interactions. Si le service d’approbation rattache ce clic à « la dernière demande pour cet identifiant », le réviseur a approuvé B en regardant A. Liez la carte à un identifiant de demande immuable et à un identifiant de session. Lorsque l’un des deux devient invalide, le seul bouton sûr est la fermeture.

Évitez les libellés tels que « Session 1 », « Exécution d’agent » ou « Tâche actuelle ». Ils fonctionnent jusqu’au démarrage de la deuxième exécution. Un libellé peut être convivial, mais l’interface a besoin d’un identifiant qui reste pertinent après le redémarrage d’un processus, la mise en veille d’un ordinateur portable ou une revue d’incident plusieurs jours plus tard.

Placez les bonnes informations dans les deux premières lignes

Les deux premières lignes d’une demande d’approbation doivent permettre au réviseur de distinguer cette demande de toutes les autres demandes en attente sans ouvrir les détails. Placez d’abord l’action demandée, puis indiquez directement dessous le processus initiateur et la session.

Une carte pratique peut prendre cette forme :

Allow POST to api.example.internal/v1/releases?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Prepare the staging release notes

Creates a release record named "2026.07.22-rc3"
Credential: release-service-write
[Review request]                         [Deny] [Allow]

La ligne d’action indique ce qui va se produire et où. La ligne d’attribution indique qui a fait la demande. La ligne de tâche précise le travail auquel le réviseur doit associer la demande. L’aperçu donne suffisamment d’informations sur la conséquence pour permettre un premier jugement. Cet ordre est intentionnel.

Ne commencez pas par « Approbation demandée » ou « L’agent veut utiliser un secret ». Aucune de ces formulations n’aide le réviseur à trier une file chargée. Ne commencez pas non plus par le nom de l’identifiant. Les identifiants sont des détails d’implémentation. Un réviseur sait généralement si une demande appartient à la bonne exécution de mise en production avant de savoir si release-service-write est la bonne clé stockée.

Pour SSH, la demande équivalente doit nommer l’hôte distant et la catégorie de commande, pas simplement « Accès SSH ». Par exemple :

Allow SSH command on build-staging-03.example.internal?
agent-cli, signed by Example Engineering, session 7TQ4N8M2
Task: Verify the staging migration

Runs: /usr/local/bin/check-migration --database app_staging
Credential: deploy-ssh
[Review command]                         [Deny] [Allow]

Si le système ne peut pas produire un aperçu sûr et lisible, il doit le dire. « Arguments de commande indisponibles » vaut mieux qu’une phrase conviviale inventée qui masque une expansion du shell, un script indirect ou une entrée non inspectée. Le réviseur peut alors ouvrir la commande exacte ou refuser la demande.

Une bonne demande ne demande pas au réviseur de déduire l’exécution initiatrice à partir d’un horodatage. L’heure a sa place dans les détails et dans l’activité. Deux agents peuvent envoyer des demandes dans la même seconde, et les humains n’utilisent pas les horodatages de manière fiable pour relier une carte à un terminal. Utilisez l’heure comme élément secondaire, jamais comme libellé chargé de porter l’attribution.

Évitez également de placer l’identifiant de session dans un pied de page peu visible. Cet identifiant n’est pas un déchet de diagnostic. Dans une file parallèle, c’est le champ qui empêche le réviseur de traiter deux cartes presque identiques comme interchangeables.

Une file a besoin de regroupement, sans fausse fusion

Appeler des API sans exposer les clés
Sallyport injecte les identifiants bearer, basic ou d’en-tête personnalisé au lieu d’exposer les clés d’API aux agents.

Le travail parallèle crée un problème de tri visuel. Regrouper les cartes par session peut aider, mais le regroupement devient dangereux lorsque l’interface gomme des différences importantes entre les demandes.

Une file doit permettre au réviseur de voir ensemble toutes les actions en attente d’une même session, tout en conservant une décision d’approbation par action lorsque leurs effets diffèrent. Un assistant de mise en production qui a besoin de trois appels d’API en lecture seule peut raisonnablement apparaître dans un groupe compact. Une session qui veut lire un ticket, écrire un enregistrement de déploiement et exécuter une migration distante doit présenter trois décisions distinctes, car les conséquences ne sont pas les mêmes.

Le mauvais modèle est une bannière globale indiquant :

agent-cli requests access to 5 services
[Allow all]

Ce bouton demande au réviseur d’approuver un ensemble avant d’avoir attribué chaque élément à une exécution ou examiné ses effets. Il récompense également la fatigue liée à la file. Plus un réviseur voit cette bannière, plus il risque de prendre l’habitude de la vider pour retourner au travail.

Une meilleure file utilise les en-têtes de session comme contexte, pas comme autorisation générale :

Session 7TQ4N8M2 · agent-cli · Prepare the staging release notes
2 pending requests

  GET api.example.internal/v1/builds/rc3             [Allow]
  POST api.example.internal/v1/releases              [Review]

Session C5J1W6PA · agent-cli · Investigate test failure #1842
1 pending request

  SSH build-staging-03.example.internal              [Review]

Le réviseur peut parcourir visuellement les demandes par exécution, mais chaque ligne formule toujours une demande distincte. Si le système prend en charge un état d’autorisation par session, affichez-le dans l’en-tête avec une portée claire : « Cette session est autorisée jusqu’à sa fermeture ». Ne donnez pas à cet état l’apparence d’une approbation de chaque action individuelle. L’autorisation par session permet à l’exécution de demander des actions ; elle ne transforme pas des actions inattendues en actions prévues.

L’ordre influence aussi les erreurs. Une file strictement chronologique peut mélanger à ce point les demandes de cinq exécutions qu’un réviseur ne peut plus conserver le contexte d’une seule. Une file strictement regroupée par session peut cacher une demande urgente derrière une session très active. Offrez les deux vues : une vue groupée par défaut pour l’attribution et une vue triée par heure pour la réponse aux incidents. Gardez le badge de session visible dans les deux vues.

Ne fusionnez pas les cartes simplement parce qu’elles partagent une destination et un identifiant. Deux exécutions distinctes qui écrivent sur le même endpoint créent exactement l’ambiguïté que la file doit résoudre. La similarité est une raison de rendre l’identité de l’exécution plus visible, pas de regrouper les approbations.

L’approbation doit être liée à la demande exacte inspectée par le réviseur

Une demande peut identifier la bonne exécution tout en autorisant la mauvaise requête si l’approbation s’applique à un modèle modifiable plutôt qu’à une action immuable. Le réviseur doit approuver une représentation précise de la demande, pas une future requête qui réutiliserait le même chemin, la même commande ou le même identifiant.

Créez un enregistrement canonique de l’action avant l’affichage de la carte. Pour HTTP, incluez au minimum la méthode, l’origine et le chemin normalisés, les en-têtes sélectionnés par nom, l’alias de l’identifiant et une empreinte du corps. Pour SSH, incluez l’identité normalisée de l’hôte, le compte demandé, le port, les octets de la commande et l’alias de l’identifiant. Conservez les éléments protégés complets dans le composant de confiance ; l’agent ne doit pas les recevoir simplement parce que le réviseur a besoin d’une demande.

Liez ensuite l’approbation à l’enregistrement canonique :

{
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "action_digest": "sha256:2a13c4e0...",
  "expires_at": "2026-07-22T16:47:11Z",
  "decision": "allow_once"
}

Au moment de l’exécution, recalculez l’empreinte à partir de l’action qui sortira réellement de la machine. Si elle diffère, refusez l’approbation et créez une nouvelle carte. Ne considérez pas silencieusement une demande modifiée comme « suffisamment proche ». Un paramètre d’URL modifié peut rediriger un paiement, un en-tête modifié peut changer la portée d’un compte et un argument shell modifié peut transformer une commande d’inspection en écriture.

C’est ici que de nombreux systèmes pourtant bien conçus échouent. Ils affichent un résumé révisable, approuvent « utiliser l’identifiant X pour l’endpoint Y », puis laissent l’agent envoyer une deuxième requête avec cette autorisation générale. Le réviseur n’a pas examiné la deuxième requête. Le système a transformé une décision explicite en règle invisible.

Utilisez une durée d’expiration courte pour une approbation en attente. Le but n’est pas de sanctionner un réviseur qui prend une pause-café, mais d’empêcher qu’une ancienne décision soit appliquée après un changement du contexte environnant. Si l’agent a encore besoin de l’action plus tard, il peut envoyer une nouvelle demande avec les mêmes informations de processus et de session. Le réviseur verra si elle correspond toujours à l’exécution.

Les documents du NIST sur l’intervention humaine dans les décisions automatisées mettent en garde contre le biais d’automatisation et les boucles d’approbation sans friction qui normalisent la fatigue face aux alertes. La conséquence pratique est claire : rendre les approbations faciles à cliquer ne les rend pas pertinentes. L’interface doit rendre la décision assez limitée pour être inspectée et assez précise pour engager la responsabilité du réviseur.

La vue détaillée doit résoudre les désaccords, pas les créer

Garder les identifiants hors des agents
Les identifiants HTTP et SSH restent dans le coffre chiffré de Sallyport, qui exécute l’action dans l’application.

Une carte d’approbation compacte ne peut pas contenir chaque octet d’une demande. Elle doit toutefois proposer une vue détaillée qui répond aux questions qu’un réviseur attentif se pose lorsque l’action est inhabituelle, coûteuse ou suspecte.

Pour une action HTTP, affichez la méthode et l’URL complètes, les en-têtes masqués par défaut, les champs du corps avec un traitement clair des secrets, l’alias de l’identifiant, l’identité du processus initiateur, l’identifiant de session, le libellé de tâche et l’heure de création de la demande. Si le corps est binaire ou trop volumineux pour être affiché, indiquez sa taille, son type de contenu et son empreinte. Ne prétendez pas qu’un résumé en une ligne suffit.

Pour SSH, affichez l’hôte, l’utilisateur, le port, l’état de vérification de l’hôte lorsqu’il est disponible, la commande exacte qui sera exécutée, le répertoire de travail s’il est pertinent et les valeurs d’environnement qui influencent le comportement. L’aperçu de la commande doit préserver les guillemets et les limites entre les arguments. Afficher un tableau comme une chaîne shell assemblée de manière approximative peut rendre une commande sûre inquiétante ou, pire, une commande dangereuse anodine.

Il existe une différence nette entre le masquage pour des raisons de sécurité et l’omission par commodité. Masquez dans la demande un bearer token, une clé privée, un mot de passe ou une valeur sensible du corps. Ne masquez pas le chemin, le compte cible, l’hôte distant, la commande ou le champ modifié simplement parce que ces détails allongent la carte. Ce sont souvent eux qui permettent de déterminer si la demande appartient à cette exécution.

Utilisez une empreinte stable de la demande dans la vue détaillée. Un réviseur qui écrit à un collègue doit pouvoir dire : « J’ai refusé la demande apr_K9H2D7LQ de la session 7TQ4N8M2 », et le collègue doit retrouver un seul enregistrement. Ne forcez jamais les utilisateurs à décrire un événement comme « la deuxième demande de déploiement vers 16 h 40 ». Cette formulation fonctionne jusqu’à ce qu’un incident exige de la précision.

La surface de révision doit également préciser ce que l’approbation autorise et ce qu’elle n’autorise pas. Par exemple :

Allow once
This decision authorizes only this POST request with digest 2a13c4e0…
It does not authorize later calls from session 7TQ4N8M2.

Cette phrase mérite sa place. Elle empêche le réviseur de supposer une autorisation générale et l’implémenteur d’élargir ultérieurement la portée derrière le même libellé de bouton.

L’annulation et la révocation doivent avoir des conséquences visibles

Un réviseur finira par approuver la mauvaise carte ou constater qu’une exécution a dévié de son objectif. La récupération doit être rapide, visible et liée aux mêmes identifiants que ceux utilisés pendant l’approbation.

L’interface doit proposer des actions distinctes pour refuser une demande et révoquer une session. Refuser signifie « n’effectuez pas cette action ». Révoquer signifie « ce processus en cours a perdu son autorisation, annulez ses approbations en attente et refusez ses actions ultérieures ». Ces actions ont des conséquences différentes et ne doivent donc pas être réunies derrière un bouton ambigu « Arrêter ».

Lorsqu’un réviseur révoque une session, affichez une confirmation qui nomme le processus, l’identifiant de session et la tâche :

Revoke session 7TQ4N8M2?
agent-cli is running “Prepare the staging release notes.”
Pending requests from this session will be cancelled. New protected actions
from this process will be denied until it starts a new session.
[Keep session] [Revoke session]

Si une demande est déjà en cours d’exécution, dites-le honnêtement. Une révocation peut empêcher de futures actions privilégiées, mais elle ne peut pas forcément annuler une requête HTTP déjà acceptée par un service distant ou arrêter une commande distante déjà lancée. L’activité doit indiquer si l’action était en attente, envoyée, terminée, échouée ou annulée. N’écrivez pas « révoquée » d’une manière qui laisserait croire que l’effet externe a disparu.

C’est une autre raison d’afficher l’identifiant de session sur chaque carte. Pendant un incident stressant, le réviseur a besoin d’un lien direct entre une demande suspecte et le contrôle qui arrête cette exécution. Si la file indique seulement « agent-cli », la révocation risque d’arrêter l’exécution utile tout en laissant l’exécution problématique active.

Un journal de session et un journal d’activité doivent utiliser les mêmes identifiants. Un enregistrement indique que la session de processus 7TQ4N8M2 a démarré, reçu une autorisation puis été révoquée. L’autre indique quelle action précise elle a tentée avant et après chaque changement d’état. Si ces enregistrements utilisent des libellés sans rapport, les intervenants perdent du temps à reconstituer des liens que le produit aurait dû rendre explicites.

Testez l’approbation de la mauvaise exécution avant les utilisateurs

Demander une approbation pour chaque appel
Marquez une clé comme nécessitant une approbation en un clic ou avec Touch ID à chaque utilisation.

Vous pouvez tester ce problème sans équipe rouge ni incident de production. Exécutez deux instances du même client d’agent sur le même espace de travail et demandez-leur d’effectuer des appels protégés similaires. Le test est réussi uniquement si un réviseur peut identifier correctement chaque demande dans une file chargée.

Utilisez cet exercice :

  1. Démarrez l’exécution A avec le libellé « Inspecter le build de staging en échec ».
  2. Démarrez l’exécution B avec le libellé « Publier l’enregistrement de mise en production de staging ».
  3. Faites demander aux deux exécutions le même identifiant à quelques secondes d’intervalle.
  4. Rendez leurs premières demandes similaires, par exemple deux appels vers la même origine d’API.
  5. Modifiez une action de sorte que l’approuver pour l’autre exécution ait un effet visible et indésirable dans un environnement de test.

Demandez ensuite à une personne qui n’a pas conçu l’interface d’approuver uniquement la demande de l’exécution B. Ne lui dites pas quelle carte correspond à B en fonction de sa position dans la file. Observez ce qu’elle utilise. Si elle s’appuie sur les horodatages, l’ordre des cartes ou le souvenir du premier terminal ouvert, l’interface a échoué. Si elle peut indiquer l’autorité du processus, l’identifiant de session, la tâche, la destination et l’action sans ouvrir un autre écran, vous disposez d’une base utilisable.

Testez également le comportement des approbations obsolètes. Créez une carte pour l’exécution A, terminez A, démarrez B et cliquez sur l’ancienne carte. Le système doit refuser le clic et expliquer que la demande n’est plus active. Recommencez après avoir modifié le corps d’une demande ou un argument SSH après la révision. Le système doit exiger une nouvelle approbation au lieu d’appliquer l’ancienne à l’action modifiée.

Testez les noms qui entrent en collision. Deux tâches peuvent s’appeler « Corriger CI ». Deux dépôts peuvent avoir le même nom de répertoire. Deux branches peuvent partager un numéro de version. Un texte convivial aide les utilisateurs, mais la conception complète doit continuer à fonctionner lorsque ce texte est ambigu.

L’autorisation par session de Sallyport offre un emplacement naturel pour établir cette limite : le premier appel d’un nouveau processus d’agent identifie cette exécution pour l’approbation, tandis que les clés par appel peuvent exiger une approbation distincte pour chaque utilisation. Gardez le libellé de session et l’autorité du processus visibles lorsque ces contrôles apparaissent, sinon les exécutions parallèles redeviendront un « agent » indistinct.

La piste d’audit doit permettre de reconstituer la décision d’approbation

Une piste d’audit n’est utile que si elle permet de savoir, après coup, ce que le réviseur a vu et ce que le système a exécuté. Enregistrer « l’utilisateur a approuvé l’accès à l’API » ne suffit pas. La question centrale reste sans réponse : l’accès de quelle exécution, pour quelle action et avec quel contexte affiché ?

Pour chaque décision, enregistrez les identifiants immuables et les éléments présentés :

{
  "event": "approval_granted",
  "approval_id": "apr_K9H2D7LQ",
  "session_id": "ses_7TQ4N8M2KDXP6R9V",
  "process_identity": "agent-cli / Example Engineering (Team ABCD1234)",
  "task_label": "Prepare the staging release notes",
  "action_digest": "sha256:2a13c4e0...",
  "displayed_action": "POST api.example.internal/v1/releases",
  "decision_scope": "once",
  "recorded_at": "2026-07-22T16:44:03Z"
}

Stockez l’enregistrement canonique de l’action séparément ou à côté de cet événement, avec un chiffrement et des contrôles d’accès appropriés. L’événement d’audit doit indiquer ce que disait la carte ; l’enregistrement canonique doit prouver quels octets et quelle destination le composant de confiance a utilisés. Si les deux diffèrent, considérez cela comme un défaut de sécurité, pas comme un simple problème de journalisation.

Un journal chaîné par empreintes aide à détecter toute réécriture de l’historique, mais ne répare pas le contenu vague des événements. Vous pouvez prouver cryptographiquement que « approbation accordée » n’a pas été modifié tout en étant incapable de savoir quelle demande l’a reçue. L’intégrité et l’attribution répondent à des problèmes différents. Il vous faut les deux.

Sallyport conserve les enregistrements de session et d’appels individuels dans un journal d’audit chiffré et chaîné par empreintes, et sa commande sp audit verify vérifie la chaîne hors ligne sur le texte chiffré. C’est utile, car les réviseurs peuvent conserver la preuve que le journal n’a pas été réécrit sans exposer les secrets stockés à l’étape de vérification.

Le test final de conception est simple. Choisissez une action terminée et remontez son historique : un enquêteur peut-il identifier le processus, la session précise, le libellé de tâche affiché à ce moment-là, la demande exacte révisée, la portée de la décision du réviseur et le résultat ? Puis partez d’une session et avancez dans le temps : peut-il voir dans l’ordre chaque action en attente, refusée, approuvée, annulée et exécutée ? Si l’une ou l’autre direction exige des suppositions, la file d’approbation laisse encore place à l’erreur de la mauvaise exécution.

Les agents parallèles rendront les files d’approbation courantes. La solution n’est pas d’ensevelir les réviseurs sous davantage de cartes ni de leur donner un contrôle général « tout autoriser ». Donnez à chaque processus en cours une identité de session durable, placez-la à côté de l’action, là où les utilisateurs regardent réellement, et liez chaque clic à la demande inspectée par le réviseur. C’est ainsi qu’une approbation garde son sens lorsque plusieurs agents sont actifs en même temps.

FAQ

Qu’est-ce qu’une file d’approbation pour agents parallèles ?

Une file d’approbation pour agents parallèles regroupe les demandes produites simultanément par plusieurs processus d’agent. Le réviseur doit disposer de suffisamment de contexte pour savoir quel processus en cours a créé chaque demande, au lieu de considérer toutes les cartes comme des demandes interchangeables provenant de « l’agent ».

Pourquoi le nom du processus ne suffit-il pas pour les approbations d’agents ?

Le nom d’un processus indique qui a lancé le travail, mais pas quelle invocation précise est concernée. Deux fenêtres de terminal peuvent exécuter le même client signé et envoyer des demandes similaires. La carte d’approbation doit donc aussi afficher un identifiant de session et un court libellé de tâche.

À quoi doit ressembler l’identifiant d’une session d’agent ?

Utilisez un identifiant de session opaque et stable, généré lorsque le processus d’agent se connecte, puis conservez-le jusqu’à la fermeture ou la révocation du processus. N’utilisez pas la position dans la file, un simple compteur de demandes ou un horodatage comme seul identifiant de session.

Quelles informations doivent apparaître en premier dans une demande d’approbation ?

Placez d’abord l’action et sa destination, puis indiquez immédiatement dessous le processus initiateur et la session. Les réviseurs déterminent généralement si l’action correspond au travail prévu avant d’examiner les en-têtes, les options de commande ou le contenu de la requête.

Les demandes d’approbation doivent-elles afficher la commande ou la requête HTTP complète ?

Une carte d’approbation doit afficher un aperçu concis et permettre d’inspecter la commande, l’URL, la destination, la méthode et les champs modifiés exacts. Ne forcez pas le réviseur à approuver un résumé vague parce que la requête complète est enfouie dans un journal d’activité.

Comment empêcher les cartes d’approbation de devenir obsolètes ?

Ne laissez pas une carte changer silencieusement de signification après son affichage. Liez l’approbation à une empreinte de requête immuable, faites-la expirer lorsque la session se termine et refusez l’action si le processus tente de réutiliser l’approbation avec des arguments modifiés.

Puis-je utiliser un identifiant de session court dans une demande d’approbation ?

Utilisez un identifiant durable qu’un humain peut comparer entre la carte d’approbation, le journal de session et le journal d’activité. Une forme courte convient, mais elle doit correspondre sans ambiguïté à l’identifiant complet dans la piste d’audit.

Que doit-il se passer lorsqu’une session d’agent est révoquée ?

L’annulation doit identifier la session concernée et indiquer au réviseur ce qu’il advient des demandes en attente. Si la révocation les annule, dites-le clairement. Si une demande déjà approuvée peut encore se terminer, affichez cet état au lieu de laisser croire que l’annulation a tout arrêté.

Quelle est la différence entre une approbation de session et une approbation par appel ?

L’approbation par session répond à la question « ce processus peut-il s’exécuter ? ». L’approbation par appel répond à la question « peut-il effectuer cette action précise maintenant ? ». Les équipes rencontrent des problèmes lorsqu’une approbation de session étendue est présentée comme la preuve que toute demande destructive ultérieure est attendue.

Comment tester une file d’approbation pour agents ?

Commencez par deux exécutions simultanées qui utilisent volontairement le même client d’agent, le même dépôt, les mêmes identifiants et la même destination. Si un réviseur ne peut pas distinguer les cartes correspondant à chaque exécution dans une capture où les détails sont masqués, la file n’est pas prête pour une utilisation réelle.

Sallyport

Sallyport exécute les appels d'API et les commandes SSH à la place de votre agent IA. Les clés restent dans un coffre-fort local sur votre Mac ; vous approuvez chaque exécution et chaque action est consignée dans un journal scellé.

© 2026 Sallyport · Open source sous Apache-2.0 · Oleg Sotnikov