As chaves estavam no console deles
Na noite de 16 de outubro, alguém entrou em um sistema legado da OpenCode e alcançou as chaves de API da OpenAI, Anthropic e Google que cerca de 1,4% dos usuários do OpenCode Console tinham salvado em seus workspaces. A OpenCode chamou o caso de ataque de destilação em larga escala, e usuários relataram faturas de provedores que não geraram. No Bromure Agentic Coding, as chaves dos provedores ficam criptografadas no seu Mac, o roteamento entre vários provedores roda no seu Mac, e qualquer cópia de uma chave que sai da VM é um substituto que nenhum provedor aceita.
Seu laptop estava em ordem. Sua chave da Anthropic foi roubada de um servidor onde você a colou meses atrás.
No sábado, 17 de outubro, a OpenCode avisou parte dos seus usuários de que havia “identified unauthorized access to a legacy system”, um sistema que estava em processo de desativação. A invasão aconteceu durante a noite, de 16 para 17 de outubro. O aviso dizia que “third party provider keys (eg OpenAI, Anthropic) saved in your workspace may have been exposed”. A OpenCode estimou a parcela de usuários do OpenCode Console afetados em cerca de 1,4%, restrita a contas com provedores externos vinculados, e mandou e-mail para cada uma delas. Descreveu o incidente como “related to a large scale distillation attack” e disse estar trabalhando com a Anthropic, a OpenAI e o Google. OfficeChai, Startup Fortune e outros noticiaram no mesmo dia.
A OpenCode disse que não podia confirmar se as chaves tinham sido usadas e que o incidente ainda estava em andamento. Usuários no X relataram cobranças em chaves que só tinham usado com a OpenCode, algumas na casa das centenas de dólares. O conselho publicado por todos foi o mesmo: revogar cada chave salva no Console pelo painel de cada provedor, emitir novas e atualizar todos os lugares onde a chave antiga estava.
As vítimas não tinham rodado um pacote malicioso nem aberto um repositório envenenado. Um invasor pegou as chaves delas de um servidor onde elas as tinham colado.
Por que as chaves estavam lá
A OpenCode é um agente de programação de código aberto que conversa com mais de 75 provedores de modelos. O Console é a parte hospedada, onde você pode salvar suas próprias chaves de provedores em um workspace e deixar o serviço usá-las por você. O resumo do ai-tldr as descreve como chaves salvas “for bring-your-own-key use”. É uma conveniência: uma conta, todos os provedores, nada de ficar levando chaves de um laptop para outro.
Também transforma o banco de dados de um fornecedor em um chaveiro. Cada usuário que vinculava um provedor acrescentava mais uma credencial ativa e cobrável ao mesmo armazenamento. Meses depois, um sistema que o fornecedor estava aposentando ainda tinha acesso a esse armazenamento.
Uma chave de API de modelo é poder de gasto. Quem a tem pode comprar inferência na sua conta até você revogá-la, no ritmo que o provedor permitir. O motivo relatado, “destilação”, significa colher em volume as respostas de um modelo forte para treinar um mais barato. Isso exige muitas requisições, e uma chave roubada faz outra pessoa pagar por elas.
Uma cópia, no seu Mac
O Bromure Agentic Coding roda Claude Code, Codex, Grok, Kimi e omp em VMs Linux no seu Mac. Você registra cada provedor de modelos uma única vez, em Preferences › Models: cole uma chave de API ou clique em Sign in with provedor para usar uma assinatura do Claude, ChatGPT, Grok ou Kimi sem chave de API nenhuma.
As chaves vão para models.enc, na pasta de suporte do app, criptografadas
com AES-GCM sob uma chave mestra própria de cada instalação. Essa chave
mestra fica no Data Protection Keychain do macOS, vinculada à identidade de
assinatura do app, com a sincronização do iCloud desligada. Ela nunca sai
do Mac. O Bromure não tem uma conta onde suas chaves morem, nem um workspace
hospedado para onde elas sincronizem.
O Bromure oferece a conveniência do console no próprio Mac. Toda máquina lê o mesmo quadro, e uma máquina pode sobrepô-lo com suas próprias chaves. Codex, Grok, Kimi e omp podem chegar ao Bedrock, OpenRouter, xAI e Moonshot por um proxy de tradução que roda no Mac e guarda a chave real ali. O Claude Code chega ao OpenRouter e ao z.ai diretamente, com um substituto.
Tudo na VM é um substituto
O agente ainda precisa de ANTHROPIC_API_KEY ou OPENAI_API_KEY para
iniciar, e recebe uma. Dentro da VM, essas variáveis guardam substitutos com
o formato das chaves reais: sk-ant-api03-brm-… para a Anthropic,
sk-brm-… para a OpenAI, xai-brm-… para a xAI, sk-kimi-brm-… para o
Kimi. O HTTPS do agente passa por um proxy no Mac, que troca o substituto
pela chave real apenas em requisições para os hosts do próprio provedor:
anthropic.com, openai.com, x.ai, moonshot.ai. A correspondência é
exata ou por subdomínio, nunca por substring, então
api.openai.com.evil.example não recebe nada.
Com uma assinatura é igual, só que sem a chave. O login acontece em uma VM descartável ou pelo próprio login do agente, o proxy captura os tokens OAuth no Mac, e o agente fica com um substituto. O host renova o token de acesso cerca de cinco minutos antes de ele expirar. A VM nunca guarda um refresh token.
Muitas ferramentas agora oferecem sincronizar suas configurações com a
nuvem do fornecedor: uma CLI que faz “backup” da config, um editor que
mantém seu workspace na sua conta, um plugin com painel. Dentro de uma
máquina Bromure, a config que essas ferramentas enviam contém
sk-ant-api03-brm-…. Um substituto guardado no servidor de outra pessoa
não vale nada lá. Nenhum provedor o aceita, e ele só vira uma chave real
quando a requisição passa pelo seu Mac a caminho do provedor para o qual
foi criado.
O proxy também pega o próprio envio. Ele examina cada requisição de saída, cabeçalhos e corpo, em busca de substitutos indo para outro destino que não o seu próprio provedor. Uma sincronização de config que leva um substituto da Anthropic a um servidor de terceiros recebe HTTP 451. Nada é encaminhado, a VM é pausada e o Mac mostra This environment may have been compromised, informando a prévia do token, a credencial, o host a que ela pertence e o host para onde foi enviada. Você fica sabendo no dia em que uma ferramenta tenta copiar sua chave para fora da máquina, meses antes do aviso de violação de qualquer fornecedor.
A manhã seguinte, no Bromure
Digamos que você tenha recebido aquele e-mail mesmo assim, porque também usou uma chave em outro lugar. Todo guia diz as mesmas três coisas: revogar, substituir em todo lugar e verificar o uso. No Bromure, cada passo é curto.
Substituir em todo lugar. A chave real fica em um só lugar. Cole a nova
no popover do provedor em Preferences › Models e o Bromure atualiza
cada máquina em execução cerca de um segundo e meio depois que você para de
digitar: o mapa de troca, o ambiente dos agentes e os arquivos de config
deles. Os agentes cuja credencial mudou reiniciam na sua aba com as flags
de retomada, então a conversa continua, e a VM nunca reinicia. Não há
arquivos .env, segredos de CI nem laptops de colegas para caçar em busca
das cópias dentro das VMs, porque essas cópias eram substitutos.
Verificar o uso. No nível AI request details, com o qual as
máquinas novas começam, o Mac registra cada troca com um provedor de
modelos como um registro llm.request: provedor, host, modelo, status e
contagens de tokens de entrada, saída e cache. Quando o painel de um
provedor mostra um pico às 3 da manhã, você pode compará-lo com o que suas
máquinas enviaram. bromure-cli trace summary e bromure-cli trace hostnames dão a visão por máquina em um terminal. Cada troca de uma chave
de provedor aparece na Security Timeline como uma linha Credential
brokering, com uma prévia mascarada e o host, em uma tabela com uma
coluna Workspace. Qualquer coisa na conta do provedor que suas máquinas
não enviaram veio de outra pessoa.
Para uma equipe, o Bromure Enterprise Manager consolida as mesmas
contagens de llm.request por usuário, por workspace e por modelo, sem
enviar prompts, respostas ou segredos. Uma chave roubada aparece como um
gasto que não corresponde a nenhuma instalação.
Ou dispense a chave. Para Claude Code, Codex, Grok e Kimi, um login com assinatura substitui a chave paga por uso, e os tokens gerados ficam no Mac e são renovados ali. Assim não sobra nenhuma chave de API de longa duração para um terceiro guardar.
Uma cópia criptografada, no seu Mac
Chaves de provedores e logins ficam em models.enc, sob uma chave mestra no Data Protection Keychain. O Bromure não tem workspace hospedado nem conta que os guarde.
Roteamento entre provedores, localmente
Toda máquina lê um único quadro Models. Os agentes chegam a outros provedores por um proxy no Mac que guarda a chave real.
Substitutos onde quer que uma cópia vá parar
A VM, seus arquivos de config e tudo o que uma ferramenta sincroniza com a nuvem guardam substitutos. Um substituto enviado ao host errado recebe um 451 e pausa a máquina.
Troque uma vez, audite por requisição
Uma chave nova chega a cada máquina em execução sem reinicialização. Cada troca com um modelo é registrada com o modelo e as contagens de tokens.
Onde uma chave deveria morar
Cada lugar onde você cola uma chave de provedor é mais um lugar de onde ela pode ser roubada. Laptops pegam stealers, repositórios são raspados e, como esta semana mostrou, fornecedores aposentam sistemas que ainda alcançam as chaves dos seus clientes.
Mantenha a chave real em um único arquivo criptografado no seu Mac e coloque substitutos em todos os outros lugares. Para a versão do mesmo problema do lado do laptop, leia O stealer levou os substitutos e O agente vazou a própria chave.