Quand les mises à jour des binaires d'agents doivent-elles perdre leur confiance ?
Les mises à jour de binaires d'agents exigent une nouvelle décision de confiance. Découvrez comment vérifier la signature macOS, la provenance de l'éditeur, le contexte du processus et les accès demandés.

L'approbation d'un agent local devrait s'appliquer à l'exécutable que vous avez examiné, dans le processus que vous avez approuvé, pour les accès qu'il demandait à ce moment-là. Quand l'exécutable change, l'ancienne approbation a expiré dans les faits, même si son nom de fichier, son identifiant de bundle et son icône restent identiques.
Cela peut sembler strict jusqu'au jour où vous devez analyser une approbation accordée à la version 1.8, puis utilisée discrètement par la version 1.9. Les mauvaises décisions commencent souvent par une vérification d'identité trop large : un chemin, un nom de produit ou un Team ID de signature familier. Ces éléments peuvent apporter des preuves. Aucun ne devrait, à lui seul, maintenir une confiance privilégiée après une modification du code.
La confiance appartient à un exécutable observé
Un agent local n'est pas une identité d'éditeur. C'est un programme signé précis, chargé à un chemin donné, avec un processus parent, des arguments, un environnement et un ensemble d'actions demandées précis. Un éditeur peut publier de nombreux programmes. Un même programme peut changer fortement d'une version à l'autre. Un nom stable ne dit presque rien sur ces deux points.
Cette distinction compte surtout quand l'agent peut appeler des API payantes, utiliser des identifiants SSH, modifier un dépôt ou envoyer des données hors de la machine. Une approbation n'est pas un compliment adressé au fournisseur. C'est l'autorisation donnée à un processus d'effectuer des actions qui ont des conséquences.
Gardez ces identités séparées :
- L'identité du fichier correspond au code signé et à son condensat sur le disque.
- L'identité de signature correspond à l'autorité que macOS indique pour ce code.
- La provenance de l'éditeur correspond aux éléments montrant que le fichier est arrivé par le circuit de publication attendu.
- L'identité d'exécution comprend le processus qui l'a lancé et les accès qu'il demande.
Les équipes confondent souvent les quatre et concluent : « c'est notre agent ». C'est ainsi qu'un remplacement au même chemin hérite d'accès qu'il n'a jamais mérités. La règle sûre est simple : le remplacement d'un exécutable ouvre une nouvelle décision de confiance.
Un hachage détecte un remplacement, mais ne dit pas qui a signé le nouveau fichier. Une signature identifie un signataire, mais ne prouve pas le canal de téléchargement. Un téléchargement propre ne dit pas si la nouvelle version a besoin d'accès plus larges. Il faut les trois vérifications, car chacune détecte un problème différent.
Ne commettez pas l'erreur inverse en verrouillant chaque octet pour toujours. Les compilations changent légitimement, les certificats sont renouvelés et les versions doivent être mises à jour. Le but n'est pas la permanence. Il faut que quelqu'un voie le changement, établisse ce qui a changé et décide explicitement si l'autorité demandée reste justifiée.
La signature de code répond à une question plus limitée qu'on ne le pense
La signature de code de macOS permet au système de vérifier qu'un code signé n'a pas changé depuis que le signataire a produit cette signature. Pour une distribution Developer ID, Gatekeeper évalue aussi l'identité du développeur et son appréciation de l'élément. C'est une preuve utile, mais pas un verdict complet sur la chaîne d'approvisionnement.
La note technique d'Apple TN2206, « macOS Code Signing In Depth », distingue l'identité du code des conditions plus larges dans lesquelles le système accepte ce code. Sa description des exigences désignées est particulièrement pertinente ici : macOS peut utiliser une exigence pour reconnaître une future version comme appartenant à la même identité de code. Cette continuité aide les mises à jour ordinaires d'applications. Elle est trop faible comme seule condition pour un agent capable de dépenser de l'argent ou d'utiliser une infrastructure privée.
Une signature valide ne répond pas aux questions suivantes :
- L'éditeur voulait-il que cette version précise arrive sur votre machine ?
- Une clé de publication compromise de l'éditeur l'a-t-elle signée ?
- La nouvelle version a-t-elle ajouté une capacité qui modifie son niveau de risque ?
- Un installeur, un programme de mise à jour ou un script de lancement a-t-il remplacé un composant sans modifier la partie que vous aviez vérifiée ?
Gatekeeper et la notarisation réduisent le risque que macOS exécute un logiciel manifestement non fiable. Ils ne transforment pas un agent correctement signé en détenteur approuvé de votre autorité opérationnelle. Traitez l'admission par le système et l'approbation des actions privilégiées comme deux décisions distinctes.
Il en va de même pour le renouvellement d'un certificat. Un certificat renouvelé peut être une simple opération administrative. Il modifie néanmoins les éléments sur lesquels vous fondez votre confiance. Si le Team ID, l'identifiant et le circuit de publication attendu restent cohérents, un opérateur peut approuver la mise à jour après examen. Si l'autorité de signature passe à une autre organisation, arrêtez-vous et demandez une explication claire à l'éditeur. N'acceptez pas un changement d'identité inattendu sous prétexte que l'application se lance sans avertissement.
La provenance de l'éditeur est distincte de la signature
La provenance concerne la manière dont le binaire vous est parvenu et la conformité de ce chemin avec les pratiques habituelles de publication de l'éditeur. La signature d'un fichier copié depuis une pièce jointe reçue dans une conversation inconnue vous indique qui a signé cette copie. Elle n'explique pas pourquoi vous l'avez reçue à cet endroit.
Pour un agent de production, consignez un petit reçu de version lorsque vous l'installez ou le mettez à jour. Il peut s'agir d'un fichier texte dans le dépôt qui gère l'agent, d'un enregistrement de modification ou d'une entrée dans un journal interne des versions. Le reçu devrait contenir la version, la source d'installation, l'autorité de signature observée, le Team ID, le condensat, la date de l'examen et le nom de la personne qui l'a accepté. Si l'éditeur fournit un condensat de version, consignez-le également.
Le canal de publication mérite une vérification humaine. Le programme de mise à jour venait-il bien de l'application attendue ? L'éditeur a-t-il publié les notes de version de cette version ? Le nom de l'archive, la signature du paquet et le chemin de destination correspondent-ils à la méthode d'installation habituelle ? Une mise à jour inattendue distribuée par un nouveau canal mérite autant de méfiance qu'un signataire inattendu.
Ne confondez pas un dépôt de code source public avec un artefact de publication. Un dépôt peut montrer l'historique du code alors que le circuit de publication compile un binaire différent. À l'inverse, un binaire signé peut être légitime même si vous ne pouvez pas reproduire sa compilation. Ce sont deux niveaux de garantie différents. Indiquez le niveau dont vous disposez au lieu de prétendre que l'un prouve l'autre.
La comparaison d'un condensat aide lorsque l'éditeur vous fournit une somme de contrôle authentifiée. Elle n'aide pas si vous copiez la somme et le binaire depuis la même page non fiable. La comparaison utile vient d'un enregistrement de version contrôlé indépendamment par l'éditeur, d'un enregistrement de gestionnaire de paquets fiable ou d'une source interne établie auparavant.
Les accès demandés doivent être réexaminés avec la mise à jour
Un binaire peut conserver la même autorité de signature tout en méritant moins d'accès que l'ancienne version. La raison de l'examen n'est pas seulement la crainte d'un code malveillant. Un nouveau comportement peut rendre une ancienne permission injustifiée.
Demandez quelles actions externes le processus effectuera après la mise à jour. Un agent qui lisait auparavant les métadonnées d'un ticket peut désormais créer des pull requests. Celui qui utilisait un jeton de test jetable peut maintenant lancer des commandes SSH sur un hôte partagé. Un nouveau module, un format de configuration modifié ou une commande par défaut différente peut élargir concrètement la portée du processus sans demander de nouveau droit au système d'exploitation.
L'examen des accès demandés doit couvrir la véritable limite d'action :
- Quels hôtes HTTP, périmètres de comptes et identifiants le processus utilisera-t-il ?
- Quelles destinations SSH et quelles commandes distantes peut-il atteindre ?
- Quel répertoire de travail, quels hooks de dépôt, quels arguments et quelles variables d'environnement le lancent ?
- Reçoit-il désormais des entrées provenant d'une autre source, comme un commentaire de pull request ou un journal de compilation ?
- Peut-il lancer un autre exécutable local qui ne faisait pas partie de l'examen précédent ?
C'est ici que l'approbation permanente et trop large échoue. Une décision comme « autoriser cet agent » dissimule l'essentiel : l'autoriser à faire quoi, avec quel identifiant et en réponse à quelle entrée ?
Pour les processus d'agents, la provenance des entrées mérite la même attention. Une mise à jour qui permet à un agent de programmation d'agir sur du texte de ticket non fiable peut transformer un accès ordinaire au dépôt en moyen d'injection de prompt. La signature de code n'examine pas les instructions reçues par le processus. Elle ne couvre que le programme qui les interprète.
Gardez les écrans d'approbation et les enregistrements internes concrets. Nommez l'autorité du processus, la destination, la catégorie d'identifiant et indiquez si l'action modifie un état distant. Un opérateur ne peut pas prendre une décision fiable devant une alerte qui dit seulement : « L'agent demande un accès. »
Terminez l'ancienne session avant que le nouveau code n'agisse
La règle la plus claire consiste à lier l'approbation à un processus en cours et à y mettre fin lorsque ce processus se termine. Un binaire de remplacement crée un nouveau processus, donc une nouvelle approbation. Cela évite de devoir décider quelle mise à jour de paquet est suffisamment petite pour hériter d'une autorisation précédente.
Ne laissez pas un processus se mettre à jour sur place tout en continuant à utiliser l'autorisation obtenue avant le remplacement. Certains programmes de mise à jour fonctionnent exactement ainsi : l'ancien processus télécharge une archive, écrit un nouvel exécutable à l'ancien chemin, puis lance un utilitaire ou se relance lui-même. Si la couche d'autorisation ne vérifie qu'un chemin ou un enregistrement client de longue durée, le nouveau code continue sous l'ancienne décision.
Un enregistrement de décision pratique peut ressembler à ceci :
process path: /Users/dev/tools/agent/bin/agent
observed digest: 8a4b...e19c
identifier: dev.example.agent
TeamIdentifier: A1B2C3D4E5
parent: interactive shell in approved repository
requested actions: issue API read, test-host SSH command
approval scope: this process only
expires: process exit
Ne traitez pas le condensat comme une entrée permanente de liste d'autorisation. Consignez-le pour pouvoir constater que l'approbation suivante concerne un code différent. Lorsque le processus redémarre après une mise à jour, comparez la nouvelle observation avec la précédente et montrez ensuite à l'opérateur les différences importantes.
Même un redémarrage de la même version peut nécessiter un examen si son contexte de lancement change. Un binaire lancé par un shell interactif dans un dépôt contrôlé n'est pas équivalent au même binaire lancé sans surveillance par une tâche de compilation disposant d'un environnement plus large. L'exécutable n'est qu'une partie du sujet. Le contexte du processus le complète.
Examinez les éléments macOS avant d'approuver un remplacement
Vous pouvez examiner un exécutable candidat avec les outils intégrés de macOS avant de l'autoriser à effectuer un appel privilégié. Lancez les commandes sur l'exécutable qui sera réellement lancé, pas sur une copie au nom similaire dans Téléchargements ni sur un bundle d'application externe que vous supposez le contenir.
codesign -d -vvv /Users/dev/tools/agent/bin/agent 2>&1
spctl -a -t exec -vv /Users/dev/tools/agent/bin/agent
shasum -a 256 /Users/dev/tools/agent/bin/agent
La sortie habituelle de codesign comprend des champs de ce type :
Identifier=dev.example.agent
Authority=Developer ID Application: Example Publisher (A1B2C3D4E5)
TeamIdentifier=A1B2C3D4E5
CDHash=8a4b9c0d...
spctl indique son évaluation et fournit généralement l'origine des logiciels Developer ID acceptés. shasum affiche un condensat SHA-256 complet suivi du chemin. Enregistrez les éléments utiles avec le reçu de version. La formulation exacte varie selon la version de macOS. Comparez donc les champs d'identité et l'évaluation, pas les espaces ni l'ordre des champs.
Pour une application groupée, examinez aussi le code imbriqué. Un bundle externe signé peut contenir des utilitaires, des frameworks ou des outils en ligne de commande. Si l'agent lance directement un utilitaire, examinez directement cet utilitaire. Le fichier qui demande l'accès est celui dont vous devez lier l'identité à la décision.
Une vérification codesign réussie ne signifie pas qu'un exécutable est notarisé ou adapté à votre usage. Elle signifie que la signature est valide selon les règles de vérification de la commande. Cette distinction mérite d'être conservée dans les notes d'incident. Sinon, quelqu'un pourra lire plus tard « signature valide » comme « version examinée et approuvée », ce qui est une affirmation bien plus large.
Un chemin stable permet facilement d'approuver le mauvais code
Imaginez un wrapper local situé à /Users/dev/bin/agent. Un développeur l'approuve une fois parce qu'il appelle une API de projet en lecture seule. Le wrapper effectue ensuite une mise à jour automatique, télécharge un nouvel utilitaire et conserve le même chemin. Le composant d'approbation reconnaît le chemin et accorde au nouvel utilitaire l'ancienne autorisation.
Rien dans cette séquence ne nécessite un attaquant malveillant. La version peut être authentique. Le problème est que l'enregistrement d'approbation dit « le chemin est le chemin autorisé », alors que la décision concernait en réalité un programme plus ancien au comportement plus limité.
Le problème s'aggrave lorsque le wrapper est lui-même un script. Les scripts shell lancent souvent des binaires versionnés sous un lien symbolique stable, lisent une configuration dans un répertoire modifiable ou sélectionnent un utilitaire dans PATH. Une vérification de signature du wrapper vous apprend peu de choses sur l'exécutable final si le wrapper peut rediriger l'exécution après la vérification.
Corrigez l'ordre des opérations. Résolvez l'exécutable final. Examinez sa signature et son condensat. Capturez le processus parent et les arguments. Autorisez ensuite ce processus en cours. Si un lanceur peut remplacer ou sélectionner un autre exécutable après l'approbation, liez la passerelle d'action au processus qu'elle observe au moment de la connexion et refusez toute discordance.
L'alternative courante consiste à autoriser automatiquement toute mise à jour signée par le même Team ID. Les équipes la choisissent parce que les demandes agacent les développeurs et que les certificats de publication restent généralement stables. Elle est inadaptée aux agents privilégiés, car elle transforme un identifiant d'éditeur en blanc-seing pour tous les comportements futurs. Réduisez la fatigue liée aux demandes grâce à des approbations limitées à la session, des accès restreints et des notifications de mise à jour claires, pas en rendant les mises à jour invisibles.
Les changements d'éditeur nécessitent un enregistrement de migration explicite
Un changement d'autorité de signature peut être légitime. Des entreprises rachètent des produits, passent à un autre compte Developer ID ou remplacent un ancien processus de distribution. Traitez ces événements comme des migrations, pas comme des mises à jour ordinaires.
Demandez un enregistrement explicite indiquant l'ancienne identité, la nouvelle, la version où le changement s'est produit et les éléments qui ont permis de l'accepter. Les bonnes preuves comprennent une annonce signée dans le canal de publication habituel de l'éditeur, des notes de version correspondantes dans le dépôt attendu et un paquet obtenu par le circuit normal. Une fenêtre contextuelle inexpliquée ne constitue pas une preuve.
Un Team ID modifié devrait par défaut entraîner un refus jusqu'à l'examen de la migration. Un certificat modifié sous le même Team ID peut faire l'objet d'une nouvelle approbation après l'examen habituel de la provenance et des accès. Un condensat modifié avec le même certificat nécessite lui aussi une nouvelle approbation, car il s'agit d'un nouveau code, même si tous les autres champs correspondent.
N'accordez pas d'exception large telle que « accepter toutes les identités futures pour ce nom d'application ». Cette exception transforme une migration ponctuelle en faille permanente. N'enregistrez la nouvelle identité qu'après l'acceptation d'une version précise par l'examinateur. Le changement suivant doit déclencher le même examen.
Si votre équipe distribue des agents internes, publiez l'identité de signature attendue, le condensat de version et la procédure de mise à jour à un endroit que les opérateurs peuvent consulter sans dépendre de l'agent lui-même. Un agent ne peut pas attester de manière crédible son propre remplacement lorsque ce remplacement est précisément l'objet de l'examen.
Un petit protocole d'approbation vaut mieux qu'une longue liste d'exceptions
Vous n'avez pas besoin d'un moteur de règles complexe pour rendre les décisions de mise à jour prévisibles. Il vous faut un court protocole applicable chaque fois que l'exécutable change.
- Arrêtez l'ancien processus et révoquez sa session active.
- Résolvez l'exécutable final qui se connectera ou agira.
- Comparez son condensat, son identifiant, son autorité de signature et son Team ID avec le dernier reçu de version.
- Vérifiez le canal de publication attendu et consignez la raison de tout changement d'identité.
- Examinez les destinations et les identifiants demandés, puis approuvez la nouvelle session du processus ou refusez-la.
Ce protocole sépare une mise à jour de maintenance normale d'une véritable anomalie. Un nouveau condensat avec la même autorité et une provenance de publication habituelle est un événement à examiner, pas une urgence. Une autorité inconnue, un installeur inattendu et une demande d'identifiant SSH de production doivent interrompre le déploiement jusqu'à l'enquête d'une personne compétente.
L'autorisation de session de Sallyport peut rendre la limite du processus visible, car elle identifie un nouveau processus d'agent avant d'autoriser son exécution. Son réglage d'approbation à chaque appel peut aussi maintenir les identifiants sensibles sous un contrôle plus strict. Cela ne dispense pas d'examiner un agent mis à jour, mais empêche une ancienne exécution de prêter discrètement son approbation à une nouvelle.
Gardez l'enregistrement suffisamment court pour que les équipes le tiennent à jour. Les preuves utiles sont le fichier observé, son signataire, sa source, son contexte de lancement et les actions approuvées. Si une version change l'un de ces éléments, la personne responsable du risque doit voir le changement avant que l'agent n'agisse.
Les journaux d'audit doivent distinguer l'acteur de l'éditeur
Un journal d'audit qui dit seulement « l'agent a utilisé un identifiant » rend l'analyse après incident inutilement difficile. Consignez le processus qui a effectué la demande, l'autorité de signature indiquée par macOS, la session qui l'a autorisée et l'action réellement effectuée. L'identité de l'éditeur explique qui a signé le code. L'enregistrement du processus explique qui a agi.
Cette distinction compte lorsqu'une exécution d'agent tourne mal. Vous devez déterminer si une nouvelle version a modifié le comportement, si un ancien binaire s'est exécuté depuis un emplacement inattendu, si une personne a approuvé une demande d'accès différente de celle qu'elle croyait accepter ou si une entrée non fiable a orienté un processus pourtant attendu. Le seul champ de l'éditeur ne peut pas répondre à ces questions.
Gardez l'intégrité séparée de la lisibilité. Un enregistrement détectant les altérations peut établir si des entrées antérieures ont changé. Il ne peut pas créer après coup les faits manquants. Capturez le condensat de l'exécutable et le contexte de la décision au moment de l'approbation, quand vous pouvez encore les observer.
Sallyport produit ses journaux Sessions et Activity à partir d'un seul journal d'audit chiffré et chaîné par hachage, et sp audit verify peut vérifier cette chaîne hors ligne sur le texte chiffré. Utilisez ce type de preuve pour vérifier l'enregistrement, puis associez-le à un reçu de version expliquant pourquoi l'exécutable a reçu l'accès au départ.
Le premier changement opérationnel que je ferais serait de supprimer toute règle d'approbation qui ne vérifie qu'un chemin, un nom affiché ou un éditeur. Remplacez-la par l'approbation du processus actuel, faites-la expirer à la fin du processus et exigez une nouvelle décision après le remplacement d'un binaire. Cette seule limite intercepte le chemin de mise à jour que les listes d'autorisation trop larges laissent régulièrement passer.
FAQ
Le même Team ID suffit-il pour faire confiance à un agent mis à jour ?
Non. Un Team ID ou un certificat de développeur inchangé indique que le signataire reste associé au nouveau fichier. Il ne prouve pas que le nouveau code mérite les accès de l'ancien processus ni que la version est arrivée par le canal habituel de l'éditeur.
Un agent doit-il être approuvé à nouveau après chaque mise à jour ?
Traitez le nouvel exécutable comme un nouveau sujet. Terminez la session de l'ancien processus, vérifiez la signature et la provenance du nouveau, puis demandez une nouvelle approbation avant qu'il puisse utiliser des identifiants ou agir à l'extérieur.
Que prouve réellement la signature de code de macOS ?
Une signature de code associe l'identité d'un signataire au contenu d'un fichier et permet à macOS de détecter les modifications effectuées après la signature. Elle ne prouve pas que le compte de publication de l'éditeur n'a pas été compromis, que l'installeur a été obtenu au bon endroit ni que les accès demandés par le programme restent appropriés.
Qu'est-ce qu'un CDHash et dois-je le conserver ?
Le CDHash identifie le répertoire de code signé utilisé par macOS et change lorsque le code signé pertinent change. Il aide à détecter qu'un exécutable diffère d'une version approuvée, mais ne remplace pas la vérification de l'autorité de signature et de la source de publication.
Que faire si la mise à jour d'un agent utilise un certificat de signature différent ?
Ne reconduisez pas cette approbation en silence. Un changement d'autorité de signature demande un examen explicite. Un changement de Team ID devrait généralement bloquer l'exécution jusqu'à la confirmation d'un transfert documenté de l'éditeur ou d'une migration volontaire.
Quand vérifier un binaire d'agent sur macOS ?
Inspectez l'exécutable après son arrivée sur le disque et avant sa première action privilégiée. Le chemin de lancement compte, car un outil de mise à jour, un utilitaire d'archive ou un script de remplacement peut ensuite placer un autre fichier au même endroit.
Comment vérifier la provenance d'un exécutable d'agent local ?
Vérifiez le canal de publication habituel de l'éditeur, l'installeur ou l'archive signée, toute somme de contrôle publiée et les notes de version qui expliquent le changement. Si vous ne pouvez pas établir l'origine du fichier, une signature valide ne suffit pas pour lui donner accès à des identifiants de production.
Une approbation de session peut-elle survivre à une mise à jour effectuée sur place ?
Elle devrait prendre fin quand le processus se termine et ne devrait pas être transférée à un binaire de remplacement. Un processus en cours qui se modifie lui-même mérite une attention particulière, car l'identité qui a reçu l'approbation ne correspond plus au code qui effectuera les appels suivants.
Est-il prudent d'autoriser un agent selon son chemin de fichier ?
Une liste d'autorisation peut réduire le nombre de demandes, mais elle échoue si elle ne vérifie qu'un chemin, un nom de bundle ou un Team ID. Faites correspondre un binaire observé précis pour l'exécution en cours, puis demandez une nouvelle décision lorsque son hachage, son exigence de signature, son contexte de lancement ou ses accès demandés changent.
Comment Sallyport gère-t-il la confiance après la mise à jour d'un agent ?
Oui, si le système conserve le secret en dehors du processus de l'agent et lie l'approbation au processus actuel. Sallyport le fait grâce à un verrou de coffre et à l'autorisation de session, mais l'opérateur doit tout de même traiter un exécutable récemment modifié comme une nouvelle exécution à examiner.