8 min de lecture

Le nettoyage d’un processus distant fonctionne-t-il après une annulation SSH ?

Le nettoyage d’un processus distant après l’annulation SSH exige des groupes de processus, un état durable, des tests avec des processus enfants et un plan honnête en cas de déconnexion.

Le nettoyage d’un processus distant fonctionne-t-il après une annulation SSH ?

Une exécution annulée par un agent n’est pas forcément la même chose qu’une commande distante arrêtée. Le processus local peut se terminer proprement alors que le transport SSH est encore actif. Le transport peut disparaître tandis que le shell distant continue de fonctionner, et le shell peut mourir alors que ses enfants poursuivent leur activité dans un autre groupe de processus. Si vous réduisez tous ces événements à un seul état appelé « annulé », vous finirez par laisser une migration de base de données, une installation de paquet, un worker de tests ou un outil de déploiement fonctionner après que l’agent a annoncé son arrêt.

La solution ne consiste pas simplement à écrire un piège à signaux ingénieux. Il faut un contrat d’annulation qui nomme l’exécution distante, crée une limite contrôlable autour de ses descendants, conserve suffisamment de sortie pour diagnostiquer une interruption et prévoit ce que doit faire le côté distant lorsque le contrôleur disparaît. Concevez et testez ce contrat avant d’autoriser un agent à lancer des commandes produisant des effets de bord.

L’annulation SSH comporte quatre étapes distinctes

Une demande d’annulation doit franchir quatre frontières : l’agent décide de s’arrêter, le superviseur local arrête ou signale son client SSH, le protocole SSH transporte un événement de canal ou un signal, puis l’hôte distant agit sur cet événement. Chaque étape peut échouer indépendamment.

RFC 4254 sépare ces notions. Il définit un message de fermeture de canal et, séparément, une demande de canal signal pour des noms comme TERM, INT et HUP. La fermeture d’un canal est un événement de transport. Elle ne signifie pas « envoyer SIGTERM à tous les descendants distants ». La RFC précise également que les données envoyées avant la fermeture doivent être livrées si possible. Cette réserve compte beaucoup lorsqu’un ordinateur portable se met en veille, qu’une route réseau disparaît ou qu’un processus local est arrêté de force.

Cette distinction met en évidence une conception défaillante fréquente :

  1. Un agent lance ssh host long-command.
  2. L’utilisateur appuie sur Annuler.
  3. Le lanceur de l’agent tue son processus enfant local.
  4. L’interface marque la tâche comme annulée.
  5. long-command, ou l’un de ses enfants, continue sur l’hôte distant.

La cinquième étape n’est pas un cas exceptionnel. C’est le résultat normal lorsque le serveur n’a aucune raison d’arrêter la commande ou lorsque celle-ci s’est détachée de la session avant la disparition de la connexion.

Un contrat d’annulation utile décrit précisément ce que le côté local tente de faire et ce qui relève du côté distant :

  • Le lanceur crée une exécution distante identifiable avec un identifiant aléatoire.
  • Le wrapper distant démarre la charge de travail dans son propre groupe de processus ou sa propre session.
  • Une annulation normale envoie TERM à ce groupe et enregistre le résultat.
  • Le wrapper ne passe à KILL qu’après un délai de grâce défini.
  • Une échéance ou un bail distant termine le travail lorsque le contrôleur ne revient jamais.
  • La sortie et l’état final survivent au flux SSH.

Ne qualifiez pas une tâche d’annulée tant que vous n’avez pas obtenu l’un de deux résultats : un enregistrement final distant confirmé ou un résultat explicite indiquant que l’état est inconnu. Feindre la certitude après une perte de connexion ralentit la résolution des incidents, car tout le monde part d’une hypothèse fausse.

Un PID distant ne suffit pas à nettoyer les enfants

Tuer le PID du shell distant n’est sûr que si le shell ne crée jamais de processus enfants, ne lance pas de pipeline, ne démarre pas de processus en arrière-plan et n’appelle pas d’outil qui crée des auxiliaires. Peu de commandes répondent à ces conditions.

Considérez cette commande distante courante :

build-assets | tee build.log &
wait

Le shell possède un PID, mais le pipeline contient plusieurs processus. tee peut encore écrire dans son journal après la fin du shell. Un compilateur peut créer des workers. Un gestionnaire de paquets peut transmettre le travail à un service. Si vous exécutez kill -TERM "$shell_pid", vous terminez un membre d’un groupe plus vaste sans savoir ce que font les autres.

Les groupes de processus fournissent la bonne unité d’annulation pour une exécution distante de courte durée. Sous Linux, chaque processus appartient à un groupe de processus et chaque groupe appartient à une session. Les signaux générés par le terminal sont envoyés au groupe de processus au premier plan, ce qui explique pourquoi le comportement d’un terminal peut sembler plus mystérieux qu’il ne l’est. La documentation Linux de setpgid(2) précise également qu’un enfant hérite du groupe de processus de son parent, sauf modification explicite.

Pour une commande contrôlée par un agent, créez une session nouvelle pour la charge de travail. Le leader de session possède normalement un PID égal à son PGID et à son SID. Un PID négatif dans kill désigne alors le groupe de processus :

kill -TERM -- -"$pgid"

Le signe moins initial fait la différence entre l’arrêt d’un processus et celui de son groupe. -- est également important : il empêche qu’une valeur mal formée soit interprétée comme une option.

Ne supposez pas aveuglément que le PID de la charge de travail est son identifiant de groupe. Vérifiez-le au lancement. Un wrapper shell, un gestionnaire de services ou un programme qui appelle setpgid peut modifier l’arbre. Voici la plus petite commande d’inspection utile dans votre kit de test :

ps -o pid=,ppid=,pgid=,sid=,stat=,etime=,command= -p "$pid"

Une sortie typique ressemble à ceci :

24182  24177  24182  24182 Ss       00:03 bash ./worker.sh /tmp/agent-runs/6c4...

Ici, le PID, le PGID et le SID correspondent. Cela indique que kill -TERM -- -24182 cible bien la limite prévue. Si le PGID ne correspond pas à l’enregistrement de l’exécution, échouez au lancement au lieu de deviner.

Un groupe de processus a néanmoins ses limites. Un enfant peut appeler setsid, un runtime de conteneur peut déplacer un processus et une charge de travail peut demander à un gestionnaire de services d’exécuter quelque chose hors du groupe. Ce comportement peut être légitime, mais votre garantie d’annulation s’arrête à ce transfert. Traitez le travail détaché comme un type de tâche distinct, avec sa propre identité, son opération d’arrêt et son enregistrement d’audit.

Un wrapper d’annulation a besoin d’un vrai chemin de nettoyage

Un wrapper shell distant doit posséder le PID de la charge de travail, intercepter les signaux de terminaison attendus, cibler le groupe de la charge de travail, attendre brièvement et écrire un enregistrement final. Il ne doit pas utiliser pkill nom-de-commande, analyser une liste de processus imprécise ou tuer tous les processus d’un compte. Ces raccourcis fonctionnent jusqu’au jour où deux exécutions d’agent partagent un utilisateur, où le nom d’hôte change ou où un nom de commande correspond au travail de quelqu’un d’autre.

Cette fixture orientée Linux reste volontairement simple. Elle crée un répertoire d’exécution protégé, démarre une charge de travail dans une session nouvelle, écrit la sortie dans des fichiers et termine le groupe de la charge lorsque le wrapper reçoit TERM, INT ou HUP.

Le wrapper doit notamment écrire un état temporaire, le renommer atomiquement en status.json, attendre le processus enfant et n’utiliser KILL qu’après une période de grâce clairement définie. Le principe essentiel est que le signal reçu par le wrapper atteigne le groupe de la charge de travail, pas uniquement le wrapper lui-même.

Ce mécanisme évite un échec précis : le signal d’annulation atteint le wrapper, mais celui-ci ne se tue que lui-même et laisse la charge active. Il ne promet pas d’arrêter les descendants volontairement détachés, et ne devrait pas le promettre. La documentation Linux de setsid(2) indique que setsid() crée une session nouvelle et fait de l’appelant le leader d’un nouveau groupe de processus, initialement sans terminal de contrôle. La commande util-linux setsid exécute un programme dans cette nouvelle session, en créant un processus enfant si nécessaire. C’est une limite pratique pour une exécution, pas un interrupteur magique de nettoyage.

Gardez le wrapper étroit. Il doit lancer, enregistrer, arrêter et rendre compte. Ne lui confiez pas la logique métier. La charge de travail doit conserver ses propres règles de transaction, de nettoyage des fichiers temporaires et d’idempotence.

Une déconnexion propre du transport ne garantit pas le nettoyage

Les utilisateurs de SSH tirent souvent trop de conclusions d’un test dans un terminal. Ils lancent une commande avec un PTY, ferment le terminal, voient un processus se terminer après SIGHUP et concluent que le nettoyage lors d’une déconnexion fonctionne. Puis un agent utilise un canal SSH non interactif sans PTY et le comportement change.

Un PTY apporte la sémantique d’un terminal. Une fermeture de terminal peut entraîner l’envoi de SIGHUP, mais seulement dans les conditions qui régissent les terminaux de contrôle et les groupes de processus au premier plan. La documentation Linux décrit SIGHUP comme la fermeture d’un terminal de contrôle ou la mort d’un processus de contrôle. Elle ne dit pas que chaque déconnexion SSH signale tous les processus lancés par SSH.

Le SSH non interactif est généralement le meilleur choix par défaut pour les agents, car il fournit une sortie plus propre et limite les surprises liées au démarrage du shell. Il évite aussi toute dépendance accidentelle au comportement d’un terminal. Utilisez un PTY uniquement lorsque le programme distant en a besoin, par exemple pour un ancien installateur qui refuse de fonctionner autrement. Documentez alors que le PTY fait partie du comportement de la commande et testez-le séparément.

Il faut distinguer trois cas de déconnexion :

Le client envoie une annulation volontaire

Le superviseur local dispose encore d’une connexion active et peut envoyer un signal de protocole, ou ouvrir une action de contrôle authentifiée distincte qui signale le PGID enregistré. C’est le meilleur scénario. Le wrapper distant reçoit TERM, nettoie le groupe et écrit cancelled:TERM.

Ne présumez pas qu’un client SSH recevant localement SIGINT fera exactement cela sans tester la bibliothèque et l’invocation réellement utilisées. Un client de terminal, une bibliothèque SSH intégrée et un outil MCP peuvent associer l’annulation locale à des comportements différents. Certains ferment une socket, certains terminent le processus local et certains peuvent envoyer une demande SSH signal. Ce sont des implémentations différentes d’une interface que l’utilisateur appelle « annuler ».

Le client local plante ou perd le réseau

La commande distante peut continuer. Le serveur ne peut pas distinguer une panne temporaire de routage d’un utilisateur qui veut que le travail continue, à moins que votre protocole ne lui indique comment le faire. Un bail distant est la réponse honnête.

Au lancement, écrivez un deadline_epoch dans le répertoire distant de l’exécution. Un superviseur local le renouvelle tant que l’exécution reste autorisée. Un watchdog distant le vérifie et appelle le même chemin de nettoyage du groupe après expiration. Choisissez une durée adaptée à l’opération. Un bail de cinq minutes peut convenir à une commande shell, mais être imprudent pour une compilation comportant de longues phases silencieuses normales.

L’hôte distant tombe en panne ou redémarre

Vous pouvez perdre à la fois le processus et l’état final. Ne signalez pas « annulé » ou « terminé » simplement parce que la connexion SSH s’est interrompue. Marquez l’exécution comme inconnue jusqu’à ce qu’une réconciliation ultérieure consulte le journal de l’hôte, l’état du déploiement, un enregistrement de verrou ou le résultat propre à l’application.

La difficulté n’est pas d’émettre un mot d’état. Elle consiste à refuser d’émettre un état que votre système ne peut pas justifier.

Une sortie partielle prouve une observation, pas une fin

Séparez les commandes des identifiants
L’agent reçoit les résultats des commandes, pas la clé privée SSH qui sert à exécuter l’action distante.

Un flux répond à la question « quels octets le client a-t-il reçus jusqu’ici ? ». Il ne répond pas à « dans quel état la commande distante a-t-elle laissé le système ? ». Cette confusion apparaît lorsqu’un programme distant affiche done avant de vider son dernier fichier ou lorsque le réseau tombe après la fin de la commande, mais avant la réception du statut de sortie SSH.

Conservez deux enregistrements :

  • stdout.log et stderr.log contiennent la sortie de diagnostic produite par la charge de travail.
  • status.json est un petit enregistrement final écrit atomiquement après l’observation de la sortie ou la gestion de l’annulation par le wrapper.

Écrivez un fichier de statut temporaire dans le même répertoire, puis renommez-le. Les lecteurs voient soit l’ancien fichier complet, soit le nouveau fichier complet. Ils ne doivent jamais analyser la moitié d’un document JSON et inventer un résultat.

La sortie elle-même doit obéir à des règles. Une commande peut fortement mettre en tampon sa sortie lorsque stdout est un fichier plutôt qu’un terminal. Si la progression compte, demandez à la charge d’émettre explicitement un état ligne par ligne sur stderr ou utilisez un fichier de progression au niveau applicatif. Ne résolvez pas le problème du tampon en allouant un PTY à chaque commande. Cela modifie le comportement et peut fusionner stdout et stderr, ce qui complique l’audit et l’analyse des échecs.

Traitez différemment ces situations dans l’interface ou le journal de l’agent :

Enregistrement distantÉtat du fluxSignification
finished, code de sortie présentcompletLe wrapper a observé une fin normale.
cancelled:TERMpeut s’arrêter brusquementLe wrapper a commencé l’annulation et arrêté son groupe.
seulement cancelling:TERMdéconnectéLe nettoyage a commencé, mais l’enregistrement final n’a pas été observé. Il faut réconcilier.
seulement running, bail validedéconnectéLe travail peut encore fonctionner. Ne relancez pas aveuglément.
aucun enregistrement exploitabledéconnectéL’état est inconnu. Vérifiez les effets de bord avant de relancer.

Évitez de placer des jetons d’accès, des dumps de configuration non expurgés ou des identifiants dans ces journaux. L’injection des identifiants SSH peut garder la clé privée hors de portée de l’agent, mais une commande distante peut tout de même afficher des secrets lus dans son propre environnement ou sa configuration. La conservation de la sortie fait partie de la conception de la commande.

Testez les arbres de processus, pas un seul shell inactif

trap 'exit' TERM; sleep 600 est un test d’annulation faible. Il prouve qu’un shell au premier plan peut recevoir un signal. Il ne teste ni les enfants, ni les groupes de processus, ni le nettoyage différé, ni la conservation de la sortie, ni la disparition du shell distant au mauvais moment.

Utilisez une charge de travail qui crée un arbre de processus visible et enregistre chaque signal. Sur un hôte Linux jetable, testez un worker qui crée un petit-enfant, écrit son PID, son PGID et les signaux reçus dans un journal, puis lancez-le via le wrapper avec un identifiant aléatoire.

Testez ensuite séparément les chemins d’échec suivants :

  1. Envoyez TERM au PID du wrapper. Vérifiez que le parent et le petit-enfant ont enregistré leur terminaison et que ps ne trouve plus de processus dans le PGID enregistré.
  2. Envoyez TERM directement au PID de la charge. Vérifiez que le comportement de ses enfants n’est pas supposé sûr. Ce test explique pourquoi le wrapper cible un groupe.
  3. Tuez le client SSH local sans envoyer de signal distant. Vérifiez que la charge reste active jusqu’à l’expiration de son bail distant. Si elle s’arrête immédiatement, notez pourquoi, par exemple à cause du comportement de déconnexion d’un PTY, au lieu de considérer ce résultat comme universel.
  4. Déconnectez-vous après l’écriture de cancelling:TERM mais avant l’enregistrement final. Vérifiez que la réconciliation distingue une observation incomplète d’une nouvelle tâche en cours.
  5. Lancez deux exécutions sous le même compte, annulez-en une et prouvez que l’autre reste active. Cela détecte les appels dangereux à pkill et les nettoyages visant tout un compte.

Utilisez ps et pgrep -a -g "$pgid" pendant le test, puis recommencez après le délai de grâce. Consultez l’état distant et les journaux seulement après avoir vérifié la table des processus. Un statut indiquant « annulé » alors que des workers sont encore actifs est un défaut du superviseur, pas une simple différence de reporting.

Les signaux de mort du parent ne servent que dans un worker maîtrisé

Confirmez chaque arrêt destructif
Demandez Touch ID ou un clic pour chaque utilisation d’une clé SSH configurée pour une approbation à chaque appel.

Linux fournit PR_SET_PDEATHSIG, qui permet à un processus de demander au noyau de lui envoyer un signal lorsque le thread qui l’a créé se termine. Cela peut être utile pour un petit helper natif que vous contrôlez, lorsqu’il crée un enfant immédiat et veut que celui-ci s’arrête en cas de mort du helper. Le réglage survit normalement à execve, mais le manuel décrit des exceptions importantes, notamment les changements d’identifiants.

Cela ne résout pas à lui seul le nettoyage d’un agent distant.

Le processus du serveur SSH n’est pas forcément le parent qui vous intéresse. Le signal s’applique au processus qui l’a défini, pas automatiquement à tous ses descendants. Un programme distant qui fork, double-fork ou transmet le travail à un autre service abandonne cette relation. Enfin, le mécanisme est propre à Linux, ce qui compte dans un parc Unix hétérogène.

Utilisez-le uniquement comme renfort lorsque l’arbre de processus vous appartient. Un worker Linux peut par exemple définir PR_SET_PDEATHSIG avant d’exécuter un enfant contrôlé, tandis que le wrapper externe conserve la responsabilité du groupe et du bail. Vous obtenez ainsi deux détecteurs d’échec de portée différente. Cela ne dispense ni de la limite de groupe ni de l’enregistrement final distant.

Le même avertissement vaut pour nohup, disown et setsid utilisés dans la charge de travail. Ils sont utiles lorsqu’une personne veut délibérément qu’un travail survive à un terminal. Ils sont incompatibles avec la promesse qu’une annulation d’exécution d’agent arrête le travail. Rendez ce choix explicite au lancement.

Un second canal de contrôle est souvent plus propre que tuer le premier

Bloquez complètement les actions SSH
Lorsque le coffre est verrouillé, Sallyport refuse toute action SSH au lieu de laisser un agent conserver des identifiants utilisables.

Lorsqu’un agent annule un appel SSH en cours, son propre contexte local peut déjà être en train de se fermer. Compter sur ce processus mourant pour envoyer un dernier signal de protocole crée des courses. Un processus superviseur distinct devrait posséder l’annulation et la réconciliation.

Une conception possible est la suivante :

  1. Le superviseur génère un identifiant d’exécution cryptographiquement aléatoire et invoque le wrapper distant.
  2. Le wrapper enregistre son PID, son PGID, son heure de début et son état dans un répertoire portant cet identifiant.
  3. Le superviseur enregistre l’identifiant et l’hôte distant avant de commencer à consommer la sortie.
  4. Lors d’une annulation, le superviseur ouvre une action de contrôle indépendante qui lit l’enregistrement, vérifie la propriété et l’âge attendus, puis signale le PGID enregistré.
  5. Le superviseur interroge l’état final jusqu’à obtenir un état terminal ou atteindre une échéance de reporting.

L’action de contrôle doit valider l’enregistrement avant de signaler quoi que ce soit. Vérifiez au minimum que le répertoire appartient à l’utilisateur attendu, que le PID existe encore, que le PGID enregistré correspond à ps et que l’heure de début correspond au processus lancé. Linux peut réutiliser les PID. Un ancien fichier PID associé à un kill inconditionnel peut terminer un travail sans rapport plusieurs semaines plus tard.

Ne cachez pas la commande de nettoyage derrière une instruction générique de l’agent telle que « tue le processus de ma tâche précédente ». L’agent doit recevoir une référence opaque. Le superviseur transforme cette référence en action distante étroitement limitée. L’audit devient également lisible : on voit que l’exécution 6c4... a demandé l’annulation du PGID 24182 sur un hôte précis, et non qu’un agent a fabriqué une commande kill arbitraire.

Pour les agents de programmation autonomes, Sallyport peut exécuter des actions SSH sans exposer la clé SSH à l’agent. Cela sépare la garde des identifiants du contrat d’annulation, qui nécessite toujours une référence d’exécution, une vérification du groupe, un bail distant et un enregistrement final.

La décision de relancer dépend de l’effet de bord

Une commande qui ne fait que lire un fichier peut généralement être relancée après une déconnexion dont l’état est inconnu. Une commande qui crée un utilisateur, applique une migration, renouvelle un certificat ou démarre un déploiement ne le peut pas. La couche SSH ne sait pas si l’opération peut être répétée sans danger.

Donnez aux commandes distantes qui produisent des effets de bord un jeton d’idempotence dérivé de l’identifiant d’exécution. Le programme distant doit enregistrer ce jeton avec le résultat de l’opération et retourner le résultat existant s’il revoit le même jeton. Si cela est impossible, ajoutez une requête préalable qui détermine si la modification demandée a déjà eu lieu.

Ne remplacez pas l’idempotence par le nettoyage. Même un TERM parfait peut arriver après l’acceptation d’une requête par une API distante, mais avant l’affichage de sa réponse. Même un KILL peut arriver après la validation d’une transaction de base de données. Le nettoyage des processus indique si le worker s’exécute encore. Il n’annule pas les effets externes.

Conservez trois résultats dans le plan de contrôle : terminé, annulé avec nettoyage confirmé et inconnu. L’état inconnu est inconfortable, mais il donne à l’opérateur suivant l’information nécessaire : inspecter l’état distant avant d’effectuer une nouvelle action. C’est bien préférable à un bouton de relance vert fondé sur une supposition.

Une fonctionnalité d’annulation est prête lorsque vous pouvez l’interrompre à chaque frontière et expliquer l’arbre de processus restant, la sortie sur disque, l’enregistrement final et la décision de relance. Si vous ne pouvez pas le faire sur un hôte jetable, ne lui faites pas confiance sur un hôte de production à deux heures du matin.

FAQ

Comment arrêter une commande SSH distante lorsqu’un agent d’IA l’annule ?

Traitez l’annulation comme une action de contrôle distincte, et non comme la simple fin du client SSH local. Envoyez un signal à un groupe de processus distant enregistré, attendez pendant une période de nettoyage limitée, puis vérifiez l’état final de l’exécution dans un enregistrement durable. Si le chemin de contrôle a déjà disparu, un bail distant ou un watchdog doit déterminer quand arrêter le travail.

La fermeture d’une connexion SSH tue-t-elle la commande distante ?

Non. La fermeture d’un canal SSH termine le canal, mais ne garantit pas que le serveur enverra SIGTERM à la commande ou à ses descendants. Un PTY peut modifier le comportement avec des signaux de déconnexion du terminal, mais cela ne constitue toujours pas un contrat de nettoyage fiable.

Comment tuer les processus enfants lancés par un script shell distant ?

Utilisez un groupe de processus ou une session dédiée pour chaque exécution distante, puis envoyez le signal au PGID négatif, par exemple kill -TERM -- -12345. Vérifiez ensuite le PGID avant de vous y fier. Tuer uniquement le PID du shell laisse les processus en arrière-plan, les pipelines et les sous-processus actifs.

Devrais-je utiliser setsid pour les commandes distantes d’un agent ?

Une invocation normale de setsid crée une nouvelle session et un nouveau groupe de processus pour la commande lancée. Le superviseur dispose ainsi d’un groupe unique à arrêter. Ne l’utilisez pas pour un travail qui doit survivre à l’annulation. Vérifiez le SID et le PGID obtenus avec ps, car les wrappers et les gestionnaires de services peuvent modifier l’arbre.

Comment nettoyer après une déconnexion SSH ou une panne réseau ?

Un processus distant doit avoir une durée maximale ou un bail renouvelable si le laisser fonctionner présente un risque ou un coût important. Le bail doit vivre sur l’hôte distant, car un client déconnecté ne peut pas signaler de manière fiable qu’il a disparu. Un signal d’annulation peut arrêter rapidement le travail, tandis que le bail couvre le cas où ce signal n’arrive jamais.

Puis-je faire confiance à une sortie partielle après la rupture d’une connexion SSH ?

Utilisez la sortie du flux pour observer le travail, mais écrivez-la aussi dans un fichier distant ou un journal. Conservez un enregistrement de fin distinct, écrit uniquement après la sortie de la commande et la fin du nettoyage. Un flux interrompu indique un échec de livraison, pas si la commande s’est terminée.

PR_SET_PDEATHSIG suffit-il pour nettoyer les processus distants ?

Cette fonctionnalité est propre à Linux et aide seulement un processus à détecter la mort de son parent direct. PR_SET_PDEATHSIG ne couvre pas automatiquement les petits-enfants, et des changements de privilèges peuvent supprimer ce réglage. Utilisez-le comme renfort local dans un worker conçu à cet effet, pas comme seul mécanisme d’arrêt de commandes arbitraires.

Un agent doit-il allouer un PTY pour les commandes SSH distantes ?

En général, non. Un terminal modifie la distribution des signaux, la mise en tampon et le comportement des programmes. Une commande non interactive fournit une sortie plus propre pour les machines. N’allouez un PTY que si le programme distant a réellement besoin de la sémantique d’un terminal, puis testez séparément le comportement lors d’une déconnexion.

Que doit contenir un enregistrement d’audit d’annulation SSH ?

Enregistrez un identifiant d’exécution aléatoire, l’identité de l’hôte distant, le PID de départ, le PGID, le SID, l’heure de lancement, la commande demandée et le résultat final. Protégez l’enregistrement distant contre les autres utilisateurs et rendez la mise à jour finale atomique. Un PID seul est une preuve faible, car les PID peuvent être réutilisés.

Un agent peut-il exécuter sans risque un travail destructif via SSH ?

Ne distribuez pas une commande SSH sans limite en considérant que le travail est annulé dès que le processus local se termine. Exigez une référence d’exécution, une vérification du groupe de processus, une échéance de nettoyage et un état final distant. Sallyport peut garder l’identifiant SSH hors de portée de l’agent, mais la conception de la commande distante détermine toujours si l’annulation est 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