← Retour à tous les articles
Publié le · par Renaud Deraison

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.

Où se trouve la vraie cléClés enregistrées dans une console hébergéeVotre portableUn collègueAutres clientsvraies clésStockage des espaces de travailsk-ant-… sk-proj-… AIza…les clés de chaque compte liéSystème ancien, en cours de retraitL’intrus lance de l’inférence en masseLa facture va au titulaire de la clé jusqu’à sa révocation.Les clés dans Bromure Agentic CodingVotre Mac · models.encAES-GCM, clé maîtresse dans le Trousseau Data ProtectionVM Linux · environnement et config de l’agentANTHROPIC_API_KEY=sk-ant-api03-brm-… (substitut)Le proxy du Mac vérifie la destination de chaque requêteapi.anthropic.comsubstitut → vraie clétout autre hôte451, VM en pauseAucune copie hébergée. La VM n’a que des substituts.
À gauche : les clés enregistrées dans une console hébergée partagent un serveur avec celles de tous les autres utilisateurs, et une seule intrusion les atteint toutes. À droite : dans Bromure, la vraie clé n’existe que dans un fichier chiffré sur votre Mac et dans la requête que le Mac envoie au fournisseur. Tout ce que détient la VM est un substitut, et un substitut envoyé ailleurs arrête la machine.

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é.