Les clés étaient dans leur console
Dans la nuit du 16 octobre, quelqu’un s’est introduit dans un ancien système d’OpenCode et a atteint les clés d’API OpenAI, Anthropic et Google qu’environ 1,4 % des utilisateurs d’OpenCode Console avaient enregistrées dans leurs espaces de travail. OpenCode a parlé d’une attaque par distillation à grande échelle, et des utilisateurs ont signalé des factures de fournisseurs qu’ils n’avaient pas générées. Dans Bromure Agentic Coding, les clés des fournisseurs restent chiffrées sur votre Mac, le routage multi-fournisseurs s’exécute sur votre Mac, et toute copie d’une clé qui quitte la VM est un substitut qu’aucun fournisseur n’accepte.
Votre portable n’avait rien. Votre clé Anthropic a été volée sur un serveur où vous l’aviez collée il y a des mois.
Le samedi 17 octobre, OpenCode a prévenu une partie de ses utilisateurs qu’il avait « identified unauthorized access to a legacy system », un système qu’il était en train de mettre hors service. L’intrusion a eu lieu dans la nuit du 16 au 17 octobre. Selon l’avis, « third party provider keys (eg OpenAI, Anthropic) saved in your workspace may have been exposed ». OpenCode a évalué la part des utilisateurs d’OpenCode Console concernés à environ 1,4 %, limitée aux comptes liés à des fournisseurs externes, et a écrit à chacun d’eux. Il a décrit l’incident comme « related to a large scale distillation attack » et a indiqué travailler avec Anthropic, OpenAI et Google. OfficeChai, Startup Fortune et d’autres en ont parlé le jour même.
OpenCode a déclaré ne pas pouvoir confirmer si les clés avaient été utilisées, et que l’incident était toujours en cours. Sur X, des utilisateurs ont signalé des frais sur des clés qu’ils n’avaient jamais utilisées qu’avec OpenCode, parfois de plusieurs centaines de dollars. Tout le monde a publié le même conseil : révoquer chaque clé enregistrée dans la Console depuis le tableau de bord de chaque fournisseur, en émettre de nouvelles, et mettre à jour chaque endroit où l’ancienne clé se trouvait.
Les victimes n’avaient pas exécuté de paquet malveillant ni ouvert de dépôt piégé. Un intrus a pris leurs clés sur un serveur où elles les avaient collées.
Pourquoi les clés étaient là
OpenCode est un agent de code open source qui parle à plus de 75 fournisseurs de modèles. La Console en est la partie hébergée : vous pouvez y enregistrer vos propres clés de fournisseurs dans un espace de travail et laisser le service s’en servir pour vous. Le résumé d’ai-tldr les décrit comme des clés enregistrées « for bring-your-own-key use ». C’est une commodité : un seul compte, tous les fournisseurs, pas de clés à promener d’un portable à l’autre.
Cela transforme aussi la base de données d’un éditeur en trousseau de clés. Chaque utilisateur qui reliait un fournisseur ajoutait un identifiant de plus, actif et facturable, au même stockage. Des mois plus tard, un système que l’éditeur retirait avait encore accès à ce stockage.
Une clé d’API de modèle est un pouvoir de dépense. Celui qui la détient peut acheter de l’inférence sur votre compte jusqu’à ce que vous la révoquiez, au débit que le fournisseur autorise. Le motif rapporté, la « distillation », consiste à récolter en masse les réponses d’un modèle performant pour en entraîner un moins cher. Cela demande énormément de requêtes, et une clé volée les fait payer par quelqu’un d’autre.
Une seule copie, sur votre Mac
Bromure Agentic Coding exécute Claude Code, Codex, Grok, Kimi et omp dans des VM Linux sur votre Mac. Vous enregistrez chaque fournisseur de modèles une seule fois, dans Preferences › Models : collez une clé d’API, ou cliquez sur Sign in with fournisseur pour utiliser un abonnement Claude, ChatGPT, Grok ou Kimi sans aucune clé d’API.
Les clés vont dans models.enc, dans le dossier de support de l’app,
chiffrées en AES-GCM sous une clé maîtresse propre à chaque installation.
Cette clé maîtresse réside dans le Trousseau Data Protection de macOS, liée
à l’identité de signature de l’app, sans synchronisation iCloud. Elle ne
quitte jamais le Mac. Bromure n’a pas de compte où vos clés vivraient, ni
d’espace de travail hébergé vers lequel elles se synchroniseraient.
Bromure vous offre la commodité de la console, sur le Mac. Chaque machine lit le même tableau, et une machine peut le remplacer par ses propres clés. Codex, Grok, Kimi et omp peuvent joindre Bedrock, OpenRouter, xAI et Moonshot via un proxy de traduction qui tourne sur le Mac et y conserve la vraie clé. Claude Code joint OpenRouter et z.ai directement, avec un substitut.
Dans la VM, tout est substitut
L’agent a toujours besoin de ANTHROPIC_API_KEY ou de OPENAI_API_KEY
pour démarrer, et il en reçoit une. Dans la VM, ces variables contiennent
des substituts qui ont la forme des vraies clés : sk-ant-api03-brm-… pour
Anthropic, sk-brm-… pour OpenAI, xai-brm-… pour xAI, sk-kimi-brm-…
pour Kimi. Le trafic HTTPS de l’agent passe par un proxy sur le Mac, qui
remplace le substitut par la vraie clé uniquement pour les requêtes vers
les hôtes propres à ce fournisseur : anthropic.com, openai.com, x.ai,
moonshot.ai. La correspondance est exacte ou par sous-domaine, jamais par
sous-chaîne : api.openai.com.evil.example n’obtient rien.
Avec un abonnement, c’est pareil, sans la clé. La connexion se fait dans une VM jetable ou via la propre procédure de connexion de l’agent, le proxy capture les jetons OAuth sur le Mac, et l’agent garde un substitut. L’hôte rafraîchit le jeton d’accès environ cinq minutes avant son expiration. La VM ne détient jamais de jeton de rafraîchissement.
Beaucoup d’outils proposent désormais de synchroniser leurs réglages vers le
cloud de leur éditeur : une CLI qui « sauvegarde » sa config, un éditeur qui
garde votre espace de travail dans votre compte, un plugin avec un tableau
de bord. Dans une machine Bromure, la config que ces outils envoient
contient sk-ant-api03-brm-…. Un substitut stocké sur le serveur de
quelqu’un d’autre n’y vaut rien. Aucun fournisseur ne l’accepte, et il ne
devient une vraie clé que lorsque la requête passe par votre Mac vers le
fournisseur pour lequel il a été créé.
Le proxy intercepte aussi l’envoi lui-même. Il inspecte chaque requête sortante, en-têtes et corps, à la recherche de substituts en route vers autre chose que leur propre fournisseur. Une synchronisation de config qui transporte un substitut Anthropic vers un serveur tiers 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, l’identifiant concerné, l’hôte auquel il appartient et l’hôte vers lequel il a été envoyé. Vous l’apprenez le jour où un outil tente de copier votre clé hors de la machine, des mois avant l’avis de violation d’un éditeur.
Le lendemain matin, dans Bromure
Imaginons que vous ayez quand même reçu ce courriel, parce que vous aviez aussi utilisé une clé ailleurs. Tous les guides disent les trois mêmes choses : révoquer, remplacer partout, vérifier l’utilisation. Dans Bromure, chaque étape est courte.
Remplacer partout. La vraie clé se trouve à un seul endroit. Collez la
nouvelle dans la fenêtre du fournisseur, dans Preferences › Models, et
Bromure met à jour chaque machine en cours d’exécution environ une seconde
et demie après que vous avez fini de taper : la table de substitution,
l’environnement des agents et leurs fichiers de config. Les agents dont
l’identifiant a changé redémarrent dans leur onglet avec leurs options de
reprise, la conversation continue donc, et la VM ne redémarre jamais. Pas
de fichiers .env, de secrets de CI ni de portables de collègues à
traquer pour les copies présentes dans les VM, puisque ces copies étaient
des substituts.
Vérifier l’utilisation. Au niveau AI request details, celui avec
lequel démarrent les nouvelles machines, le Mac journalise chaque échange
avec un fournisseur de modèles sous forme d’enregistrement llm.request :
fournisseur, hôte, modèle, statut, et nombre de jetons en entrée, en sortie
et en cache. Quand le tableau de bord d’un fournisseur montre un pic à
3 h du matin, vous pouvez le confronter à ce que vos machines ont envoyé.
bromure-cli trace summary et bromure-cli trace hostnames donnent la vue
par machine dans un terminal. Chaque substitution d’une clé de fournisseur
apparaît dans la Security Timeline sous forme de ligne Credential
brokering, avec un aperçu masqué et l’hôte, dans un tableau doté d’une
colonne Workspace. Tout ce qui figure sur la facture du fournisseur et
que vos machines n’ont pas envoyé vient de quelqu’un d’autre.
Pour une équipe, Bromure Enterprise Manager agrège ces mêmes compteurs
llm.request par utilisateur, par espace de travail et par modèle, sans
envoyer de prompts, de réponses ni de secrets. Une clé volée se repère
comme une dépense qui ne correspond à aucune installation.
Ou se passer de clé. Pour Claude Code, Codex, Grok et Kimi, une connexion par abonnement remplace la clé facturée à l’usage, et les jetons qu’elle produit restent sur le Mac et s’y rafraîchissent. Il ne reste alors aucune clé d’API durable qu’un tiers pourrait stocker.
Une copie chiffrée, sur votre Mac
Les clés de fournisseurs et les connexions se trouvent dans models.enc, sous une clé maîtresse du Trousseau Data Protection. Bromure n’a ni espace de travail hébergé ni compte qui les détienne.
Routage multi-fournisseurs, en local
Chaque machine lit un même tableau Models. Les agents joignent les autres fournisseurs via un proxy sur le Mac qui détient la vraie clé.
Des substituts partout où une copie atterrit
La VM, ses fichiers de config et tout ce qu’un outil synchronise vers le cloud contiennent des substituts. Un substitut envoyé au mauvais hôte reçoit un 451 et met la machine en pause.
Une rotation, un audit par requête
Une nouvelle clé atteint chaque machine en cours d’exécution sans redémarrage. Chaque échange avec un modèle est journalisé avec son modèle et ses nombres de jetons.
Où une clé devrait vivre
Chaque endroit où vous collez une clé de fournisseur est un endroit de plus d’où elle peut être volée. Les portables attrapent des stealers, les dépôts se font aspirer, et comme cette semaine l’a montré, les éditeurs retirent des systèmes qui peuvent encore atteindre les clés de leurs clients.
Gardez la vraie clé dans un seul fichier chiffré sur votre Mac, et mettez des substituts partout ailleurs. Pour la version côté portable du même problème, lisez Le stealer a emporté les substituts et L’agent a divulgué sa propre clé.