8 min de lecture

Des instances de passerelle en double peuvent-elles scinder votre historique d'audit ?

Des instances de passerelle en double peuvent créer une autorité contradictoire et un historique invisible. Testez en sécurité la propriété du coffre, les autorisations, les révocations et l'intégrité de l'audit.

Des instances de passerelle en double peuvent-elles scinder votre historique d'audit ?

Un bundle d'application copié n'est pas une manière anodine de créer une deuxième passerelle locale. C'est un test qui vérifie si le logiciel peut conserver une seule autorité sur les identifiants, les autorisations, les révocations et les preuves lorsque macOS lui présente deux prétendants plausibles.

Le problème dangereux n'est pas toujours un plantage. Un plantage est bruyant. La défaillance plus discrète met en scène deux processus qui semblent tous deux fonctionner normalement, acceptent tous deux les demandes d'un agent et laissent tous deux assez de preuves pour rassurer la personne qui les a lancés. Puis une modification d'identifiant, une révocation ou une analyse d'incident révèle la division : un processus savait quelque chose que l'autre ignorait.

Sallyport est conçu comme une seule application macOS signée, toujours active dans la barre de menus, avec un cœur de coffre exécuté dans le processus. Le lancement simultané des bundles stable, bêta et copiés doit donc être traité comme un test volontaire de concurrence et d'identité, pas comme une pratique normale. Le test doit apporter une réponse précise : le système refuse-t-il le doublon, le coordonne-t-il de manière sûre, ou l'autorise-t-il tout en conservant un seul coffre faisant autorité et un historique vérifiable unique ?

Deux bundles ne signifient pas automatiquement deux identités

Le nom affiché dans le Finder est le signal d'identité le moins fiable dans cette expérience. Sallyport.app, Sallyport Beta.app et Sallyport Copy.app peuvent sembler être trois applications indépendantes pour une personne, tout en contenant le même identifiant de bundle et la même identité de signature dans leurs bundles.

Apple décrit l'identifiant de bundle comme l'identifiant utilisé par macOS pour l'identification au niveau de l'application. Sa documentation sur la signature du code explique aussi qu'une exigence désignée permet au système de reconnaître un code comme celui de la même application au fil des mises à jour. Ces notions sont utiles, mais aucune ne répond à la question qui vous intéresse ici. Le fait que macOS reconnaisse une identité ne prouve pas que deux processus actifs possèdent leur état de manière sûre.

Commencez par noter ce que vous avez réellement lancé. Faites-le avant d'ouvrir le coffre, de connecter un agent ou d'approuver quoi que ce soit.

APP_A="/Applications/Sallyport.app"
APP_B="$HOME/Desktop/Sallyport Beta.app"

for app in "$APP_A" "$APP_B"; do
  echo "=== $app ==="
  plutil -p "$app/Contents/Info.plist" | grep -E 'CFBundleIdentifier|CFBundleShortVersionString|CFBundleVersion'
  codesign -dvv "$app" 2>&1 | grep -E 'Identifier=|TeamIdentifier=|Authority='
  codesign -d -r- "$app" 2>&1 | grep 'designated =>'
done

La forme de la sortie compte davantage que le texte exact :

=== /Applications/Sallyport.app ===
"CFBundleIdentifier" => "..."
"CFBundleShortVersionString" => "..."
Identifier=...
TeamIdentifier=...
designated => identifier "..." and anchor ...

Conservez cet élément avec le dossier de test. Si les deux bundles intacts indiquent le même identifiant et la même exigence désignée, considérez-les comme deux copies d'une même identité de code. S'ils diffèrent, considérez-les comme deux identités de code distinctes. N'utilisez pas des noms comme « stable » et « bêta » à la place de ces faits.

Il faut aussi distinguer deux notions que les équipes confondent souvent : l'identité du code n'est pas l'identité du stockage. Deux processus ayant la même exigence désignée peuvent être censés lire les mêmes données protégées. Deux processus ayant des exigences différentes peuvent recevoir des autorisations système distinctes. Aucun de ces résultats ne dit s'ils peuvent partager un coffre chiffré ou ajouter des entrées à une chaîne d'audit en toute sécurité. Vous devez tester séparément la propriété du stockage.

Un journal d'audit scindé est pire qu'un journal incomplet

Un journal incomplet vous indique que des preuves manquent. Un journal scindé peut raconter deux histoires cohérentes en interne, chacune ignorant les enregistrements détenus par l'autre. L'analyse d'un incident devient alors plus lente, et une session révoquée peut sembler valide du point de vue d'un seul processus.

Pour une passerelle d'action, le journal doit permettre de répondre après coup à des questions concrètes :

  • Quel processus agent a demandé l'action ?
  • Quel processus de passerelle l'a autorisée ou refusée ?
  • Quelle référence d'identifiant a été utilisée sans exposer le secret ?
  • Une personne a-t-elle approuvé la session ou l'appel individuel ?
  • La révocation a-t-elle eu lieu avant ou après l'action ?

Si les processus A et B écrivent chacun une séquence indépendante, les deux séquences peuvent être vérifiées séparément. Ce n'est pas suffisant. La vérification d'une chaîne cryptographique montre que les enregistrements présents dans cette chaîne n'ont pas été modifiés sans détection. Elle ne prouve pas, à elle seule, qu'un autre auteur légitime n'a pas commencé une chaîne distincte ailleurs.

C'est pourquoi il faut distinguer les traces de falsification et l'exhaustivité. Une chaîne de hachage protège la relation entre les enregistrements présents dans cette chaîne. L'exhaustivité exige une règle de propriété claire, un point d'ajout unique ou des preuves durables de chaque branche acceptée et de la manière dont elle a été réconciliée. Si vous vous trompez, un opérateur peut vérifier la chaîne avec succès tout en manquant la moitié des actions.

Le sujet dépasse les journaux. Un historique d'audit scindé suit souvent une autorité scindée :

  • Un processus croit que le coffre est verrouillé tandis qu'un autre dispose d'une session déverrouillée.
  • Un processus révoque une session agent tandis qu'un autre continue de l'accepter.
  • Un processus enregistre une autorisation par appel tandis qu'un autre ne voit aucune raison de demander une confirmation.
  • Un processus écrit le résultat final de l'action tandis que l'autre n'enregistre que la demande.

Ne jugez pas le test sur la capacité des deux copies à terminer un appel HTTP ou une commande SSH. Un appel réussi prouve seulement qu'un chemin existe. Le test est réussi lorsqu'une personne chargée de l'analyse peut reconstituer tout l'historique de l'action sans avoir à deviner quelle copie détenait l'état manquant.

Définissez le contrat de propriété avant de lancer la course

Un test d'instances en double sans invariants attendus ne produit que des anecdotes. Écrivez d'abord le contrat, puis essayez de le briser.

Trois contrats sont défendables pour des copies de passerelle locales.

  1. Propriété exclusive. Le premier processus possède le coffre et les journaux. Les copies suivantes refusent de fonctionner, ramènent la première application au premier plan ou quittent le programme en indiquant clairement la raison.
  2. Un seul processus actif avec transfert. Un nouveau lancement découvre le propriétaire et lui demande d'effectuer le travail. Le nouveau processus ne déverrouille pas, n'autorise pas et n'ajoute pas lui-même d'entrées.
  3. Propriété coordonnée entre plusieurs processus. Plusieurs processus peuvent fonctionner, mais ils utilisent tous un protocole délibéré d'état partagé qui préserve les modifications atomiques du coffre et un ordre unique et vérifiable des événements.

Le premier contrat est généralement le plus facile à raisonner pour une application de bureau qui détient un état important. Le troisième peut être valide, mais il demande beaucoup plus de preuves. « Ils pointent tous les deux vers le même dossier » n'est pas un protocole de coordination.

Écrivez les résultats attendus dans un tableau avant le test. Chaque résultat doit être observable.

ConditionComportement attenduPreuves à conserver
Stable possède un coffre déverrouilléLe lancement de la bêta est refusé, transféré ou coordonnéÉtat de l'interface, liste des processus, réponse de la passerelle
Stable possède un coffre verrouilléAucune copie ne peut exécuter d'action avant l'ouverture de la protection du coffreEnregistrement de la demande refusée et état local
Stable possède une session agent autoriséeUn nouvel agent doit faire l'objet de sa propre décision de sessionEnregistrements d'autorisation avec l'identité du processus
L'autorisation par appel est activée pour un identifiantChaque utilisation demande une confirmation, quelle que soit la copie qui la reçoitUn enregistrement d'autorisation par appel tenté
Une session est révoquée dans un processusAucun processus ne peut poursuivre cette sessionÉvénement de révocation et appel de suivi refusé
Les deux copies demandent une action inoffensive en même tempsL'historique reste complet et vérifiableEnregistrements d'activité ordonnés et vérification d'audit

La formulation compte. « Les copies ne doivent pas entrer en conflit » n'est pas testable. « Un bundle copié ne peut pas renvoyer une réponse d'action réussie après que le propriétaire existant a révoqué la même session agent » est testable.

Séparez aussi le comportement du produit de celui du banc de test. Votre script shell peut empêcher par accident deux lancements, mais cela ne prouve pas que l'application les empêche. Votre proxy inverse peut sérialiser les demandes, mais cela ne prouve pas que le coffre local gère les demandes simultanées. Ne laissez pas le banc de test résoudre le problème que vous vouliez trouver.

Lancez d'abord des copies intactes avant de tester des artefacts modifiés

Une expérience propre commence par des bundles d'application intacts. Copiez un bundle sans modifier les fichiers qu'il contient, placez les copies dans des emplacements ordinaires distincts et notez chaque chemin. Modifier d'abord un exécutable ou un Info.plist invalidera souvent la signature du code, ce qui transforme l'expérience en test de validation de signature.

La note technique TN3127 d'Apple explique pourquoi cette limite compte : macOS s'appuie sur les exigences désignées pour déterminer si un code respecte une identité établie. Si vous modifiez un bundle et que sa signature n'est plus valide, tout refus peut être correct, mais il ne vous apprendra rien sur la propriété en double entre des versions valides.

Utilisez une petite fiche de lancement. Elle doit contenir uniquement des faits observables :

Test ID: duplicate-owner-01
Build A path: /Applications/Sallyport.app
Build B path: /Users/tester/Desktop/Sallyport Beta.app
Bundle IDs: [recorded value A] / [recorded value B]
Designated requirements: [recorded value A] / [recorded value B]
Launch order: A first, B second
Vault state before launch: locked
Agent process IDs: [record after start]
Expected contract: exclusive ownership

Lancez ensuite A, attendez qu'il ait atteint son état inactif, puis lancez B. Notez le résultat avant toute autre action. Un refus doit indiquer assez clairement à l'opérateur quel processus existant possède l'état. Une sortie silencieuse crée des demandes d'assistance et incite à réessayer jusqu'à provoquer une course.

Vérifiez la séparation réelle des processus avec le système d'exploitation plutôt qu'avec les fenêtres de l'application. Une deuxième fenêtre peut appartenir au même processus, tandis qu'un utilitaire auxiliaire en arrière-plan peut créer un deuxième processus même lorsqu'un seul élément est visible dans la barre de menus.

pgrep -alf 'Sallyport|sp mcp|sp-ssh'
ps -axo pid,ppid,start,command | grep -E 'Sallyport|sp mcp|sp-ssh' | grep -v grep

Traitez la sortie comme un élément de chronologie. Enregistrez-la immédiatement après chaque phase de lancement. Incluez autant que possible les identifiants des processus parents. Ils permettent de déterminer si la deuxième action vient d'un processus d'application indépendant, d'un intermédiaire lancé par un agent ou d'un utilitaire enfant.

N'utilisez pas d'identifiants de production pour ce travail. Dirigez les requêtes HTTP vers un point de terminaison de test dédié qui accepte une méthode inoffensive, ou vers un service de test contrôlé. Pour SSH, utilisez un compte dédié avec une restriction de commande ou un hôte sans accès à la production. Vous testez la propriété des processus et le comportement de l'audit. Un point de terminaison destructif ne vous aidera pas à savoir si une deuxième copie peut agir.

La protection du coffre doit avoir un propriétaire visible unique

Rendez la protection du coffre absolue
La protection du coffre refuse toute action lorsqu'il est verrouillé, avec Secure Enclave et Touch ID sur macOS.

La protection du coffre n'est une limite absolue que si chaque chemin d'action passe par la même protection. Si un processus peut rester déverrouillé après qu'un autre a verrouillé le coffre, quitté l'application ou perdu l'accès, « verrouillé » décrit une fenêtre plutôt que l'état réel du système.

Testez d'abord la séquence suivante avec une action HTTP inoffensive :

  1. Démarrez la copie A avec le coffre verrouillé.
  2. Connectez un processus agent par l'intermédiaire de l'interface MCP locale et tentez l'action inoffensive. Attendez-vous à un refus.
  3. Déverrouillez A par l'interaction locale normale, puis répétez l'action. Notez le résultat réussi et son entrée d'activité.
  4. Lancez la copie B pendant que A reste disponible. Ne déverrouillez pas encore B.
  5. Demandez au même processus agent, puis à un nouveau processus agent, de tenter la même action par le chemin accessible de B, s'il en existe un.
  6. Verrouillez A ou quittez l'application, puis répétez les demandes depuis les deux agents.

Le résultat attendu dépend du contrat de propriété, mais le résultat dangereux est facile à nommer : B exécute l'action parce qu'il a conservé ou acquis séparément une autorité que la personne ne pouvait pas voir lorsqu'elle a verrouillé A.

C'est ici qu'un conseil courant échoue : « Partagez simplement l'état déverrouillé pour éviter que la bêta redemande une autorisation. » On le recommande parce que l'authentification locale répétée est pénible pendant le développement. Ce conseil est incorrect si l'état partagé n'a pas de propriétaire défini, de durée claire et de chemin de révocation observé par chaque processus avant toute action. Éviter une demande répétée ne justifie pas la création d'un deuxième état de déverrouillage invisible.

Le modèle de coffre protégé par le matériel fournit une limite de test utile. Tant que le coffre est verrouillé, un agent doit recevoir un refus, pas un secret fictif, une demande partiellement préparée ou une action mise en file qui s'exécuterait après le déverrouillage. Une passerelle d'action doit exécuter elle-même une action autorisée et en renvoyer le résultat. Elle ne doit pas transmettre les identifiants à l'agent en attendant que la personne résolve l'état local.

Enregistrez à la fois la réponse de l'action et les preuves du journal. Un refus qui disparaît de l'historique rend le débogage ultérieur inutilement difficile. Une réussite qui apparaît sans enregistrement de déverrouillage ou d'autorisation préalable est plus grave encore.

L'autorisation de session doit être liée à un processus, pas à un nom

L'autorisation par session permet à une personne de juger une session agent précise. Elle perd son sens lorsque l'autorisation passe d'un processus à un autre parce que les deux sessions ont un nom similaire, s'exécutent depuis le même terminal ou se connectent par le même bundle copié.

L'enregistrement d'autorisation doit permettre de répondre à ces questions : quel exécutable a effectué la demande, qui l'a signé, quand le processus a-t-il démarré et quand son autorité a-t-elle pris fin ? L'autorité de signature du code du processus est particulièrement utile, car une commande de terminal ne suffit pas à identifier le code qui se trouve derrière.

Effectuez ce test avec deux processus agent réellement distincts. Ne réutilisez pas un seul processus shell en le présentant comme deux agents.

# Terminal 1
sp mcp

# Terminal 2
sp mcp

Les commandes sont volontairement simples. L'important est qu'elles proviennent de processus agent distincts dans votre banc de test, puis que chacun envoie un appel inoffensif. Autorisez la première session et laissez la deuxième sans réponse. Si votre configuration affiche les détails du processus dans la carte d'autorisation, capturez l'autorité indiquée et comparez-la au processus lancé.

Essayez ensuite les transitions suivantes :

  • Quittez le processus agent autorisé, puis démarrez un processus de remplacement avec la même commande.
  • Lancez ou activez une passerelle copiée pendant que la première session reste autorisée.
  • Révoquez la première session depuis le journal des sessions.
  • Demandez aux deux processus d'envoyer une nouvelle requête inoffensive.

La règle attendue est simple : une autorisation appartient à une session jusqu'à la fin de celle-ci, et une révocation met fin à l'autorité de cette session partout. Un processus de remplacement ne doit pas hériter de l'autorisation simplement parce qu'il semble familier. Une passerelle copiée ne doit pas interpréter la même connexion agent comme une permission de contourner une décision que son homologue aurait exigée.

Ne confondez pas l'autorisation de session et les clés nécessitant une autorisation par appel. L'autorisation de session indique si ce processus agent peut utiliser la passerelle pendant sa session. Une clé par appel indique si chaque utilisation de cet identifiant précis exige une nouvelle décision humaine. La première concerne la durée de vie de l'appelant, la seconde la sensibilité de l'identifiant. Si vous les mélangez dans vos notes de test, vous interpréterez mal le résultat.

L'autorisation par appel révèle les chemins dupliqués invisibles

Gardez les clés API avec la passerelle
Sallyport exécute lui-même les requêtes HTTP et injecte les identifiants sans les transmettre à l'agent.

Un identifiant qui demande une autorisation à chaque utilisation constitue une bonne sonde pour les instances en double, car il force le logiciel à traiter chaque action séparément. Utilisez un identifiant de test dédié ou une cible SSH dédiée, activez l'autorisation par appel et envoyez des demandes inoffensives simultanées par les deux chemins possibles.

Le test ne consiste pas à demander « ai-je reçu deux demandes d'autorisation ? » Deux demandes peuvent être correctes ou révéler que les deux copies ont créé une autorité indépendante. La vraie question est de savoir si chaque action terminée correspond à une autorisation unique et si une copie peut réutiliser l'autorisation de l'autre.

Construisez un petit registre d'événements pendant le test :

HeureProcessus de passerellePID agentID de demandeDécision humaineRésultat
10:03:01A4128req-a1autoriséeréussite
10:03:02B4194req-b1refuséerefus
10:03:04A4128req-a2autoriséeréussite

Utilisez les identifiants de demande générés par votre point de terminaison de test ou votre banc de test. Ne vous fiez pas à l'ordre d'apparition des fenêtres. La planification du bureau peut réordonner les demandes visibles, et une réponse HTTP peut arriver après une demande ultérieure.

Un mauvais résultat peut sembler propre au départ : vous autorisez la demande A dans la copie A, puis découvrez que la copie B peut terminer la demande B sans sa propre autorisation. Cela indique que l'état d'autorisation a franchi une limite sans décision de l'opérateur. L'échec inverse est également grave : vous autorisez B, mais le résultat apparaît dans le flux d'activité de A sans explication de la raison pour laquelle A a agi.

Répétez la course après avoir verrouillé le coffre, après avoir quitté une copie et après avoir révoqué la première session agent. Ces transitions détectent les états en mémoire obsolètes. Les problèmes les plus révélateurs apparaissent souvent après un changement d'état, lorsqu'un processus a actualisé sa vue et que l'autre ne l'a pas encore fait.

La vérification d'audit nécessite une preuve avant et après

Un rapport qui indique simplement « le journal semblait correct » ne constitue pas une preuve. Capturez une référence initiale, générez un ensemble contrôlé d'actions, vérifiez après l'exécution, puis comparez les enregistrements attendus aux enregistrements observés.

La conception d'audit décrite pour cette passerelle possède un avantage : le même journal chiffré, chaîné par hachage et insensible à l'écriture alimente les journaux des sessions et des activités. Ces journaux doivent donc être deux vues d'un même historique, pas deux enregistrements gérés séparément qui se ressemblent seulement.

Commencez par une période de test vide ou clairement délimitée. Notez l'heure de départ, puis générez une séquence connue : refus lorsque le coffre est verrouillé, action de session autorisée, action autorisée par appel, refus par appel, révocation de session, action refusée après révocation. Gardez la séquence assez courte pour pouvoir rendre compte de chaque événement.

Ensuite, lancez le vérificateur hors ligne :

sp audit verify

Conservez toute la sortie de la commande, y compris un code de sortie différent de zéro en cas d'échec. Le vérificateur ne devrait pas avoir besoin d'accéder au coffre pour contrôler la chaîne de texte chiffré. Cette propriété permet à un enquêteur de vérifier l'intégrité sans déverrouiller d'abord le magasin d'identifiants, ce qui est exactement ce qu'il faut lorsqu'un test de processus en double s'est mal déroulé.

La vérification n'est que le premier contrôle. Comparez trois vues :

  1. Votre registre de test externe, avec chaque identifiant de demande et le résultat attendu.
  2. Le journal des sessions, avec les autorisations, les fins de session et les révocations.
  3. Le journal des activités, avec chaque tentative d'action et son résultat.

Chaque événement du registre doit correspondre à la vue de journal appropriée. Chaque événement de journal de la période de test délimitée doit correspondre à quelque chose que vous avez généré volontairement. Examinez aussi les enregistrements supplémentaires, même si la chaîne est valide. Une action réussie inattendue peut être une nouvelle tentative, une demande mise en file ou la preuve qu'un deuxième processus est resté actif alors que vous pensiez qu'il avait quitté l'application.

Si deux chaînes indépendantes sont vérifiées avec succès, signalez un échec d'exhaustivité de l'historique, sauf si la conception multiprocessus documentée enregistre une relation parent et une fusion déterministe. Ne résolvez pas le problème en concaténant les journaux exportés après le test. Une fusion manuelle produit un rapport, pas un historique d'audit.

Le comportement de récupération détermine si un doublon devient un incident

Révoquez les sessions avec des preuves
Révoquez une session agent depuis le journal des sessions au lieu de laisser une ancienne autorisation active.

Vous devez vous attendre à des interruptions des tentatives de prise de possession. Des personnes forcent l'arrêt des versions bêta. Les ordinateurs portables se mettent en veille. Un banc de test tue un processus entre une autorisation et le résultat d'une action. L'application doit gérer ces cas sans laisser un propriétaire abandonné bloquer indéfiniment le travail ni permettre à un nouveau propriétaire de supposer qu'aucune action n'a eu lieu.

Testez au moins quatre points d'interruption :

  • Tuez la copie A après réception d'une demande, mais avant l'obtention de l'autorisation.
  • Tuez la copie A après l'autorisation, mais avant la fin de l'action externe.
  • Tuez la copie A après la fin de l'action, mais avant que le résultat soit visible par l'agent.
  • Lancez la copie B immédiatement après chaque interruption.

Pour chaque cas, écrivez la règle de récupération sûre avant de l'exécuter. Une règle raisonnable pourrait être que B refuse d'agir jusqu'à ce qu'il puisse établir que A a quitté l'application et récupérer l'état durable. Une autre pourrait être que B ne reprenne qu'à partir des enregistrements d'audit validés et marque toute action incertaine comme inconnue au lieu de la déclarer réussie ou échouée. La règle correcte dépend de l'implémentation, mais deviner n'est jamais acceptable.

Ne masquez pas l'incertitude. Des systèmes externes peuvent terminer une requête HTTP ou une commande SSH au moment où le processus local s'arrête. Si la passerelle ne peut pas prouver si l'opération a abouti, elle doit conserver cette ambiguïté dans les preuves. Réessayer une écriture inconnue peut créer une deuxième action réelle. Prétendre que la première n'a jamais eu lieu crée une fausse histoire d'audit.

C'est aussi le moment d'examiner la révocation immédiate. Révoquez une session agent, terminez immédiatement le propriétaire actuel, lancez une copie et tentez la même action avec cet agent. Si le processus de remplacement considère l'absence de l'état en mémoire comme une nouvelle session, la révocation n'était pas assez durable. Une révocation qui ne fonctionne que tant qu'un processus reste actif n'est pas fiable en cas de panne.

Isolez les tests stable et bêta, sauf si le partage est volontaire

Les versions stable et bêta incitent les équipes à les faire fonctionner ensemble sans précaution, car toutes deux sont utiles. Stable exécute le travail réel. Bêta a besoin d'une pression réaliste. Les faire utiliser le même coffre et les mêmes journaux sans contrat de compatibilité explicite vous donne les risques de la production avec la visibilité limitée d'une expérience.

Utilisez l'une de deux configurations. La plus sûre fournit à la bêta un coffre de test, des identifiants de test, des agents de test et un ensemble de preuves distinct. Cela permet de tester le comportement de la bêta tout en empêchant un processus expérimental de devenir une partie de l'historique des actions de production.

La configuration plus difficile fait partager volontairement l'état entre stable et bêta. Choisissez-la uniquement lorsque la continuité entre versions est précisément le sujet du test. Dans ce cas, testez la différence de version dans les deux sens : stable possède l'état puis la bêta se lance, la bêta possède l'état puis stable se lance, un processus se met à niveau tandis qu'un autre reste ouvert, et un processus revient en arrière après que l'autre a écrit un nouvel historique. Notez si chaque transition est refusée, transférée ou coordonnée.

Pour Sallyport, la séquence de décisions fixe fournit un cadre d'acceptation utile : la protection du coffre reste absolue, un nouveau processus agent reçoit par défaut sa propre autorisation de session et les identifiants marqués pour une autorisation par appel demandent toujours une confirmation à chaque utilisation. L'implémentation peut choisir la propriété exclusive ou un transfert sûr, mais elle ne peut pas affaiblir discrètement ces contrôles pour rendre deux bundles plus pratiques.

Terminez le test par une conclusion claire qu'un autre ingénieur peut remettre en question : quel processus possédait le coffre, ce qui s'est produit lorsqu'une autre copie est apparue, si une action a franchi une limite d'autorisation ou de révocation et si une vérification hors ligne unique couvrait chaque événement généré. Si la réponse dépend de la fenêtre que vous regardiez, recommencez le test. Les preuves ne sont pas encore suffisantes.

FAQ

Est-il sûr d'exécuter deux copies d'une passerelle d'action IA locale ?

Considérez cela comme un test de propriété de l'état, pas comme un simple test visuel. Lancez les copies uniquement dans un environnement de test isolé, gardez visibles leurs identités de processus et leurs emplacements de stockage, et rendez chaque action inoffensive. Le test n'est réussi que lorsque vous pouvez démontrer l'existence d'un coffre faisant autorité et d'un historique complet et vérifiable pour les actions générées.

Une version bêta doit-elle partager le coffre de l'application stable ?

Un canal bêta peut partager l'identité et le stockage avec la version stable, ou isoler volontairement les deux. Les deux choix peuvent être corrects, mais un mélange accidentel ne l'est pas. Si une version bêta peut déverrouiller le coffre de production ou ajouter des entrées au journal de production, documentez ce contrat et testez les mises à niveau, les retours en arrière et les restaurations avec cette configuration.

Renommer un bundle d'application macOS crée-t-il une instance distincte ?

Renommer le dossier .app extérieur ne crée pas nécessairement une identité macOS différente. Examinez l'identifiant du bundle, les détails de signature, le chemin de l'exécutable, l'identifiant du processus en cours et les emplacements de stockage avant de tirer des conclusions. Une copie du bundle peut toujours être reconnue comme la même application signée, ou être rejetée parce que sa signature n'est plus valide.

La signature du code peut-elle empêcher un état de coffre partagé en deux ?

Non. Un bundle signé indique à macOS qui a produit et identifié le code. Il ne prouve pas que deux processus actifs coordonnent correctement leurs écritures. Vous avez toujours besoin d'une règle de propriété explicite, d'un verrouillage, d'un comportement de récupération et d'un test d'audit capable de détecter une bifurcation, pas seulement un plantage.

Quelles preuves faut-il recueillir lors d'un test d'instances en double ?

Un test utile doit suivre une séquence précise : lancement du processus, tentative de déverrouillage du coffre, autorisation de session, demande d'action, résultat, révocation et arrêt. Notez les horodatages, les identifiants de processus, les chemins des exécutables et le résultat de la vérification d'audit après chaque étape. Si vous ne pouvez pas reconstituer le processus qui possédait chaque événement, le test ne fournit pas les preuves nécessaires pour évaluer le résultat.

Puis-je tester des passerelles en double avec des clés API de production ?

N'utilisez pas un identifiant réel sous prétexte que l'application garde les secrets hors de portée de l'agent. Utilisez un point de terminaison de test dédié ou une cible SSH qui accepte une requête en lecture seule, sans effet sur la production. Le but est d'observer le comportement de la passerelle, pas de vérifier si une copie accidentelle peut atteindre une ressource importante.

Que se passe-t-il si deux processus de passerelle écrivent des événements d'audit en même temps ?

Une écriture d'audit concurrente n'est pas automatiquement une corruption, mais elle doit être considérée comme suspecte tant que le système n'a pas démontré l'ordre et l'intégrité des événements. Un journal chaîné par hachage doit avoir un prédécesseur non ambigu pour chaque entrée acceptée, ou un mécanisme défini qui enregistre plusieurs auteurs sans masquer aucune branche. Lancez la vérification hors ligne après la course, puis examinez l'ordre des événements au lieu de vous fier à la réussite d'une action.

Deux processus agent doivent-ils partager une même autorisation ?

L'autorisation de session doit être liée à un processus agent concret, pas simplement à un nom d'application, une fenêtre de terminal ou une intention générale de l'utilisateur. Notez l'identité du processus affichée lors de l'autorisation et vérifiez qu'un second processus agent reçoit sa propre décision. Sinon, une autorisation peut s'étendre à une action que la personne n'a jamais examinée.

Dois-je modifier le bundle de l'application pour tester les instances en double ?

Commencez par des bundles copiés, pas par des bundles modifiés. Modifier une application à l'intérieur du bundle peut invalider sa signature et transformer la question en test de gestion d'un code non signé. Établissez d'abord le comportement avec des artefacts intacts, puis créez un cas de test distinct pour l'échec de signature si cette limite compte pour votre processus de publication.

À quoi ressemble un test réussi d'une passerelle en double ?

Un résultat correct consiste en un refus explicite, un transfert vers un processus unique ou une conception coordonnée à état partagé qui conserve la cohérence du coffre et de l'historique d'audit. Le mauvais résultat est celui de deux processus qui semblent fonctionner normalement tout en conservant chacun une vision différente des autorisations ou de l'historique. La commodité ne compte pas si un opérateur ne peut pas démontrer plus tard quel processus a exécuté une action.

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