← Voltar para todas as publicações
Publicado em · por Renaud Deraison

Porque o Bromure Agentic Coding não é uma sandbox

Uma sandbox pede ao programador que abdique da velocidade que torna um agente de codificação digno de ser usado — pré-aprovar cada dependência, manter uma lista de domínios permitidos, nunca tocar num pacote que a organização não tenha avaliado. Por isso os programadores desligam-na. O Bromure Agentic Coding recusa essa troca. Não restringe o que o agente faz; traça uma única linha rígida no hypervisor e deixa-o fazer tudo do lado de dentro. Esta é a defesa fundacional de por que uma fronteira vence uma sandbox, e as três garantias que a fronteira torna verdadeiras: nenhuma credencial para roubar, tokens amplos estreitados no fio, e ataques à cadeia de fornecimento travados antes de o tarball aterrar — mais a quarta que a linha agora torna verdadeira: injeções de prompt apanhadas no conteúdo que o agente lê, antes de o modelo lhes obedecer.

Uma sandbox oferece uma troca: abdique de parte do que torna um agente de codificação útil, e em troca ela mantê-lo-á seguro. Os programadores recusam essa troca todas as vezes — desligam a sandbox, ou nunca a ligam — e fazem bem. A função de um agente é mover-se depressa por território confuso e não avaliado. O Bromure Agentic Coding não restringe isso. Traça uma única linha rígida, no hypervisor, e deixa-o fazer tudo o que quiser do lado de dentro dela.

Um post fundacional — escrito uma vez, para os restantes apontarem para ele. Não sobre um incidente. Sobre por que construímos o Bromure Agentic Coding da forma que construímos, e por que «é uma sandbox» é a descrição que continuamos a corrigir.

Um programador não é um administrador de sistemas.

A razão para pôr um agente de codificação na sua máquina é a velocidade — a do tipo concreto: puxar um pacote que ninguém na sua empresa avaliou, às onze da noite, para ver se uma ideia se aguenta. Experimentar a biblioteca, correr o seu exemplo, deitá-la fora se não encaixar. Isso não é um defeito a disciplinar para fora das pessoas. É o fluxo de trabalho, e a própria razão por que vale a pena ter o agente.

Por isso qualquer modelo que o obrigue a pré-aprovar cada dependência, ou que obrigue alguém a manter uma lista de domínios que o agente pode alcançar, está em guerra com aquilo que protege. Atrasa a única atividade que foi implantado para permitir — e um controlo que atrapalha a entrega tem exatamente um destino: é desligado. Um controlo que um programador desliga para conseguir trabalhar nunca foi um controlo.

«Corra um espelho privado e avaliado» falha o argumento da mesma forma: os pacotes que importam para a experimentação são os que ninguém ainda avaliou. Um espelho de dependências aprovadas é um espelho das ideias de ontem.

Por isso a questão não é como impedir os programadores de tocar em código não avaliado. Têm de o fazer; é essa a função. É como deixá-los tocar em tudo, livremente, sem que o seu chaveiro faça parte do negócio.

A sandbox construída para produção não serve para a bancada.

O primeiro reflexo é uma sandbox de rede — os contentores endurecidos, os da NVIDIA, as receitas de Docker-Compose que circulam por aí. A forma é sempre a mesma: enumerar os hosts que o agente pode alcançar, negar o resto. Funciona lindamente quando o agente tem uma função conhecida e estreita. Um agente de produção a falar com três serviços internos e um endpoint de modelo vive atrás de uma lista de permissões para sempre, porque a lista é curta e deixa de mudar.

A ideação não tem lista curta, e nunca deixa de mudar. Ninguém quer manter uma whitelist de cada registry, CDN, host de Git, e API pontual que uma experiência possa alcançar — nunca está acabada, cresce todas as tardes, e o dia em que bloqueia algo legítimo é o dia em que o programador a desativa para se desbloquear. A lista de permissões não está errada; protege um agente cujo escopo já é conhecido. O valor todo da bancada é que o escopo ainda não é conhecido.

Pegue numa tarde concreta. Um programador tem ficheiros de configuração Node que cresceram para dezenas de megabytes, e o parser de YAML em que está engasga-se com eles. Há vários candidatos — js-yaml, yaml, yaml-js — e a única forma de saber qual sobrevive a um ficheiro de 40 MB sem rebentar a heap é instalar os três e atirar o ficheiro a cada um. Abrir um ticket para pôr três bibliotecas no espelho privado para que possam ser avaliadas em benchmark é exatamente ao contrário: o programador quer testar primeiro e promover o vencedor para o espelho, não o contrário. A pré-avaliação é o portão pelo qual a experiência existe para passar.

Há um problema mais silencioso por baixo. Estas ferramentas endurecem o agente em produção — implantado, com escopo, supervisionado. Mas um comprometimento da cadeia de fornecimento aterra no portátil do programador, a meio de uma experiência, com credenciais reais em ~/.aws e ~/.npmrc porque é onde os programadores as guardam. O modelo é mais forte onde os ataques não estão, e ausente onde eles estão.

A sandbox de gato-e-rato perde a segunda ronda.

O outro instinto é deixar o agente no host e prender o processo — bloquear o processo claude de ler ~/.ssh e ~/.aws. Parece estanque, até se lembrar de que a função do agente é escrever código, e o código corre na mesma máquina.

O agente faz o scaffolding de um projeto. Depois você — ou o agente, ou uma segunda ferramenta — corre npm install no repositório que ele acabou de escrever. Esse npm install não é o processo preso. O seu hook postinstall lê ~/.aws/credentials como qualquer outro programa no seu portátil, porque é exatamente o que é: outro programa, a partilhar o único sistema de ficheiros e o único chaveiro com tudo o resto que você corre.

O SEU PORTÁTIL — um sistema de ficheiros, um chaveiroPRISÃO DE PROCESSOclaude✗ read ~/.ssh✗ read ~/.awsbloqueado — parece estanque./repo — acabado de escrever pelo agentepackage.json "postinstall": "node x.js"SEGUNDA SHELL — não presa$ npm install corre postinstallum processo diferente que a prisão não nomeouCHAVEIRO~/.aws/credentials~/.ssh/id_rsa~/.npmrctokens reais✗ a prisão recusa este caminholê creds reais — ninguém prendeu isto
O buraco do gato-e-rato. Uma prisão de processo bloqueia o processo claude do chaveiro (o caminho tracejado, recusado). Mas a saída real do agente — um repositório com um hook postinstall — corre num processo irmão de que a prisão nunca ouviu falar. Abra uma segunda shell, corra npm install, e o seu postinstall lê ~/.aws/credentials livremente e exfiltra, porque num só host todos os processos partilham um sistema de ficheiros e um chaveiro. A prisão traçou a sua fronteira em volta da coisa errada: o perigo nunca foi o processo nomeado, foi a máquina partilhada.

A prisão traçou a sua fronteira em volta de um processo. O perigo nunca foi o processo; foi que todos os processos na máquina partilham um sistema de ficheiros e um chaveiro. Por isso remenda — prende a shell também, depois o node, depois o gestor de pacotes — e o atacante continua a encontrar uma porta que não trancou, porque num só host há sempre outro processo, outro caminho para os mesmos segredos. É esse o jogo, e a casa tem sempre outra porta.

Trace a linha uma vez, com o hypervisor.

O Bromure deixa de jogar movendo a fronteira um nível abaixo. O agente, as shells que gera, os pacotes que instala, e qualquer código que esses pacotes corram vivem todos dentro de uma VM Linux por perfil. As suas credenciais reais nunca entram nela.

A diferença é o tipo de linha. Uma prisão de processo é uma política acerca de um processo, e um processo irmão contorna-a. A fronteira da VM é o muro entre convidado e host, imposto pelo hypervisor — o mesmo muro que impede uma VM de ler a memória de outra. Não há syscall para o atravessar. O código de dentro não consegue raciocinar o seu caminho até ao seu chaveiro, porque o chaveiro não está sequer no mundo dele.

E dentro dessa linha, você é livre. Instale o pacote não avaliado. Corra o seu postinstall. Deixe o agente reescrever a sua configuração de shell, encher o disco, partir a toolchain. A VM é descartável e nunca guardou nada que importe. Essa liberdade é o ponto todo — exatamente o que uma sandbox tira e o que uma fronteira limpa devolve. Não consegue segurança tornando a bancada menos útil; consegue-a tornando a bancada um lugar onde nada de valioso estava na sala para começar.

Essa mesma linha é onde três garantias deixam de ser conselhos que o agente pode anular e se tornam factos impostos por baixo dele — porque tudo o que a VM faz ao exterior tem de a atravessar.

Três coisas que a linha torna verdadeiras.

VM POR PERFIL — instale tudo, corra tudo, parta tudoagente · shells geradas · npm / pip · código postinstall não confiávelo sistema de ficheiros só tem stubs — aws_secret = stub-… _authToken = stub-… id_rsa = stub-…nada aqui é real, por isso nada aqui vale a pena roubarbuscar um pacoteusar uma credencialpush / drop / deleteFRONTEIRA DO HYPERVISOR — a linha que o código de dentro não pode cruzar① Bloquear pacotes maliciososanálise: OSV + socket.devcooldown: < 2 dias retidoo tarball malicioso nunca aterra② Sem creds para roubarstub-token ⇄ real tokentrocado no fioa varredura no host só acha placeholders③ Perguntar antes de mutarleitura passa · escrita pausapedido no hostvê a chamada literalHOST — tokens reais, atrás do broker~/.aws · ~/.ssh · ~/.npmrc — nunca entram na VM, trocados só no fio, só para uma chamada que permitiu
Uma fronteira, três controlos, impostos por baixo do agente. Dentro da VM o agente faz o que quiser. Mas cada travessia é mediada pelo hypervisor: uma busca de pacote é analisada (OSV + socket.dev) e retida se for mais nova que o cooldown; um uso de credencial encontra um stub que o proxy do host troca pelo token real no fio e volta a trocar; uma escrita que muda estado faz uma pausa para um pedido no host. O chaveiro real está por baixo da linha e nunca entra na VM. O agente não consegue contornar nada disto, porque não há caminho através da fronteira a não ser por ela.

Nenhuma credencial para roubar — o segredo nunca esteve na sala.

Os tokens reais ficam no host. A VM recebe stubs: ficheiros de credenciais sintaticamente válidos cujo conteúdo não significa nada na internet pública. Quando o agente faz uma chamada legítima que precisa de um token real, um proxy do host troca o stub pelo segredo real no fio e volta a trocá-lo na resposta. Uma dependência comprometida a varrer o sistema de ficheiros à procura de ~/.aws/credentials, ~/.npmrc, ou id_rsa encontra placeholders. Isto é a troca de token: a credencial existe, o agente usa-a para aquilo a que se destina, e a cópia que poderia ser roubada não existe em lado nenhum que o mundo do agente alcance.

Estreite o token amplo — perguntar antes de usar, perguntar antes de mutar.

Os tokens reais são normalmente mais amplos do que a tarefa. O broker mantém as concessões efémeras e com escopo, e — a parte que justifica o seu valor — trata uma leitura e uma escrita de forma diferente. Uma leitura passa. Uma chamada que muda estado — um git push, um DROP TABLE, um Terminate* da AWS — faz uma pausa na fronteira e pergunta-lhe, no host, mostrando a operação literal, não um resumo que o agente escreveu.

Isso muda o que um token amplo significa. Um que poderia apagar produção só o consegue fazer quando um humano viu a chamada exata e disse sim; o escopo impresso na credencial deixa de ser o raio de explosão. O agente não consegue pré-aprovar-se, rebaixar o modo, ou ler a concessão — a decisão vive no lado de lá da linha. Quando um agente apagou uma base de dados de produção em nove segundos, o princípio era o mesmo: a coisa que quer correr o comando não devia ser a coisa que decide que ele é seguro.

Não seja o primeiro a descobrir — cadeia de fornecimento travada à porta.

O melhor momento para travar um pacote envenenado é antes de ele aterrar. Cada busca atravessa a fronteira, por isso o proxy analisa-a — OSV para CVEs conhecidos, socket.dev para o que as bases de dados ainda não apanharam: scripts de instalação maliciosos, typosquats, o comprometimento publicado há uma hora. E impõe um cooldown: qualquer release dos últimos dois dias (ajustável) é simplesmente não instalável enquanto o ecossistema se atualiza. A janela toda de um worm é o intervalo entre publicar e retirar; recusar pacotes com um dia é recusar ser o canário. Os hooks postinstall são removidos do tarball à entrada, com o hash corrigido para que a instalação continue a verificar — por isso o pacote que aterra aterra inerte. Nada disto pede ao programador que avalie seja o que for. Puxam o que quiserem; a fronteira é o que espera.

Onde todo o resto fica para trás

A maioria das ferramentas cobre uma camada. O Bromure cobre todas elas.

Isolamento, manter os segredos fora do agente, limitar como eles são usados, escanear a cadeia de suprimentos, barrar a injeção de prompt — a área costuma escolher só uma. Aqui está o mesmo modelo de ameaça do agente aplicado às ferramentas a que as pessoas recorrem, e onde cada uma termina.

Proteção
Dev ContainerVS Code
nonokernel sandbox
agent-vaultoctokraft
Agent VaultInfisical
Docker SandboxesmicroVM
BromureAgentic Coding
Fronteira de isolamento
Onde o raio de dano para
Mesmo contêiner, kernel compartilhado
Allowlists de kernel, sem kernel próprio
O agente roda no lugar
Só proxy; agente sem isolar
microVM, seu próprio kernel
VM por hardware, seu próprio kernel
Manter os segredos fora do agente
Ele consegue ler a credencial real?
Encaminha o agente SSH + creds do git
Bloqueia arquivos de chave; intermedia alguns
Injetados por pipe; sem caminho de leitura
O proxy as anexa no fio
O proxy do host injeta cabeçalhos
Stub trocado no fio
Escopo e aprovação de credenciais
Limites por uso, somente leitura, expiração, consentimento
Sem escopo por uso
Fluxo de aprovação + filtro de egresso
TTL por segredo; bloqueia shells
Filtro de egresso por endpoint
Allowlist de domínios; o código na VM ainda pode usá-la
Consentimento por destino + TTL
Varredura da cadeia de suprimentos
Capturar pacotes maliciosos / vulneráveis
Sem varredura do registro
Só assinatura, sem varredura de pacotes
Fora do escopo
Fora do escopo
Sem varredura de pacotes
Age-gate, OSV, socket.dev
Detecção de injeção de prompt
Varre conteúdo não confiável e arquivos de regras
—
—
—
—
—
PromptGuard + ModernBERT
Trilha de auditoria
Registrar o que o agente fez
Só logs do contêiner
Auditoria local imutável
—
Registro de requisições
Registro de requisições
Trace de sessão completo, criptografado
Inventário da cadeia de suprimentos(Enterprise)
Um registro de cada pacote baixado
—
—
—
—
—
Cada dependência + veredito, pesquisável
Uso de tokens(Enterprise)
Quais arquivos consomem mais tokens
—
—
—
—
—
Por arquivo, repo e modelo
Total — embutido, imposto Parcial — limitado ou opcional Nenhum — não tratado

Ocultar um token não é o mesmo que governar seu uso. O Docker Sandboxes mantém o valor real fora da VM, mas seu proxy ainda anexa essa credencial a qualquer requisição de saída que a sandbox faça, então um pacote comprometido instalado por fora pode gastá-la contra um serviço da allowlist sem nunca vê-la. Só o Bromure escaneia o pacote antes de ele rodar e condiciona cada uso — consentimento, somente leitura, um TTL — impondo os cinco controles em uma única fronteira que o agente não consegue contornar.

Compilado da documentação pública de cada projeto, junho de 2026. Aqui, agent-vault se refere a octokraft/agent-vault (injeção de segredos por pipe), distinto do Agent Vault da Infisical (proxy de credenciais HTTP). O Docker Sandboxes é uma prévia experimental cujas credenciais intermediadas continuam utilizáveis por qualquer coisa dentro da VM. O inventário de pacotes de toda a frota e os detalhamentos de uso de tokens são oferecidos no Bromure Enterprise Manager. Essas ferramentas mudam rápido — viu algo desatualizado? Avise a gente.

A quarta coisa: uma instrução nos dados não é uma ordem.

As três garantias acima partilham uma assunção que vale a pena trazer à superfície: todas defendem contra código que tira algo — uma credencial, um token, a oportunidade de um tarball fresco correr. Há um ataque que não tira nada. Limita-se a dizer ao agente o que fazer. Uma linha enterrada num README que o agente lê, uma string numa página buscada, uma frase na saída de uma ferramenta, uma diretiva escondida no CLAUDE.md que o agente trata como ordens permanentes — o modelo ingere-a como contexto e obedece-lhe como instrução. Vaze o ficheiro. Enfraqueça a verificação. Salte o teste. Uma sandbox não tem opinião sobre nada disto, porque nada cruzou um muro que ela vigie: a instrução chegou como dados, em conteúdo que o agente era suposto ler.

Mas cruzou a linha — tudo o que o modelo vê cruza-a. Por isso, desde a 2.4.0, a fronteira lê-o primeiro, no dispositivo, do lado do host. Um classificador PromptGuard local pontua o conteúdo não confiável que flui para o modelo — leituras de ficheiros, buscas web, saída de ferramentas — à procura de instruções que não têm nada que lá estar. E os ficheiros de regras a que um agente obedece sem questionar — CLAUDE.md, AGENTS.md, GROK.md — recebem uma dupla passagem mais severa: uma análise determinística de Unicode invisível, truques de texto bidirecional e meta-diretivas no estilo «ignore as instruções anteriores», mais um classificador ModernBERT ajustado para o abuso redigido em tom calmo que um filtro de palavras-chave deixa passar. Por perfil, escolhe os dentes: registrar no Security Log, perguntar e ver o texto sinalizado, ou bloquear o pedido antes de o modelo sequer ver o trecho envenenado. Nada sai do Mac.

A colocação é o mesmo argumento das outras três. Um agente que já engoliu uma injeção não é de confiança para a reportar — a primeira instrução da injeção é normalmente alguma versão de não mencione isto. O detetor não pergunta ao agente. Lê o tráfego no lado de lá da linha, onde a persuasão do agente não chega.

Onde a linha não o salva.

Uma fronteira é uma forma específica, não uma palavra mágica. Quatro margens honestas:

O perfil é de longa duração, por isso a persistência persiste.

Um perfil do Bromure não é um disco descartável. Um payload que se escreve a si mesmo num caminho de arranque pode acordar na sessão seguinte — para um convidado sem chaves do host e um broker que só fala tokens efémeros, pedidos e com escopo. Presença numa sala sem nada dentro, mas presença na mesma.

Uma escrita que aprova é uma escrita que acontece.

O pedido apanha a chamada de que o agente não lhe falou. Não lê o seu diff. Aprove um git push e o Bromure encaminha-o — incluindo, em princípio, um workflow envenenado que não reparou. Move a decisão para si e mostra a operação real; lê-la continua a ser a sua função.

O cooldown é uma janela, não um muro.

Dois dias estão ajustados ao intervalo observado entre publicar e retirar. Um atacante paciente pode sentar-se sobre uma versão comprometida para lá do cooldown e ficar instalável ao terceiro dia. Esfomeia os worms do mesmo dia; não responde por um pacote que apenas envelheceu. O socket.dev e o OSV ainda têm de fazer a sua parte.

Dê escopo ao broker de propósito.

O isolamento contém a explosão; o escopo decide quão grande ela poderia ter sido. Um perfil que só lê um repositório não devia ter um token que o escreve; um que nunca publica não devia ter token de publicação. A linha mantém os segredos fora da VM — quais segredos existem afinal continua a ser decisão sua.

A linha que vamos manter.

Eis o compromisso. Um programador não devia ter de se tornar um administrador de sistemas — manter uma lista de permissões, pré-validar cada dependência, abdicar da velocidade que tornou um agente digno de ser usado — para manter o seu chaveiro. Uma sandbox faz da segurança uma troca contra a utilidade, e os programadores, sensatamente, continuam a escolher a utilidade. Uma fronteira recusa a troca: faça tudo do lado de dentro, porque o lado de dentro é dispensável, e as quatro coisas que importam — as suas credenciais, o escopo dos seus tokens, os pacotes que o alcançam, as instruções que alcançam o seu modelo — são decididas numa linha com a qual o código de dentro não consegue discutir.

É por isso que «é uma sandbox» é a descrição que continuaremos a corrigir. Uma sandbox restringe o agente. O Bromure restringe a fronteira, e liberta o agente. O Bromure Agentic Coding é gratuito, de código aberto, e já disponível hoje.