8 min de lecture

Comment l’approbation locale ou en amont change le contrôle des agents

Utilisez cette matrice d’approbation locale ou en amont pour comparer latence, contexte, identité, pannes, relances et preuves d’audit des actions d’agent.

Comment l’approbation locale ou en amont change le contrôle des agents

Un bouton d’approbation n’est pas, à lui seul, une propriété de sécurité. Sa valeur dépend de l’endroit où la décision est appliquée, de ce que l’examinateur peut voir, de l’identité que le service consigne et de ce qui se passe après un délai d’attente ou une connexion rompue.

Pour un agent IA qui appelle une API, l’approbation locale et l’approbation en amont répondent à des questions différentes. Une barrière locale peut décider si ce processus d’agent peut utiliser un identifiant ou envoyer une requête préparée. Une barrière en amont peut décider si le système distant doit appliquer le changement demandé à sa propre ressource. Lorsqu’une API demande déjà une confirmation, le bon choix consiste rarement à « prendre la plus stricte ». Choisissez la barrière qui détient le fait à examiner, puis reliez ses preuves au reste de l’action.

Cette distinction compte parce qu’un écran d’approbation bien conçu peut masquer une grande faille d’autorisation. Un examinateur peut approuver localement « déployer la version 184 » alors que le service en amont reçoit un jeton réutilisable et une charge utile différente. Ou bien le service en amont peut consigner l’approbation d’un déploiement sans savoir qu’un processus d’agent non fiable a composé la requête. Les deux enregistrements peuvent être exacts sans pour autant expliquer l’action.

Les barrières locales et en amont n’autorisent pas la même chose

L’approbation locale autorise l’usage d’une capacité avant que la requête franchisse la limite de la machine. L’approbation en amont autorise une transition de ressource dans le service qui détient la ressource. Les traiter comme interchangeables fait perdre soit le contexte de l’appelant, soit celui de la ressource.

Une barrière locale se place à côté de l’agent, du coffre d’identifiants, de l’exécuteur de commandes ou de la passerelle d’actions sortantes. Elle peut inspecter l’exécutable, sa signature de code, le processus parent, le début de session, l’identifiant sélectionné, l’hôte cible, la méthode de requête et les arguments proposés. Elle peut aussi garder le secret hors de l’agent et effectuer elle-même l’appel. Elle répond ainsi solidement à la question : « Ce processus local peut-il exercer cette capacité maintenant ? »

Une barrière en amont se place chez le fournisseur d’API ou dans un plan de contrôle qui lui est relié. Elle peut inspecter la version actuelle de la ressource, l’appartenance à l’organisation, l’environnement protégé, la politique du service, l’état des conflits et l’identité distante de l’approbateur. Elle répond ainsi solidement à la question : « Cette transition distante précise doit-elle avoir lieu dans l’état actuel du service ? »

La publication spéciale NIST 800-207 décrit un point de décision de politique et un point d’application de politique. Elle recommande de rapprocher l’application de la ressource afin de limiter la zone de confiance implicite. Ce principe justifie l’application en amont pour les faits que seul le propriétaire de la ressource connaît. Il ne rend pas une barrière locale superflue. Un service ne peut pas inspecter l’identité d’un processus local à moins que le client ne la transmette et ne la lie à la requête, et la plupart des appels avec jeton porteur identifient le détenteur du jeton plutôt que le processus à l’origine de l’appel.

OpenSSH illustre concrètement le cas local. Le manuel OpenBSD de ssh-add indique que l’option -c exige une confirmation avant qu’un agent utilise une identité ajoutée. Le serveur SSH distant effectue ensuite sa propre autorisation après cette signature. Une barrière demande si le client local peut utiliser la clé, l’autre demande si l’authentification obtenue respecte la politique du serveur. Qualifier l’une ou l’autre de doublon revient à ignorer la limite qu’elle protège.

La règle pratique est simple : l’approbation doit être appliquée par le composant qui peut empêcher l’action qu’elle décrit. Une notification locale qui ne peut pas retenir l’identifiant ou l’appel n’est qu’une mise en scène. Un commentaire en amont enregistré après une mutation relève de la revue, pas de l’autorisation.

La matrice commence par le fait à examiner

Choisissez la barrière principale selon ce qu’elle peut connaître et appliquer, pas en comptant les demandes. Le tableau ci-dessous constitue la matrice de décision que j’utilise avant d’ajouter un flux d’approbation.

<table> <thead> <tr><th>Critère</th><th>Approbation locale</th><th>Approbation en amont</th><th>Conséquence pour la conception</th></tr> </thead> <tbody> <tr><td>Latence</td><td>En général, une interaction locale puis le temps d’appel</td><td>Inclut le réseau, la file d’attente du fournisseur, la notification et le temps de l’examinateur</td><td>Préférez le local pour les appels fréquents et réversibles lorsque le contexte local suffit</td></tr> <tr><td>Contexte de l’agent</td><td>Peut lier processus, session, autorité de l’exécutable, appel d’outil et utilisateur local</td><td>Voit généralement un jeton, une application, une charge de travail ou un compte de service</td><td>Gardez une barrière locale lorsque la provenance du processus change la décision</td></tr> <tr><td>Contexte de la ressource</td><td>Ne voit qu’un état récupéré ou fourni, qui peut devenir obsolète</td><td>Peut évaluer la version actuelle, les règles de protection, la propriété et les conflits</td><td>Utilisez une revue en amont pour les transitions dont la sûreté dépend d’un état distant en direct</td></tr> <tr><td>Identité humaine</td><td>Peut lier la personne présente devant l’appareil</td><td>Peut lier un compte d’organisation, un rôle d’équipe ou une séparation des tâches</td><td>Utilisez le domaine d’identité qui porte la responsabilité, ou conservez les deux</td></tr> <tr><td>Exposition des identifiants</td><td>Peut garder le secret hors de l’agent et ne libérer qu’une action</td><td>Commence souvent après que le client possède déjà des identifiants utilisables</td><td>Le contrôle local est nécessaire lorsque la garde des secrets fait partie du modèle de menace</td></tr> <tr><td>Panne du service</td><td>Peut refuser localement et conserver une intention en attente</td><td>Ne peut pas approuver tant que le service ou son plan d’approbation est indisponible</td><td>Définissez l’expiration et l’annulation, sans jamais interpréter une panne comme un consentement</td></tr> <tr><td>Panne locale</td><td>Bloque les appels contrôlés sur cet appareil</td><td>Peut rester disponible depuis un autre client fiable</td><td>Décidez si les clients alternatifs sont autorisés ou s’ils constituent un contournement</td></tr> <tr><td>Détail d’audit</td><td>Peut enregistrer demandes, refus, sorties de processus et appels tentés</td><td>Peut enregistrer requêtes acceptées et changements de ressource faisant autorité</td><td>Reliez les deux enregistrements avec un identifiant d’action stable</td></tr> <tr><td>Limite de falsification</td><td>Un hôte compromis peut attaquer les enregistrements ou l’interface locale</td><td>Le fournisseur contrôle l’enregistrement distant</td><td>Ne demandez pas à un journal de prouver des événements au-delà de sa limite de confiance</td></tr> <tr><td>Couverture</td><td>Peut envelopper de nombreuses API de manière cohérente</td><td>Ne couvre que les opérations que le fournisseur expose à sa barrière</td><td>Inventoriez les chemins non protégés avant de vous reposer uniquement sur l’approbation en amont</td></tr> </tbody> </table>

Ne transformez pas ce tableau en système de points avec un gagnant universel. Certaines lignes constituent des veto. Si l’agent ne doit jamais recevoir une clé API, une confirmation en amont ne règle pas l’exposition de l’identifiant, même si elle obtient un meilleur score sur le contexte de la ressource. Si un déploiement en production exige un approbateur du groupe des opérations, une demande Touch ID locale adressée au développeur qui a lancé l’agent ne satisfait pas la séparation des tâches.

Classez l’action avant de choisir un modèle. Les appels de lecture dont le risque de divulgation est faible peuvent nécessiter une autorisation de session, sans demande à chaque appel. Les écritures réversibles peuvent utiliser une barrière locale, une courte expiration et une clé d’idempotence. Les transitions irréversibles ou réglementées exigent généralement une revue en amont, car le service détient l’état final et l’identité de l’organisation. Une commande qui combine l’usage d’un secret et une transition irréversible peut justifier les deux barrières, à condition que chaque demande explique sa propre décision.

La latence inclut l’attente, l’expiration et la reprise humaine

L’approbation locale offre généralement une latence d’interaction plus faible, mais la mesure utile reste le temps nécessaire pour atteindre un résultat sûr et sans ambiguïté. Une demande rapide suivie d’une nouvelle tentative incertaine n’offre pas une faible latence.

Pour une personne qui supervise un agent sur un Mac, une carte locale peut apparaître alors que le contexte de la requête est encore frais. L’approbateur peut répondre immédiatement et la passerelle peut envoyer l’appel sans second aller-retour de notification. Cela convient à des actions comme l’ouverture d’une pull request habituelle, l’interrogation d’une API interne protégée ou l’exécution d’une commande SSH connue dans une session surveillée, à condition que les conséquences de l’action soient visibles localement.

Les flux en amont comportent davantage de points d’attente. Le service doit créer un objet en attente, sélectionner les examinateurs éligibles, envoyer ou afficher une notification, attendre une identité d’organisation, revérifier la politique actuelle, puis appliquer la transition. Ce délai est utile s’il crée une véritable séparation des tâches ou permet à l’examinateur de voir l’état faisant autorité. Il devient inutile lorsque la même personne approuve deux fois la même charge utile sans recevoir de nouvelle information.

La documentation GitHub sur les environnements fournit un exemple utile. Un job qui référence un environnement avec des examinateurs requis attend avant de démarrer et ne peut pas accéder aux secrets de cet environnement avant l’approbation. GitHub permet aussi à un environnement d’empêcher l’auto-approbation. Ces détails donnent un sens au délai en amont : la barrière contrôle à la fois l’état du service et la libération du secret, et peut lier un examinateur distinct de l’initiateur. Une approbation locale ne peut pas reproduire cette relation d’organisation en affichant l’adresse e-mail de l’examinateur.

Mesurez au moins quatre intervalles en production : de la création de l’intention à la demande, de la demande à la décision humaine, de la décision à l’exécution et de l’exécution au résultat faisant autorité. Conservez les refus et les expirations dans les mêmes données. Un temps médian d’approbation qui exclut les demandes abandonnées embellit un flux défaillant.

La fréquence des demandes modifie également les comportements. Une demande locale à chaque appel dans une boucle de cinquante lectures semblables apprend à l’examinateur à cliquer sans lire. Déplacer les cinquante demandes en amont ne corrige pas ce défaut. Ne regroupez que les actions qui partagent une capacité limitée, un ensemble clair de cibles et une durée courte. Gardez les transitions destructrices séparées, même si le regroupement serait plus rapide.

Fixez une expiration qui reflète la vitesse à laquelle les faits peuvent changer. Dix minutes peuvent être excessives pour une requête construite à partir d’une tête de branche qui évolue rapidement et trop courtes pour une revue formelle de production. Ne renouvelez pas une approbation silencieusement. Si la charge utile, la version cible, l’identifiant ou l’ensemble des examinateurs éligibles change, créez une nouvelle décision.

Le contexte détermine si l’examinateur peut juger

Une demande utile contient l’ensemble minimal et complet de faits nécessaires à sa décision. Les systèmes locaux et en amont voient des moitiés différentes, il est donc rarement pertinent de copier un écran dans l’autre.

Le côté local doit indiquer qui fait la demande avec des éléments que la personne peut vérifier : identité de l’exécutable, autorité de signature lorsqu’elle est disponible, session parente, nom de l’outil, alias de l’identifiant, destination, opération et résumé lisible de la charge utile. Il doit distinguer les données observées par la passerelle du texte fourni par l’agent. Une explication fournie par l’agent, comme « nettoyage sans risque », n’est pas une preuve.

Le côté en amont doit montrer l’objet faisant autorité et la transition proposée : dépôt et environnement, compte et région, version de la ressource, diff, contrôles de politique, identité de l’initiateur et approbateurs éligibles. Il ne doit pas prétendre connaître la provenance locale lorsqu’il n’a reçu qu’un jeton porteur.

Liez l’intention approuvée à l’exécution avec un condensat calculé sur des champs canoniques de l’action. L’enveloppe ci-dessous est volontairement assez petite pour être mise en œuvre. action_id relie les systèmes ; le condensat empêche une charge utile ultérieure d’emprunter une approbation antérieure.

{
  "action_id": "act_01JQ7M6F4R2K",
  "session_id": "ses_01JQ7KZ9J1AA",
  "caller": {
    "executable": "/usr/local/bin/agent",
    "signing_authority": "Developer ID Application: Example Team"
  },
  "target": {
    "service": "deploy-api",
    "resource": "production/payments",
    "version": "184"
  },
  "request": {
    "method": "POST",
    "operation": "promote",
    "body_sha256": "98b0...e42c"
  },
  "approval": {
    "scope": "single_action",
    "expires_at": "2026-07-24T14:05:00Z"
  }
}

L’exécuteur doit recalculer body_sha256, comparer la ressource et la version, vérifier l’expiration et consommer une seule fois une approbation d’action unique. Si l’agent modifie un argument après l’approbation, la comparaison doit échouer de façon sûre. La requête en amont doit transmettre action_id dans un champ de métadonnées ou de corrélation pris en charge par le fournisseur lorsque c’est possible. Ne le glissez pas dans un champ qui modifie le comportement métier.

Une capture d’écran crée une liaison faible. Elle peut aider une personne à comprendre une requête, mais le code doit appliquer la relation entre les octets approuvés et les octets envoyés. J’ai vu des systèmes afficher un résumé convivial issu d’un objet et exécuter un autre objet assemblé plus tard. Examinez le chemin de sérialisation, pas seulement l’interface.

Une action comporte trois acteurs, pas un seul

Garder les identifiants hors de l’agent
Sallyport injecte les identifiants API ou SSH, tandis que l’agent ne reçoit que le résultat.

Une action d’agent comporte au moins trois identités : le processus qui l’a proposée, le principal associé à l’identifiant qui l’a exécutée et la personne qui l’a approuvée. Les compresser en un seul champ d’acteur produit des journaux séduisants qui répondent à la mauvaise question.

L’identité du processus peut inclure un chemin d’exécutable, un hachage, une autorité de signature, un processus parent, une session de protocole de l’agent et l’utilisateur local du système d’exploitation. Aucun de ces éléments ne devient automatiquement une identité distante. L’API voit généralement un client OAuth, un compte de service, une clé de déploiement, une session de rôle ou un jeton utilisateur.

La personne qui approuve appartient aussi à un domaine d’identité. Une confirmation biométrique locale peut établir la présence d’une personne inscrite devant un appareil, selon le mécanisme du système d’exploitation, mais elle n’établit pas forcément le rôle que cette personne occupe actuellement dans l’organisation. Un compte d’examinateur en amont peut établir l’appartenance à une équipe et la séparation avec l’initiateur, sans rien savoir du binaire local qui a demandé l’action.

Conservez les trois identités et indiquez la méthode de liaison.

<table> <thead> <tr><th>Identité</th><th>Exemple de preuve</th><th>Question à laquelle elle répond</th></tr> </thead> <tbody> <tr><td>Proposeur</td><td>Signature du processus, hachage de l’exécutable, identifiant de session</td><td>Quel code en cours d’exécution a fait la demande ?</td></tr> <tr><td>Exécutant</td><td>Principal API, empreinte de clé publique SSH, session de rôle</td><td>Quelle autorité a effectué l’appel ?</td></tr> <tr><td>Approbateur</td><td>Présence d’un utilisateur local ou compte d’organisation en amont</td><td>Quelle personne a accepté quel risque ?</td></tr> </tbody> </table>

Les identifiants porteurs rendent ce point particulièrement important. Si cinq processus d’agent partagent un jeton, la piste d’audit en amont peut correctement nommer le principal du jeton tout en échouant à distinguer les processus. Une passerelle locale peut fournir cette provenance manquante, à condition que ses enregistrements de session résistent aux modifications triviales et se corrèlent avec l’événement distant.

N’étiquetez pas l’agent comme approbateur lorsqu’un humain a cliqué. N’étiquetez pas l’humain comme appelant de l’API lorsqu’un compte de service a exécuté la requête. Consignez directement la délégation : le proposeur P a demandé l’action A, l’approbateur H a autorisé la portée S, l’exécutant E a appliqué le résultat R.

La séparation des tâches est un atout de l’amont lorsque le service détient l’appartenance au groupe et empêche l’auto-approbation. L’approbation locale est plus forte pour la présence de l’utilisateur et la provenance du processus. Lorsque la politique exige les deux, demandez des preuves distinctes plutôt que deux clics de la même personne sur le même appareil.

Une panne doit laisser un état durable unique

Les systèmes d’approbation échouent gravement lorsqu’ils traitent les erreurs réseau comme des problèmes d’interface. L’action a besoin d’une machine à états durable qui survit aux sorties de processus, aux réponses perdues et au rétablissement du service.

Utilisez des états explicites tels que créé, approuvé_localement, soumis, en_attente_en_amont, en_exécution, réussi, refusé, expiré et inconnu. Les états terminaux doivent le rester. Stockez chaque transition avec le condensat de l’action et l’heure. Un redémarrage local peut reprendre l’observation d’une requête en attente en amont, mais il ne doit pas créer une nouvelle mutation sauf si les règles de relance l’autorisent.

Les règles sûres en cas de panne sont strictes :

  1. Si la barrière locale est indisponible, les actions contrôlées ne quittent pas la machine.
  2. Si le plan d’approbation en amont est indisponible, les actions qui en dépendent restent en attente ou expirent.
  3. Si l’approbation réussit mais que le statut d’exécution est inconnu, interrogez par identifiant d’action ou d’idempotence avant toute relance.
  4. Si la ressource change pendant l’attente d’approbation, invalidez la décision ou demandez au service en amont de la réévaluer.
  5. Si un examinateur refuse ou révoque, annulez toute exécution en attente et consignez si l’annulation a atteint le service.

L’ouverture en cas d’échec n’est pas une stratégie de reprise. Les équipes ajoutent parfois un contournement d’urgence parce que le service d’approbation se trouve sur le chemin critique. Un contournement peut être légitime, mais c’est une opération privilégiée distincte, avec une personne nommée, une portée étroite, une courte durée et son propre enregistrement durable. Le cacher derrière « relancer sans approbation » détruit le contrôle précisément lorsque les incidents rendent la revue la plus importante.

Les pannes locales et en amont ne sont pas symétriques. Une barrière locale peut encore enregistrer une tentative refusée alors que le réseau est coupé. Le fournisseur ne peut pas enregistrer une requête qu’il n’a jamais reçue. À l’inverse, le fournisseur peut terminer une action après le plantage du processus local et laisser l’enregistrement local à l’état soumis. La réconciliation doit accepter que chaque côté ait une connaissance incomplète.

Concevez l’annulation avant le lancement. Demandez-vous si une action approuvée mais en file d’attente peut être retirée, si une approbation expire pendant l’exécution et quel état l’emporte lorsqu’un refus et une fin d’exécution se croisent. L’état de la ressource distante détermine ce qui s’est produit ; l’enregistrement d’approbation explique toujours si c’était autorisé.

Les relances ne doivent pas dépenser deux fois une approbation

Vérifier la chaîne d’audit locale hors ligne
Sallyport vérifie sa chaîne de hachage chiffrée sans avoir besoin de la clé du coffre-fort.

L’approbation et l’exécution sont deux opérations distinctes, une relance peut donc dupliquer l’une ou l’autre. Le risque le plus élevé apparaît lorsqu’un client reçoit l’approbation, envoie une mutation, perd la réponse, puis renvoie la mutation.

La RFC 9110 définit une méthode idempotente par l’effet prévu de la répétition d’une requête identique. Elle précise que les clients ne doivent pas relancer automatiquement une requête non idempotente, sauf s’ils savent que sa sémantique est idempotente ou peuvent établir que la requête initiale n’a pas été appliquée. L’approbation ne change pas cette règle. Une personne qui a consenti à un paiement, un déploiement ou une suppression n’a pas consenti à un nombre indéterminé de tentatives.

Utilisez une clé d’idempotence générée lors de la création de l’intention immuable, pas au début de l’exécution. Liez-la au condensat de la charge utile et conservez-la lors des relances sûres. Le service en amont doit renvoyer le résultat d’origine pour une clé en double ou exposer une recherche de statut. Si l’API ne propose ni l’un ni l’autre, la passerelle doit faire passer les mutations ambiguës à l’état inconnu et exiger une réconciliation au lieu de deviner.

Gardez les identifiants d’approbation distincts des identifiants d’idempotence. Une approbation peut autoriser une tentative d’exécution, un ensemble limité de relances identiques ou une capacité de session. Une clé d’idempotence indique au service quelle mutation ne doit avoir qu’un seul effet. Réunir ces deux sens dans un même jeton complique l’expiration, la révocation et l’enquête.

Une séquence de test utile ne nécessite aucun cadre d’injection de panne :

  1. Créez une action approuvée avec un action_id, un condensat et une clé d’idempotence fixes.
  2. Envoyez-la, puis coupez la connexion du client après le départ du corps de la requête.
  3. Redémarrez l’agent local et laissez la reprise inspecter l’état stocké.
  4. Vérifiez qu’il interroge le fournisseur avant toute relance.
  5. Confirmez une seule transition de ressource faisant autorité et une seule chaîne liée d’enregistrements de tentatives.

Exécutez la même séquence lorsqu’une approbation en amont est en attente et lorsqu’elle expire pendant la coupure. Si un redémarrage crée une seconde demande avec un nouvel identifiant, votre chemin de reprise a déjà rompu la chaîne de possession.

Pour les API qui utilisent un point de terminaison de confirmation, examinez sa sémantique. Un modèle à deux appels, comme préparer puis confirmer, n’est sûr que si la confirmation consomme une fois un objet serveur immuable ou applique une clé d’idempotence. Si confirmer ne fait que répéter des champs fournis par le client, il peut s’agir d’un autre point de terminaison de mutation sous un nom rassurant.

Des audits complets relient intention, décision, tentative et résultat

Aucun journal isolé n’est complet à moins qu’un même composant n’observe l’intention proposée, la décision d’approbation, la tentative sortante, l’acceptation par le fournisseur et l’état final de la ressource. Dans la plupart des systèmes réels, l’exhaustivité provient d’enregistrements reliés au-delà de limites de confiance.

L’audit local doit inclure les requêtes refusées et expirées, car elles n’apparaissent jamais en amont. Il doit consigner l’identité du processus et de la session, la version du résumé affiché, le condensat canonique de la charge utile, l’alias de l’identifiant plutôt que le secret, la décision humaine, la tentative sortante, le code de réponse et toute incertitude. L’audit en amont doit inclure le principal faisant autorité, l’objet d’approbation, l’identité de l’examinateur, la version de politique, la version de la ressource, l’événement d’exécution et le statut final.

Utilisez un action_id stable partout où vous avez la main, ainsi que les identifiants d’événements du fournisseur lorsqu’ils existent. Ne reliez pas uniquement sur les horodatages. Les décalages d’horloge, le traitement par lots et les appels simultanés finiront par produire une fausse correspondance.

Cette forme d’événement suffit pour une première mise en œuvre :

{
  "event_id": "evt_01JQ7N2AZ8S4",
  "action_id": "act_01JQ7M6F4R2K",
  "phase": "upstream_result",
  "observed_by": "local_gateway",
  "principal": "service-account:deploy-agent",
  "approver": "org-user:release-reviewer",
  "payload_sha256": "98b0...e42c",
  "provider_event_id": "dep_91358",
  "outcome": "succeeded",
  "recorded_at": "2026-07-24T14:02:18Z"
}

Le chaînage de hachages ou le stockage en ajout seul peut révéler des modifications ultérieures, mais aucun des deux ne prouve qu’un événement omis a eu lieu. Les tests de couverture doivent comparer les phases attendues pour chaque classe d’action. Une lecture peut nécessiter l’intention, la décision locale, la tentative et la réponse. Un déploiement protégé peut aussi nécessiter une attente en amont, une décision en amont, l’exécution et la version finale de la ressource.

La documentation AWS CloudTrail illustre le côté fournisseur des preuves d’identité : ses événements IAM Identity Center peuvent indiquer si une requête provient d’un utilisateur, d’un rôle, d’un utilisateur fédéré ou d’un autre service, et certains événements incluent des identifiants Identity Center. Ce sont des preuves utiles faisant autorité, mais elles ne révèlent toujours pas quel processus d’agent local a formé la requête, à moins de propager des données de corrélation et de conserver l’enregistrement local.

Auditez les chemins de contournement avec autant de rigueur que le chemin principal. L’usage direct d’un identifiant, des profils CLI alternatifs, des points de terminaison API sans protection, le contournement administrateur et la répétition d’un objet serveur approuvé peuvent tous rendre sans intérêt un journal d’approbation parfait. Votre déclaration de couverture doit indiquer les canaux que la barrière contrôle, sans prétendre que « toutes les actions sont approuvées » sans inventaire.

Deux barrières ne sont utiles que si elles restent indépendantes

Conserver les deux côtés de l’approbation
Les journaux Sessions et Activité consignent l’intention locale à côté de la décision du fournisseur.

Superposez les approbations locales et en amont lorsqu’elles contrôlent des faits ou des personnes différents. Retirez-en une lorsqu’elle ne fait que répéter la même décision et ajoute de la fatigue.

Un solide flux de déploiement à deux niveaux peut fonctionner ainsi. La barrière locale vérifie le processus de l’agent et demande au développeur d’autoriser l’usage de la capacité de déploiement pour un seul candidat de version immuable. Elle soumet ce candidat sans exposer l’identifiant. L’environnement en amont demande ensuite à un examinateur éligible des opérations d’approuver la promotion sur la base des contrôles actuels et de l’état de l’environnement protégé. Le journal final relie les deux décisions à une action et à une version déployée.

Un flux superposé faible affiche « déployer en production ? » localement, puis les mêmes mots en amont à la même personne. Aucune demande n’inclut de condensat ou de version, les deux approbations restent valables indéfiniment et l’agent détient le jeton pendant tout ce temps. Le second clic ajoute de la latence sans ajouter de limite de confiance.

La recommandation répandue « toujours approuver au plus près de la ressource » est incomplète. Elle découle d’un bon principe d’application, mais ignore la garde de la capacité et l’identité du processus local. Utilisez l’approbation en amont pour la vérité sur la ressource. Conservez le contrôle local lorsque vous devez contrôler quel processus peut invoquer la capacité ou empêcher le processus de voir le secret.

Sallyport occupe ce rôle local pour les actions HTTP API et SSH : l’agent se connecte via son shim MCP, tandis que les secrets restent dans le coffre-fort chiffré et que l’application exécute l’action. Son autorisation par session et son approbation facultative à chaque utilisation ne remplacent pas l’environnement protégé ni l’examinateur d’organisation d’un fournisseur d’API. Elles ajoutent des preuves sur le processus et l’usage des identifiants du côté local.

Avant de déployer deux barrières, écrivez une phrase pour chacune : « Cette barrière empêche X parce qu’elle seule observe Y et applique Z. » Si les phrases désignent les mêmes X, Y et Z, regroupez-les. Si l’un des composants ne peut pas réellement arrêter l’action décrite, corrigez le point d’application avant de peaufiner sa demande.

Un parcours de déploiement révèle les liaisons manquantes

Prenez le cas d’un agent de programmation autonome qui promeut la version 184 vers un environnement de production dont l’API exige déjà une revue. Un flux sûr préserve une seule intention à travers l’approbation locale, l’attente en amont, l’exécution et la réconciliation.

L’agent propose d’abord une requête canonique contenant l’environnement, la version de publication, la version actuelle attendue et la clé d’idempotence. La passerelle locale attribue action_id, consigne la session du processus et le condensat de la charge utile, puis décide si une approbation locale est requise. L’approbation n’autorise ce condensat que jusqu’à une courte expiration. La passerelle injecte ensuite l’identifiant et soumet la requête préparée.

Le fournisseur crée un objet de déploiement en attente. Son examinateur voit les contrôles actuels, l’environnement protégé, la version exacte et l’identité d’organisation qui a initié l’opération. L’approbation consomme cet objet en attente. Si la production a avancé par rapport à la version attendue, le fournisseur refuse ou rouvre la revue au lieu d’appliquer un consentement obsolète.

Rompez maintenant la connexion après l’approbation en amont. Le côté local ne doit pas renvoyer un succès ni soumettre immédiatement une autre promotion. Il stocke l’état inconnu, interroge le fournisseur avec l’identifiant du déploiement en attente ou la clé d’idempotence et consigne le résultat faisant autorité. Si le fournisseur signale une réussite, le journal local ferme l’action existante. Si le fournisseur n’a aucun enregistrement, la passerelle peut relancer selon le contrat d’idempotence d’origine si l’approbation reste valide.

Ce parcours fait ressortir les questions que les revues d’interface ne voient pas. L’agent peut-il modifier la version après le clic local ? Un autre client peut-il confirmer le déploiement en attente ? Un refus en amont révoque-t-il l’autorisation locale ? Un contournement par un administrateur du fournisseur apparaît-il dans l’enregistrement relié ? Des enquêteurs peuvent-ils prouver quel processus a proposé la version sans faire confiance à une étiquette rédigée par l’agent ?

Choisissez l’architecture à partir de ces réponses. Utilisez uniquement l’approbation locale lorsque l’usage local de la capacité constitue tout le risque et que l’action distante est courante, limitée et récupérable. Utilisez uniquement l’approbation en amont lorsque des clients fiables détiennent déjà des identifiants acceptables et que seul l’état actuel de la ressource ou le rôle d’organisation peut décider. Utilisez les deux lorsque la garde du secret ou la provenance du processus compte localement et que la revue de la transition faisant autorité compte à distance.

Ne promettez pas que deux approbations rendent une action sûre. Elles rendent visibles deux décisions. La sûreté vient du lien entre chaque décision et une intention immuable, de son application à la limite qui détient le fait, de la gestion de l’incertitude sans effets dupliqués et de la conservation de suffisamment de preuves reliées pour reconstituer le résultat après que chacun a oublié la demande.

FAQ

L’approbation en amont est-elle toujours plus sûre que l’approbation locale ?

Non. L’approbation en amont offre un meilleur contexte sur la ressource, mais elle peut intervenir après qu’un agent a déjà reçu un identifiant réutilisable. Le contrôle local est plus solide lorsque la décision porte sur l’identité du processus, la présence de l’utilisateur ou la nécessité de garder les secrets hors de l’agent.

Faut-il deux approbations lorsqu’une API demande déjà une confirmation ?

Seulement si les deux approbations tranchent des points différents. Gardez-les si la barrière locale contrôle l’usage de la capacité et si la barrière en amont contrôle une transition de ressource faisant autorité ou un autre approbateur de l’organisation.

Que doit afficher une demande d’approbation locale ?

Affichez l’identité observée du processus, la session, la destination, l’opération, l’alias de l’identifiant, la ressource cible, un résumé de la charge utile, la portée et l’expiration. Présentez les explications fournies par l’agent comme des affirmations, pas comme des faits fiables.

Que se passe-t-il si le service d’approbation en amont est indisponible ?

L’action doit rester en attente ou expirer. Ne transformez jamais une panne en approbation. Si l’activité l’exige, utilisez une procédure d’urgence autorisée séparément et entièrement journalisée.

Puis-je réutiliser une approbation pour relancer des appels API ?

Oui, mais uniquement dans un cadre défini qui lie la même charge utile immuable et la même clé d’idempotence. Si le statut d’exécution est inconnu, interrogez le fournisseur avant de relancer une mutation.

Combien de temps une approbation doit-elle rester valable ?

Fixez l’expiration selon la vitesse à laquelle les faits examinés changent et le temps nécessaire à un approbateur légitime. Toute modification de la charge utile, de la version cible, de l’identifiant ou de l’éligibilité des approbateurs doit invalider la décision précédente.

Comment corréler les journaux d’audit locaux et en amont ?

Créez un identifiant d’action stable avant l’approbation et propagez-le dans les métadonnées prises en charge par le fournisseur lorsque c’est possible. Stockez localement les identifiants d’événements du fournisseur et les condensats de charge utile. Les horodatages seuls ne constituent pas une jointure fiable.

Une confirmation biométrique identifie-t-elle l’approbateur en amont ?

Elle établit la présence locale d’un utilisateur selon le mécanisme de l’appareil, pas un rôle d’organisation auprès du fournisseur d’API. Consignez séparément les identités humaines locales et en amont au lieu de considérer l’une comme preuve de l’autre.

Les appels API en lecture seule doivent-ils nécessiter une approbation ?

Certaines lectures exposent des données sensibles, le verbe HTTP ne suffit donc pas à décider. Utilisez la classification des données, la portée de l’identifiant, la provenance de l’appelant et le volume pour choisir une approbation de session, une approbation à chaque utilisation ou l’absence de demande humaine.

Quel est le moyen le plus rapide de tester une conception d’approbation ?

Coupez la connexion du client après l’envoi d’une mutation approuvée, mais avant la réception de la réponse. Redémarrez-le et vérifiez que la reprise interroge l’état faisant autorité, conserve les identifiants d’origine et ne produit qu’une seule modification de ressource.

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