Credenciais e a fronteira de transmissão
Uma sessão de programação agêntica precisa de credenciais — uma chave da Anthropic para falar com o Claude, um token do GitHub para fazer push, chaves da AWS para implementar. Além disso, executa código arbitrário, instala pacotes arbitrários e segue instruções de ficheiros que não escreveu. Entregar os seus segredos reais a um ambiente destes é a forma como as chaves acabam na caixa de entrada de um ladrão.
O Bromure Agentic Coding resolve esta tensão com a fronteira de transmissão: o agente dentro da VM só alguma vez vê tokens de substituição falsos. As suas credenciais reais residem encriptadas no anfitrião macOS e são substituídas na transmissão por um proxy MITM do lado do anfitrião no último momento possível — depois de o pedido ter saído da VM, e apenas quando se destina ao anfitrião a que a credencial pertence. Nenhum ficheiro, variável de ambiente ou processo dentro da VM contém alguma vez uma chave de API real, token OAuth, segredo da AWS ou chave privada SSH.
Este capítulo explica o mecanismo de ponta a ponta e depois percorre a forma como os agentes iniciam sessão, cada tipo de credencial suportado e o seu ciclo de vida, o sistema de aprovação por utilização, o detetor de comprometimento, as saídas de emergência para anfitriões que não funcionam com interceção, e como verificar a fronteira por si mesmo.
As credenciais configuram-se por máquina. Uma máquina é aquilo a que o editor de definições ainda chama espaço de trabalho; as duas palavras designam a mesma VM e as suas definições.
Nota: Este capítulo trata dos conceitos e do comportamento em execução. Para uma referência campo a campo do painel de definições, consulte Definições → Credenciais. As chaves de API e as subscrições dos agentes já não se definem nesse painel; estão em Preferências › Modelos (consulte Modelos e fornecedores).
A fronteira de transmissão em resumo
Três princípios definem o modelo:
- Falsificações na VM. Cada credencial que configura é substituída dentro da VM por uma falsificação que preserva a estrutura. As falsificações mantêm a forma que os validadores esperam — uma falsificação da Anthropic começa por
sk-ant-api03-brm-, uma falsificação do GitHub éghp_mais 36 caracteres — para que ferramentas como oclaude, oghe odoctlas aceitem sem reclamar. - Reais apenas na transmissão. Cada pedido HTTPS que a VM faz é encaminhado por túnel para o proxy do anfitrião, que o desencripta, troca a falsificação pelo valor real e reencripta a montante. A troca é limitada ao anfitrião de destino para o qual a credencial foi cunhada.
- Falha fechada. Se algo contornar o proxy, o pedido transporta apenas uma falsificação e a autenticação a montante falha. Não existe nenhum caminho no qual um segredo real vaze por acidente.
As falsificações são determinísticas: cada uma é derivada do valor real mais um salt de 32 bytes por instalação através de HKDF-SHA256. A mesma chave real mapeia sempre para a mesma falsificação no seu Mac, pelo que os clientes que identificam a sua chave por impressão digital (o Claude Code coloca em cache um hash da chave, por exemplo) nunca veem a credencial "rodar" entre sessões.
| Credencial | Forma da falsificação na VM |
|---|---|
| Chave de API da Anthropic | sk-ant-api03-brm-… |
| Chave de API da OpenAI | sk-brm-… |
| Chave de API da xAI | xai-brm-… |
| Chave de API da Moonshot (Kimi) | sk-kimi-brm-… |
| Chave do OpenRouter usada pelo Claude Code | sk-or-v1-brm-… |
| Chave de API do Amazon Bedrock | bedrock-brm-… |
| Token do GitHub | ghp_ + 36 caracteres (40 no total) |
| Token do GitLab | glpat- + 20 caracteres |
| PAT da DigitalOcean | dop_v1_ + hex (64 caracteres no total) |
| Chave de API do Linear | lin_api_ + 40 caracteres (48 no total) |
| Token de autenticação do Twilio / segredo de chave de API | brm-twilio-… (pelo menos 32 caracteres) |
| Token bearer MCP | brm-mcp_… |
| Palavra-passe de registo Docker | brm-docker-… (pelo menos 40 caracteres) |
| Token bearer Kubernetes | brm-k8s-… |
| Segredo de base de dados | brm-db-… (pelo menos 32 caracteres) |
| Token manual genérico | brm_… |
Não existe um interruptor de ligar/desligar para a fronteira. O proxy é a única via de saída da VM; a troca é simplesmente como as credenciais funcionam nesta aplicação.
Como funciona a troca de ponta a ponta
A viagem de ida e volta completa de um pedido autenticado:
- Arranque da sessão — o plano de tokens. Quando a VM de uma máquina arranca, a aplicação constrói um plano de tokens por máquina que associa cada credencial real ao seu valor falso derivado. Os valores falsos são escritos na VM: variáveis de ambiente (
ANTHROPIC_API_KEY,GH_TOKEN,LINEAR_API_KEY, …) e ficheiros de configuração (~/.git-credentials,~/.docker/config.json,~/.kube/config,~/.aws/config,~/.config/doctl/config.yaml, configurações MCP). Os valores reais são carregados no mapa de troca em memória do proxy, cada um associado ao anfitrião de destino a que pertence. - O pedido sai da VM. O tráfego HTTPS do convidado é encaminhado por túnel através de um socket virtio (vsock porta 8443) para o proxy do anfitrião. A VM não tem outra rota para a rede.
- Terminação TLS. O proxy apresenta um certificado folha forjado por anfitrião — o nome de anfitrião de destino como CN e SAN, uma chave EC por anfitrião — assinado pela Bromure Agentic Coding Root CA. Como o certificado público dessa CA foi instalado no arquivo de confiança da VM no arranque, os clientes TLS do convidado aceitam a ligação, e o proxy pode ler o pedido em texto simples.
- A troca. O proxy procura cada token falso que aparece no pedido (cabeçalhos e, para tipos de credencial que optaram por isso, o corpo) e, se o anfitrião de destino corresponder ao âmbito da credencial, substitui-o pelo valor real.
- Reencriptação a montante. O pedido reescrito é reemitido para o destino real através do
URLSessionda Apple, ou seja, a própria pilha TLS do macOS, que valida o certificado genuíno do servidor a montante. A resposta é transmitida de volta através do túnel para o convidado.
Se o destino não corresponder ao âmbito de uma falsificação, a falsificação sai inalterada (e falha a autenticação a montante) — ou, quando a incompatibilidade parece exfiltração, o pedido é bloqueado de imediato (consulte O detetor de compromisso abaixo).
A Bromure Agentic Coding Root CA
A CA é por instalação e reside em ~/Library/Application Support/BromureAC/ca/ (cert.pem mais um key.pem em modo 0600). O seu assunto é "Bromure Agentic Coding Root CA", organização "Bromure". Propriedades que vale a pena conhecer:
- A validade da CA é de 10 anos. Os certificados folha forjados por anfitrião são válidos por 1 ano e retroativos em 24 horas, pelo que um convidado cujo relógio se desviou durante suspensão/retoma continua a aceitá-los. As folhas são colocadas em cache por anfitrião durante o tempo de vida do processo da aplicação.
- O certificado público é instalado no arquivo de confiança de cada VM no arranque (entregue através da meta share e aplicado com
update-ca-certificates). Nunca sai da sua máquina e não é confiável por nada exceto pelas suas VMs. - Para rodar a CA, saia da aplicação e elimine o diretório
ca/. Uma nova CA é cunhada no arranque seguinte e cada VM adota o novo certificado público no seu arranque seguinte. A rotação não invalida mais nada — os segredos do espaço de trabalho e os metadados deprofile.jsonpermanecem intactos.
Delimitação por anfitrião
Cada entrada de troca está associada a um âmbito de anfitrião. A correspondência é exata-ou-subdomínio e insensível a maiúsculas/minúsculas, nunca por subcadeia: uma credencial com âmbito openai.com corresponde a api.openai.com mas não a openai.com.evil.example — um anfitrião com aparência semelhante não consegue enganar o proxy para que decore o seu pedido com uma chave real. As regras de token manual podem usar deliberadamente um filtro de anfitrião em branco, o que significa "injetar em qualquer anfitrião"; essa é uma escolha explícita que faz por entrada (consulte Chaves de API genéricas).
Falha fechada por construção
O design nunca depende de o proxy ser inevitável para o sigilo — depende de os segredos não estarem lá:
- Um pedido que de alguma forma salta o proxy transporta um token falso; a API a montante rejeita-o.
- Os pedidos da AWS assinados dentro da VM são assinados com uma chave secreta falsa; se chegassem diretamente à AWS falhariam com
InvalidSignatureException(consulte AWS abaixo). - Os bytes da chave privada SSH nunca estão de todo na VM; apenas as assinaturas atravessam a fronteira.
Gerir credenciais no editor de espaços de trabalho
As credenciais de serviços — tokens git, chaves de nuvem, registos, bases de dados, chaves SSH — configuram-se por máquina. Abra as definições da máquina (Definições… no menu da máquina, ou Definições de «máquina»… a partir do menu de uma sessão) e selecione Credenciais em Segurança na barra lateral.
O painel abre com Identidade do Git (um nome e um e-mail gravados em ~/.gitconfig na VM; deixe ambos em branco para manter os padrões do git — os textos de exemplo são só exemplos, não credenciais), seguida de uma lista apenas das credenciais que configurou, agrupadas sob cabeçalhos de categoria (Agents, Git, Cloud, Databases, SSH, Other). Sem nada configurado, o painel diz Nenhuma credencial ainda. Há dois botões em baixo: Adicionar credencial abre um seletor dos tipos de credencial — Git token, SSH key, AWS credentials, DigitalOcean token, Linear API key, Twilio API key, Kubernetes, Container registry, Database e Other API key — e Importar arquivo env… importa em massa a partir de um .env ou ~/.bashrc. Clique em Guardar; o próximo arranque de sessão escreve os valores falsos na VM e carrega os reais no proxy.
As chaves de API dos agentes (Anthropic, OpenAI, xAI, Moonshot e os outros fornecedores de modelos) não estão neste seletor: definem-se em Preferências › Modelos, descrito a seguir. O grupo Agents só aparece num espaço de trabalho que ainda guarda uma chave de agente própria de uma versão anterior; o item de menu Editar em Modelos… abre Preferências › Modelos. Para alterar o acesso aos modelos, use Preferências › Modelos ou o painel Modelos da máquina.
A barreira de aprovação por credencial (Perguntar antes de usar) e a política de escrita de cada serviço definem-se no painel Salvaguardas, não aqui. Consulte Definições → Credenciais para a referência campo a campo.
Sete fornecedores são tratados automaticamente — Anthropic, OpenAI, GitHub, GitLab, DigitalOcean, Twilio e Kubernetes não precisam de regras de token manuais; as respetivas secções tratam deles. Tudo o resto passa por Outras chaves de API.
Importar de um ficheiro env. Importar arquivo env… lê um ficheiro .env existente — ou um ~/.bashrc — e transforma as suas variáveis em credenciais. O analisador trata KEY=VALUE e export KEY=VALUE, retira as aspas e os comentários no fim da linha, e ignora deliberadamente tudo o que precise de avaliação pela shell (interpolação $VAR ou substituição $(…)), pelo que é seguro apontá-lo a um .bashrc real. Uma folha de revisão mostra depois as variáveis com valores ocultos: os nomes reconhecidos (GH_TOKEN/GITHUB_TOKEN, GITLAB_TOKEN, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN, DIGITALOCEAN_ACCESS_TOKEN, LINEAR_API_KEY, TWILIO_ACCOUNT_SID/TWILIO_AUTH_TOKEN, e as chaves dos fornecedores de modelos ANTHROPIC_API_KEY, OPENAI_API_KEY, XAI_API_KEY, MOONSHOT_API_KEY e KIMI_API_KEY, que vão para o fornecedor correspondente em Preferências › Modelos — ou, numa máquina remota, para a sua própria substituição Modelos) são associados automaticamente ao seu tipo de credencial, enquanto os nomes não reconhecidos podem ser importados como tokens manuais genéricos com um âmbito de anfitriões, separados por vírgulas, que indicar. As entradas já configuradas são assinaladas e ficam desmarcadas, para que uma nova importação nunca substitua um segredo em silêncio.
Chaves e subscrições dos agentes
Cada agente de programação — Claude Code, Codex, Grok, Kimi e omp — obtém o acesso aos modelos a partir de um fornecedor configurado em Preferências › Modelos (⌘, e depois Modelos). O mesmo painel existe nas definições de cada máquina, como substituição opcional por máquina. A referência completa — fornecedores, escolha de modelo por agente, substituição por máquina, OpenRouter, servidores personalizados e modelos no dispositivo — está em Modelos e fornecedores. Esta secção trata do que importa para as credenciais: como uma chave ou uma subscrição chega ao agente sem nunca entrar na VM.
Clique num fornecedor na coluna Provedores para abrir a sua janela instantânea. Para cada fornecedor, tem um campo Chave de API; para os quatro fornecedores que oferecem subscrições, tem também os controlos de início de sessão.
Chaves de API
Cole a chave no campo Chave de API da janela instantânea. Nas Preferências, o painel guarda à medida que escreve; nas definições de uma máquina, a chave é guardada com Guardar. Ciclo de vida:
- Na VM: a variável habitual do agente (
ANTHROPIC_API_KEY,OPENAI_API_KEY,XAI_API_KEY, …) contém o valor falso com a forma do fornecedor (sk-ant-api03-brm-…,sk-brm-…,xai-brm-…,sk-kimi-brm-…). - Na transmissão: trocado pela chave real apenas em pedidos para os anfitriões desse fornecedor (
anthropic.com,openai.com,x.ai,moonshot.ai, …). - Em repouso: as chaves, tal como o resto das definições de modelos, são guardadas encriptadas em
models.enc(consulte Onde os segredos residem no anfitrião).
As chaves definidas em Modelos não aparecem nos painéis Credenciais nem Salvaguardas, por isso não têm linha Perguntar antes de usar. (Uma chave de agente ainda guardada no próprio espaço de trabalho desde uma versão anterior aparece lá e pode ser sujeita a aprovação. Importar um ficheiro env já não cria essas chaves: coloca as chaves de agentes nas definições de modelos.)
A partir da CLI, bromure-cli workspaces create --auth token|subscription|bedrock|local e bromure-cli vm run --auth token|subscription|bedrock|local continuam a escolher o modo de autenticação do agente principal do espaço de trabalho.
Subscrições: Claude, ChatGPT, Grok e Kimi
Se tiver uma subscrição em vez de uma chave de API, inicie sessão. As subscrições só existem para Anthropic (Claude), OpenAI (ChatGPT, usado pelo Codex), xAI (Grok) e Moonshot (Kimi); z.ai, Amazon Bedrock, OpenRouter e servidores personalizados só aceitam chaves, e o omp funciona apenas com chave de API. Uma subscrição só alimenta o seu próprio agente: um início de sessão Claude executa o Claude Code, um início de sessão ChatGPT executa o Codex, e assim por diante.
Seja qual for a forma de iniciar sessão, o resultado é o mesmo: os tokens OAuth reais só existem no anfitrião, e o convidado corre com uma chave fictícia — um ANTHROPIC_API_KEY falso para o Claude, um ~/.codex/auth.json pré-preenchido com um JWT fictício de validade muito longa para o Codex (para que o cliente nunca tente atualizá-lo), e tokens substitutos nos ficheiros de credenciais próprios do Grok e do Kimi. O proxy reconhece o valor fictício e injeta na transmissão um token de acesso Authorization: Bearer válido.
Iniciar sessão em Preferências › Modelos
A janela instantânea do fornecedor mostra um de três estados:
| Estado | O que a janela instantânea mostra |
|---|---|
| Sessão não iniciada | Sign in with fornecedor, «Login interativo em uma VM temporária — sem necessidade de chave de API.», e depois «ou cole uma chave de API» por cima do campo Chave de API. |
| Sessão iniciada | Uma linha verde «Sessão iniciada» com a data do início de sessão, Entrar novamente… e Sair…. |
| Expirada | Um painel laranja Login expirado — «fornecedor rejeitou o login salvo (salvo …). As sessões não podem usá-lo até você entrar novamente.» — com Entrar novamente e Sair…. |
Sign in with fornecedor executa o fluxo de registo:
- Uma explicação intitulada Registrar com fornecedor diz o que vai acontecer. Clique em Continuar. (O registo é recusado se o proxy do Bromure não estiver a correr.)
- Arranca uma VM de registo descartável — temporária, isolada, sem pastas de espaço de trabalho, sem segredos guardados e sem mapa de troca de credenciais. Dentro dela, corre o comando de início de sessão do próprio agente.
- O navegador predefinido do seu Mac abre a página de início de sessão do fornecedor. Inicie sessão como habitualmente.
- Os tokens resultantes são capturados no anfitrião, encriptados e guardados; a VM descartável é desligada e eliminada.
Um início de sessão feito a partir das Preferências é sempre partilhado por todas as máquinas. Sair… pergunta «Sair de fornecedor?» — «Os workspaces que usam este login deixam de funcionar até você entrar novamente.» — e elimina o início de sessão guardado. Sair… fica oculto onde não pode atuar.
Iniciar sessão no painel Modelos de uma máquina: âmbito de partilha
A mesma janela instantânea aparece no painel Modelos próprio de uma máquina. Um início de sessão feito aí termina com uma pergunta, Compartilhar com todos os espaços de trabalho?:
| Botão | Efeito |
|---|---|
| Todos os espaços de trabalho | Guarda o início de sessão como o partilhado e remove o início de sessão próprio de cada máquina para esse fornecedor, para que todas as máquinas usem realmente o novo. |
| Apenas este espaço de trabalho | Guarda o início de sessão só para esta máquina. |
O âmbito importa porque uma máquina lê primeiro o seu próprio início de sessão e só recorre ao partilhado quando não tem nenhum. Uma máquina que alguma vez iniciou sessão para si continua a usar esse início de sessão, mesmo depois de um partilhado mais recente, até escolher Todos os espaços de trabalho ou terminar a sessão dessa máquina. Um cliente remoto que inicie o início de sessão recebe a mesma pergunta; se ninguém responder, o início de sessão fica só com essa máquina.
Iniciar sessão a partir do chat
Não precisa de passar primeiro pelas Preferências. Quando um agente numa sessão precisa de iniciar sessão, o chat mostra um cartão intitulado Entrar em fornecedor — «O Bromure faz o login por você neste Mac e mantém sua conta fornecedor fora da máquina — o agente só vê uma chave substituta.» — com um botão Entrar em fornecedor…, e a linha da sessão na barra lateral diz Login necessário. Quando o início de sessão guardado de um agente foi rejeitado, o cartão de erro vermelho oferece o mesmo botão.
Clicar nele inicia sessão sem VM descartável:
- O próprio terminal da sessão executa o comando de início de sessão do agente, e a página de início de sessão do fornecedor abre no navegador do seu Mac («Abrindo seu navegador para fazer login…»).
- Quando o agente troca o código de autorização por tokens, o próprio proxy responde a essa troca: os tokens reais vão diretamente para o repositório do anfitrião. O Claude Code e o Codex são informados de que a credencial fica no Mac; o Grok e o Kimi recebem tokens substitutos, que as suas CLIs escrevem nos respetivos ficheiros de credenciais.
- O agente reinicia com o substituto («Login feito. Iniciando … de novo…»).
Um início de sessão feito a partir do chat substitui o que a máquina estava a ler: o da própria máquina, se tiver um, ou caso contrário o partilhado. Se nenhum início de sessão chegar ao proxy em 5 minutos, o cartão diz «O Bromure não recebeu um login do fornecedor a tempo. Você pode tentar novamente.» Só pode decorrer um início de sessão por máquina de cada vez.
O omp não tem conta onde iniciar sessão; o seu cartão diz «omp precisa de um provedor de modelo» e oferece Definições da máquina… em vez disso.
Aviso: Não execute
/login(nem o comando de início de sessão do agente) à mão dentro da VM para resolver um início de sessão expirado. Use o cartão ou Preferências › Modelos, para que os tokens sejam capturados pelo anfitrião em vez de ficarem na VM.
O Kimi inicia sessão na região internacional
A CLI do Kimi Code usa por predefinição a região da China continental, que rejeita contas de outros sítios. O Bromure inicia a sessão do Kimi na região internacional (auth.kimi.ai, API em api.kimi.ai) definindo as variáveis de região da CLI na VM de registo e em cada sessão. Um início de sessão Kimi capturado na antiga região auth.kimi.com continua a ser reconhecido.
Custódia dos tokens: uma autorização, um atualizador
A atualização dos tokens é feita inteiramente no anfitrião, e cada início de sessão é atualizado por um único dono:
- Uma autorização por posição. O início de sessão partilhado e o início de sessão próprio de cada máquina são posições separadas. Para cada posição corre uma atualização de cada vez, e todas as máquinas que leem essa posição usam o resultado. O convidado nunca tem um token de atualização.
- Momento da atualização. O anfitrião atualiza cerca de 5 minutos antes da expiração, junto do endpoint de tokens do fornecedor (
platform.claude.compara o Claude,auth.openai.compara o Codex,auth.x.aipara o Grok,auth.kimi.aipara o Kimi). Um início de sessão acabado de registar é guardado como já expirado, para que a primeira utilização prove que o caminho de atualização funciona. - Os clones de automação partilham a autorização. Uma máquina clonada para uma automação aponta para o início de sessão da sua máquina base em vez de o copiar.
- Os inícios de sessão das CLIs do seu Mac não são importados. Partilhar uma autorização com uma CLI no anfitrião terminaria a sessão de uma delas sempre que a outra atualizasse.
- Quando não há token disponível para um pedido Claude, o proxy responde ele próprio ao agente em vez de reencaminhar a chave fictícia: uma falha temporária volta como um
529que se pode repetir, e um início de sessão rejeitado como um401que lhe diz para iniciar sessão novamente a partir do Bromure. A janela instantânea mostra então Login expirado.
Credenciais de serviços
AWS
A AWS recebe o tratamento mais profundo de qualquer fornecedor, porque os pedidos da AWS não são autenticados por um token bearer — são assinados (SigV4). Abra Credenciais → AWS no editor de espaços de trabalho; um controlo segmentado escolhe entre Chaves estáticas e SSO / Identity Center.
Chaves estáticas e o reassinador do anfitrião
Cole o seu ID da chave de acesso e a Chave de acesso secreta (mais um Token de sessão STS opcional e uma Região predefinida). O ciclo de vida:
- Na VM:
~/.aws/configaponta para um auxiliar credential_process que fornece — através da vsock porta 8445 — o ID real da chave de acesso emparelhado com uma Chave de acesso secreta falsa de 40 caracteres, omitindo o token de sessão. Cada SDK da AWS, a CLIaws, o terraform e o boto3 adotam isto nativamente; não é necessária configuração específica de ferramenta. - O que o convidado faz: assina os seus pedidos com o segredo falso, produzindo uma assinatura SigV4 sintaticamente válida mas criptograficamente condenada.
- Na transmissão: o reassinador AWS do anfitrião deteta pedidos destinados à AWS em qualquer partição, no seu nome IPv4 ou dual-stack (
*.amazonaws.com,*.api.aws,*.amazonaws.com.cn,*.api.amazonwebservices.com.cn, os domínios da European Sovereign Cloud e das partições ISO; incluindo GovCloud, anfitriões regionais, FIPS e anfitriões S3 ao estilo bucket), remove a assinatura do convidado, injeta oX-Amz-Security-Tokenreal quando existe um token de sessão, e reassina com o segredo real antes de o pedido sair do seu Mac. A salvaguarda AWS cobre os mesmos anfitriões, e a reescrita das credenciais criadas pela VM (abaixo) cobre-os também, maispublic.ecr.aws. Cada reassinatura bem-sucedida emite um evento de auditoriacredential.aws_signcom uma chave de acesso ocultada, mostrado como linha Credencial usada na Linha do tempo de segurança.
Isto é falha-fechada no sentido mais forte: a chave secreta real nunca existe na VM sob qualquer forma, e um pedido que contorne o proxy é rejeitado pela AWS com InvalidSignatureException.
Três estilos de pedido não são suportados e devolvem um erro claro ao convidado em vez de uma falha silenciosa: carregamentos S3 em streaming por blocos (STREAMING-AWS4-HMAC-SHA256-PAYLOAD, respondidos com 501), assinatura assimétrica SigV4A e URLs de query-string pré-assinados (que incorporam a assinatura onde o reassinador não a consegue substituir).
Credenciais criadas pela VM
Algumas chamadas emitem uma nova credencial: aws sts assume-role / get-session-token / get-federation-token, aws iam create-access-key, as credenciais de função do IAM Identity Center, GetCredentialsForIdentity do Cognito, aws ecr get-login-password e, na DigitalOcean, doctl registry login, doctl kubernetes cluster kubeconfig save (e a respetiva chamada de credenciais) e doctl spaces keys create. O proxy retém a resposta a uma chamada destas e substitui cada segredo nela por uma falsificação antes de a VM a ver. Uma chave AWS temporária mantém o seu ID real da chave de acesso, com um segredo e um token de sessão falsos, para que o reassinador saiba com que chave o convidado assinou. Um token de registo ou de cluster torna-se uma falsificação que só é trocada de volta pelo valor real nesse registo ou cluster.
Os valores reais são guardados, cifrados, na configuração do espaço de trabalho, pelo que as falsificações que a VM guardou (em ~/.aws, ~/.docker/config.json ou num kubeconfig) continuam a funcionar após um reinício. Uma chave AWS emitida é reassinada com o seu próprio segredo e token de sessão. Depois de expirar, os pedidos assinados com ela são recusados em vez de reassinados com a chave do próprio espaço de trabalho, o que os executaria com uma identidade diferente. As credenciais expiradas são eliminadas 30 dias depois de expirarem.
Uma resposta que o proxy não consegue reescrever por completo nunca é passada adiante: em vez disso, o convidado recebe um 502. As chamadas que definem um segredo escolhido pela própria VM, que nenhuma falsificação pode substituir, são recusadas em qualquer modo das salvaguardas: iam:CreateLoginProfile, UpdateLoginProfile, CreateServiceSpecificCredential e ResetServiceSpecificCredential. Um pedido de consentimento da AWS indica a chamada que assinaria (por exemplo sts:AssumeRole), e cada credencial emitida gera um evento credential.minted.
SSO / IAM Identity Center
Se a sua organização usa o IAM Identity Center, selecione SSO / Identity Center em vez de colar chaves de longa duração:
- Clique em Conceder acesso a ~/.aws e aprove o pedido de acesso à pasta (uma concessão com âmbito de segurança; a pasta é lida no anfitrião e nunca montada na VM).
- Escolha o seu perfil no seletor Perfil SSO. A aplicação descobre secções
[profile …]em~/.aws/configque transportamsso_start_url,sso_account_idesso_role_name, resolvendo referências[sso-session …]; o ID da conta e a função são mostrados apenas para leitura. - No arranque da sessão, o anfitrião resolve as credenciais de função temporárias a partir da cache de tokens SSO (
~/.aws/sso/cache). Se o token em cache tiver expirado, o seu navegador abre paraaws sso login— executado no anfitrião, a partir de/usr/local/bin/aws.
As chaves temporárias resolvidas alimentam o mesmo reassinador que as chaves estáticas; a VM continua a nunca ver um segredo. As credenciais atualizam-se automaticamente no anfitrião cerca de 5 minutos antes de expirarem.
Bedrock
O Amazon Bedrock é um fornecedor de modelos para todos os agentes, não um modo de autenticação de um deles. Ative Usar Amazon Bedrock na janela instantânea Amazon Bedrock de Preferências › Modelos (ou do painel Modelos de uma máquina) e escolha IDs de modelos Bedrock por agente. O Claude Code corre nativamente no Bedrock; os outros agentes chegam lá através da API compatível com OpenAI do Bedrock. Os pedidos são assinados com as credenciais AWS de cada máquina (Credenciais → AWS, estáticas ou SSO) pelo mesmo caminho de reassinatura, já que os endpoints do Bedrock são anfitriões *.amazonaws.com — ou, se colar uma no campo Chave de API do Bedrock (opcional — senão as credenciais da AWS assinam) da janela instantânea, com essa chave, que a VM só vê como um valor falso bedrock-brm-…. A janela instantânea aceita também uma Região da AWS; deixe-a vazia para usar a região AWS de cada máquina. Consulte Modelos e fornecedores.
Tokens Git HTTPS (GitHub, GitLab, Bitbucket, auto-hospedados)
Os tokens de acesso pessoal para git-sobre-HTTPS residem em Tokens do GitHub / Tokens do GitLab / Tokens do Bitbucket (coletivamente, tokens HTTPS). Cada entrada recebe um anfitrião, um nome de utilizador e o token; instâncias auto-hospedadas de GitLab ou Gitea funcionam definindo o campo de anfitrião. Ciclo de vida:
- Na VM: uma falsificação é escrita em
~/.git-credentialse na configuração dogh/glab;GH_TOKENeGITLAB_TOKENsão exportados para que as CLIs se autentiquem automaticamente. As formas das falsificações correspondem aos validadores de cada fornecedor (ghp_+ 36 para o GitHub,glpat-+ 20 para o GitLab,brm_…caso contrário), pelo que as verificações de prefixo e comprimento noghe noglabpassam. - Na transmissão: trocada pelo token real nos pedidos ao anfitrião git dessa entrada.
- Aprovação: cada entrada obtém a sua própria linha Perguntar antes de usar no painel Salvaguardas.
Se só precisar de git push sobre SSH, pode não precisar de todo de um token HTTPS — consulte Chaves SSH abaixo.
Chaves de API genéricas (Outras chaves de API / Regras de token manual)
Para qualquer API que a aplicação não trate automaticamente, adicione uma entrada em Outras chaves de API (as regras de token manual, também apresentadas como Troca de token MITM). Clique em Adicionar token e forneça:
| Campo | Significado |
|---|---|
| Nome | Uma etiqueta para a entrada. |
| Valor | O segredo real (armazenado encriptado no anfitrião). |
| Nome da variável de ambiente | A variável sob a qual a falsificação é exportada dentro da VM. Referencie-a a partir do seu código. |
| Filtro de anfitrião (opcional) | O âmbito de anfitrião para a troca. |
Dois casos-limite são deliberados:
- Nome da variável de ambiente vazio: nada é exportado; você copia a falsificação do banner de boas-vindas da sessão e coloca-a onde as suas ferramentas precisarem.
- Filtro de anfitrião em branco: o valor real é injetado em qualquer anfitrião, sem perguntar. Essa é uma escolha explícita sempre ativa — útil para APIs com muitos nomes de anfitrião regionais — mas significa que o âmbito da credencial já não a protege. Para condicionar um segredo sem âmbito, ative Perguntar antes de usar para ele no painel Salvaguardas (ou atribua-lhe afinal um filtro de anfitrião).
A Anthropic, a OpenAI, o GitHub, o GitLab, a DigitalOcean e o Kubernetes nunca precisam de entradas manuais aqui.
Referências de segredos 1Password (op://)
Em vez de colar um segredo real, o valor de uma Outra chave de API pode ser uma referência de segredo 1Password — op://vault/item/field, ou a forma com chavetas {{ op://vault/item/field }} que o op inject e os ficheiros .env.op usam. Apenas a referência é alguma vez armazenada em disco; o próprio segredo nunca é escrito em lado nenhum no anfitrião ou na VM. O editor reconhece a referência, mostra-a às claras (não é um segredo) e nota que se resolve através do 1Password.
Em cada arranque de espaço de trabalho, o Bromure resolve a referência do lado do anfitrião com a CLI do 1Password (op read), cunha uma falsificação a partir da cadeia de referência (para que a falsificação permaneça estável mesmo quando o segredo roda) e exporta apenas essa falsificação para a VM. O proxy MITM troca então a falsificação pelo valor resolvido na transmissão, exatamente como faz para um segredo colado — e volta a resolver a cada 2 minutos, pelo que rodar o item no 1Password entra em vigor dentro de alguns minutos sem reiniciar.
Isto precisa da CLI op instalada e com sessão iniciada — desbloqueio biométrico através da aplicação 1Password, ou op signin num terminal. Se o op não for encontrado, o editor mostra uma ligação Obter a CLI do 1Password e o espaço de trabalho apresenta instruções de instalação no arranque; se a resolução falhar (sem sessão iniciada, ou o item não existe), o Bromure apresenta o erro para que o possa corrigir e reiniciar o espaço de trabalho.
Importar um ficheiro .env ou .env.op (Importar arquivo env… no painel Credenciais) reconhece automaticamente os valores op:// — sob nomes reconhecidos como ANTHROPIC_API_KEY ou arbitrários como STRIPE_KEY — e guarda cada um como token manual que contém a referência.
DigitalOcean
Cole um token de acesso pessoal em Credenciais → DigitalOcean (a ligação Abrir a página de tokens da DigitalOcean no seu navegador leva-o à geração de tokens). A falsificação (dop_v1_ + hex, 64 caracteres) é exportada como DIGITALOCEAN_ACCESS_TOKEN e escrita em ~/.config/doctl/config.yaml, pelo que doctl auth init é desnecessário. A troca cobre pedidos a digitalocean.com, mais uma segunda entrada para o blob de autenticação Basic em base64 usado por docker login / doctl registry login contra registry.digitalocean.com, pelo que os pushes e pulls de registo também se resolvem.
Linear
Cole uma chave de API pessoal em Credenciais → Linear (ligação: Abrir as configurações da API do Linear no seu navegador; as chaves vêm de linear.app → Settings → API). O valor falso (lin_api_ + 40) é exportado como LINEAR_API_KEY, que o SDK do Linear, os servidores MCP e as ferramentas CLI leem automaticamente; a troca está estritamente limitada a linear.app (GraphQL em api.linear.app e MCP em mcp.linear.app). Uma chave do Linear no espaço de trabalho é também o pré-requisito para os acionadores de automação por issues do Linear — consulte Automatizações.
Twilio
Adicione uma credencial Twilio API key com o SID em Account SID (AC…) or API Key SID (SK…) e o segredo em Auth Token / API Key secret (ambos de console.twilio.com). O Twilio autentica-se com HTTP Basic, em que o SID é uma identidade — viaja no URL do pedido — e só o token é secreto. Ciclo de vida:
- Na VM:
TWILIO_ACCOUNT_SIDcontém o SID real eTWILIO_AUTH_TOKENum valor falsobrm-twilio-…, para que os SDKs do Twilio e a CLI os leiam sem configuração. - Na transmissão: em pedidos para
twilio.com, o proxy troca pelos reais tanto o token falso simples como o bloco de autenticação BasicSID:tokenjá codificado em base64. - Aprovação: através de Perguntar antes de usar no painel Salvaguardas.
Importar arquivo env… reconhece TWILIO_ACCOUNT_SID / TWILIO_API_KEY_SID e TWILIO_AUTH_TOKEN / TWILIO_API_SECRET e junta-os numa única credencial Twilio.
Tokens bearer de servidor MCP
Os servidores MCP de transporte HTTP configurados no painel MCP recebem o mesmo tratamento: o token bearer real permanece no anfitrião, uma falsificação brm-mcp_… é injetada na configuração MCP que o agente lê, e o proxy troca-a na transmissão, com âmbito no anfitrião do servidor. Apenas os servidores de transporte HTTP ativados com um token bearer não vazio recebem uma entrada de troca.
Uma cortesia extra: para anfitriões com uma entrada brm-mcp_, o proxy responde aos caminhos de descoberta OAuth/OIDC (endpoints .well-known de servidor de autorização, recurso protegido e configuração OpenID) com 404. O Claude Code trata então o servidor como pré-autenticado em vez de tentar o seu próprio fluxo OAuth — que de qualquer forma nunca poderia completar-se dentro da VM.
Registos de contentores (Docker Hub, GHCR e afins)
Credenciais → Registos de contentores gere a autenticação HTTP Basic para docker pull/push. Existem predefinições para o Docker Hub (docker.io), o GitHub Container Registry (ghcr.io) e o GitLab Container Registry (registry.gitlab.com); qualquer outro registo pode ser adicionado por anfitrião. Ciclo de vida:
- Na VM:
~/.docker/config.jsoncontém um blob de autenticação falso — o base64 do seu nome de utilizador emparelhado com uma palavra-passebrm-docker-…derivada — para que o Docker acredite estar com sessão iniciada. - Na transmissão: o proxy substitui o blob base64 real no anfitrião de registo correspondente. A dança de tokens da distribution-spec também é tratada: as entradas de troca são adicionadas para realms de autenticação conhecidos (o Docker Hub autentica-se contra
auth.docker.io, o registo da DigitalOcean contraapi.digitalocean.com). - Importação: clique em Importar config.json… para extrair entradas de um
~/.docker/config.jsonexistente no anfitrião. As entradas delegadas acredsStore/credHelperssão ignoradas — as suas palavras-passe residem no keychain do SO, não no ficheiro — e o resumo da importação relata quantas foram ignoradas e porquê. - Aprovação: por registo, através de Perguntar antes de usar no painel Salvaguardas. Remover este registo elimina uma entrada.
Contextos Kubernetes
Credenciais → Kubernetes transforma contextos de kubeconfig em acesso ao cluster mediado por proxy. Clique em Importar kubeconfig para analisar um kubeconfig existente numa linha por contexto (o contexto atual primeiro, tipo de autenticação detetado automaticamente), ou Adicionar contexto para introduzir manualmente um URL de servidor, credenciais, namespace e CA do cluster. Em todos os casos, a VM recebe um ~/.kube/config sintético: o kubectl no convidado fala com o proxy (confiado através da CA do Bromure), nunca diretamente com o servidor de API.
Por tipo de autenticação:
- Os contextos de token bearer recebem um marcador de posição
brm-k8s-…na VM, trocado pelo token real na transmissão. - Os contextos de certificado de cliente recebem um certificado e chave autoassinados descartáveis na VM; o certificado e a chave reais são registados no anfitrião como um
SecIdentitye usados para mTLS a montante. - Os contextos de plugin exec nunca executam de todo o plugin na VM. O poller de plugin exec executa o comando no anfitrião a cada intervalo de atualização (predefinição 600 segundos, mínimo 60), analisa o JSON
ExecCredentiale alimenta o token fresco no mapa de troca. As atualizações preservam o estado de consentimento da entrada.
Se o kubeconfig fornecer a CA própria do cluster, ela é reencaminhada para que o proxy possa verificar o servidor de API a montante. Os campos de caminho de ficheiro num kubeconfig importado (CA, cert, chave) são lidos avidamente no momento da importação — alterações posteriores a esses ficheiros em disco não são adotadas. Cada contexto obtém a sua própria linha Perguntar antes de usar no painel Salvaguardas, onde uma política de escrita pode adicionalmente remover verbos destrutivos (kubectl delete, AWS Delete*/Terminate*, docker push, git push) do lado do anfitrião antes de um byte ser reencaminhado — uma camada separada da troca de credenciais.
Bases de dados HTTP (MongoDB, ClickHouse, Elasticsearch)
Credenciais → Bases de dados (as secções MongoDB / ClickHouse / Elasticsearch) cobre endpoints de base de dados que falam HTTPS — a Data API do Mongo, a interface HTTP do ClickHouse, o Elastic. Cada endpoint recebe um motor, anfitrião, segredo, nome de utilizador, tipo de autenticação e um ou mais nomes de variável de ambiente (separados por vírgulas) sob os quais a falsificação brm-db-… é exportada; referencie essas variáveis a partir do seu código ou cadeias de ligação.
As credenciais de base de dados são a única família em que a troca varre o corpo do pedido além dos cabeçalhos e parâmetros de consulta, porque os segredos de ligação viajam rotineiramente dentro de cargas úteis JSON ou SQL. O proxy corrige o Content-Length após uma troca no corpo; corpos multipart ou binários não relacionados de outro tráfego nunca são tocados (todas as outras trocas têm âmbito nos cabeçalhos). Os endpoints de autenticação Basic também têm o seu blob base64 de utilizador-e-segredo trocado. O Perguntar antes de usar por endpoint e a política de escrita são definidos no painel Salvaguardas.
Chaves SSH
O SSH é tratado sem qualquer token: o SSH_AUTH_SOCK da VM é suportado por uma ponte ssh-agent sobre vsock (porta 8444). O convidado pode listar identidades e solicitar assinaturas, mas os bytes da chave privada residem apenas no anfitrião e fisicamente não podem ser lidos ou extraídos de dentro da VM. Existem duas fontes de chave, ambas em Credenciais → Chaves SSH:
- A chave predefinida por espaço de trabalho. Um par de chaves ed25519 predefinido partilhado é gerado no arranque da aplicação (armazenado em
default-ssh/no Application Support) e copiado para o diretório do agente de cada novo espaço de trabalho. O painel mostra a chave pública do espaço de trabalho para que a possa colar no seu anfitrião git (para o GitHub: github.com/settings/keys). Também pode cunhar uma chave nova a partir da CLI combromure-cli workspaces ssh-keygen <workspace-id|name>, que imprime a nova chave pública. - Chaves importadas. Clique em Importar… / Importar ficheiro… em Chaves SSH importadas e aponte a aplicação a um ficheiro de chave privada existente — RSA, ed25519 e ECDSA são suportadas, chaves encriptadas incluídas. Uma chave encriptada pede a sua palavra-passe uma vez na importação; a palavra-passe é armazenada no Keychain do macOS (serviço
io.bromure.agentic-coding.ssh-key-passphrases) e fornecida viaSSH_ASKPASSno arranque, nunca registada. A assinatura de chaves importadas flui através de um processo ssh-agent privado que a aplicação gera para si própria (ssh-agent -Dnum socket sob o diretório temporário) — separado de qualquer outra coisa no seu sistema. - Chaves de um agente do anfitrião. Uma chave cuja metade privada não pode sair do seu dispositivo — uma YubiKey ou outra chave de segurança por trás do gpg-agent, o Secretive, o 1Password — adiciona-se antes com Do agente do anfitrião…. Escolha o socket do agente (vazio = o próprio
SSH_AUTH_SOCKda aplicação, que para uma aplicação aberta a partir do Finder é o agente do macOS, e não um que a sua shell exporte; para o gpg-agent use~/.gnupg/S.gpg-agent.ssh), clique em Carregar e marque as chaves que o espaço de trabalho pode usar. Nada é copiado: a VM só vê as chaves marcadas — e apenas enquanto o agente as detém, por isso uma chave desligada não é oferecida — e os pedidos de assinatura delas são reencaminhados para esse agente, pelo que um pedido de toque ou PIN aparece no seu Mac como habitualmente (o pedido espera por ele até dois minutos). As outras chaves do agente continuam invisíveis para a VM, e um pedido para assinar com uma delas é recusado.
Por chave importada, ativar Perguntar antes de usar no painel Salvaguardas faz com que cada pedido de assinatura na VM peça consentimento. Cada assinatura — chave predefinida ou importada — emite um evento de auditoria credential.ssh_sign que transporta a impressão digital SHA256 da chave e se se tratou de uma chave gerida, importada ou de um agente do anfitrião.
Nota: O seu ssh-agent de início de sessão do macOS (o do launchd) — ou qualquer outro agente do anfitrião — é deliberadamente nunca exposto à VM no seu todo. Apenas as chaves por espaço de trabalho, as chaves que importou explicitamente e as chaves individuais de agentes do anfitrião que escolheu são alcançáveis a partir de uma sessão.
Aprovação por utilização e durações de concessão
Qualquer credencial neste capítulo pode ser sinalizada com Perguntar antes de usar — uma caixa de verificação por credencial no painel Salvaguardas (rotulada Exigir aprovação para usar no próprio controlo), desativada por predefinição, descrita na interface como: "Apresenta um diálogo de confirmação na primeira vez que esta credencial é usada numa sessão."
Quando uma credencial condicionada é usada pela primeira vez numa sessão, o proxy retém o pedido e mostra um diálogo de consentimento intitulado Permitir que "nome do espaço de trabalho" use a credencial? (com o nome do seu espaço de trabalho e a etiqueta da credencial preenchidos), oferecendo quatro botões:
| Botão | Concessão |
|---|---|
| Permitir por 5 minutos | Limitado no tempo; a credencial flui sem mais pedidos durante 5 minutos. |
| Permitir por 1 hora | Limitado no tempo, 1 hora. |
| Permitir pelo resto da sessão | Até a VM da máquina ser desligada. |
| Não permitir | O pedido é recusado; a recusa é lembrada durante 5 minutos para que uma tempestade de repetições de um agente não produza uma tempestade de diálogos. |
Comportamento que vale a pena conhecer:
- Coalescência. Pedidos concorrentes que precisam da mesma credencial colapsam num único diálogo — um agente falador que dispara doze chamadas de API paralelas produz um único pedido, e as doze seguem a sua decisão.
- A recusa vence. Uma recusa ativa faz curto-circuito antes de qualquer permissão mais antiga ser consultada.
- Efémero por conceção. As autorizações e recusas só existem em memória e são revogadas quando a VM é desligada. «O resto da sessão» nunca sobrevive a um reinício da VM, e nada é guardado entre execuções da aplicação.
- Sessões headless. Numa sessão SSH ou headless, o pedido aparece no tmux da máquina em vez de um alerta gráfico — consulte Acesso remoto.
Para a AWS, o portão aplica-se a cada chamada de assinatura do lado do anfitrião; para as chaves SSH, aos pedidos de assinatura; para tudo o resto, à primeira troca na transmissão da sessão.
Dica: O portão de consentimento é por credencial, não por anfitrião. Se quiser que um token manual sem âmbito permaneça sob controlo, a aprovação é o mecanismo concebido para isso.
A janela de Aprovações de Credenciais
Janela → Aprovações de Credenciais… abre uma vista ao vivo de cada decisão de consentimento tomada durante a execução atual da aplicação: permissões limitadas no tempo (5 minutos / 1 hora / resto da sessão) e recusas lembradas. Cada linha mostra o nome do espaço de trabalho e o tempo restante, e oferece Revogar; Revogar tudo (⌘⌫) limpa tudo de uma vez. A lista atualiza-se automaticamente a cada 2 segundos e encolhe naturalmente à medida que as concessões expiram.
Como as decisões só existem em memória, a janela fica vazia depois de as autorizações expirarem, depois de a VM ser desligada (autorizações com âmbito de sessão) e depois de a aplicação sair. É um painel de controlo para o presente, não um registo de auditoria — para o histórico, use a Linha do tempo de segurança e o Rastreio.
O detetor de compromisso
As falsificações têm dupla função: além de substituírem segredos, são fios de disparo. Um token falso tem exatamente uma família de destino legítima — o âmbito de anfitrião para o qual foi cunhado. Não há razão honesta para que sk-ant-api03-brm-… apareça num pedido a pastebin.example. Por isso, o proxy analisa cada pedido de saída — cabeçalhos e corpo, através de um autómato de Aho-Corasick, suficientemente barato para correr sobre tudo — em busca de qualquer falsificação a caminho de fora do seu âmbito.
Quando encontra uma, trata o pedido como tentativa de exfiltração de credencial:
- O pedido é bloqueado com HTTP 451. Nem um único byte é reencaminhado para o destino.
- A VM é colocada em pausa de imediato. Se a máquina estava a correr em segundo plano, é primeiro trazida para o ecrã, e a sua imagem congelada fica tingida de vermelho.
- Aparece um alerta crítico, intitulado Este ambiente pode ter sido comprometido: «O Bromure detectou uma tentativa de saída para vazar uma credencial de sessão de “máquina” para um host para o qual ela não foi emitida. A VM foi pausada.» Em Vazamentos detectados: lista uma linha por fuga — uma pré-visualização do token (como
sk-a…f9q3), o nome da credencial, o anfitrião para o qual foi emitida e o anfitrião para onde foi enviada. - A deteção é registada como uma linha vermelha Intermediação de credenciais na Linha do tempo de segurança e, nas instalações inscritas, como evento
credential.exfiltration.
O alerta oferece quatro botões:
| Botão | Efeito |
|---|---|
| Desligar (predefinição) | Para a VM e marca a máquina como comprometida. |
| Bloquear | Trava só este pedido (que já recebeu um 451) e retoma a VM. Nada é memorizado: se o agente tentar de novo, o detetor volta a disparar e o alerta reabre. |
| Permitir | Confia no anfitrião observado apenas durante o resto desta sessão e retoma a VM. A partir daí a credencial é trocada e enviada para esse anfitrião (e os seus subdomínios), e os pedidos para ele deixam de ser assinalados. A decisão é registada como uma linha verde Intermediação de credenciais, «allowed by user for this session», e, nas instalações inscritas, como credential.exfiltration_allowed. A lista de permissões é limpa quando a VM é desligada. |
| Salvar para investigação | Pede uma pasta, exporta disk.img (uma cópia do disco de sistema da VM), home.tar.gz (a pasta pessoal da máquina) e shares/<nome>.tar.gz para cada pasta partilhada, depois desliga a VM e marca a máquina como comprometida. O estado da RAM da VM é descartado. |
Só Desligar responde à tecla Return; Bloquear, Permitir e Salvar para investigação não têm equivalente de teclado, por isso retomar uma VM possivelmente hostil — e mais ainda enviar-lhe a credencial — exige sempre um clique explícito. Só aparece um alerta de cada vez; as deteções repetidas enquanto está aberto são descartadas (cada uma continua bloqueada).
Dica: Permitir existe para configurações legítimas com vários anfitriões — por exemplo, uma chave com formato OpenAI que uma ferramenta envia deliberadamente para o endpoint compatível com OpenAI de outro fornecedor. Se não reconhecer o destino, não o permita.
Se a máquina estiver a ser espelhada por um cliente remoto, a pergunta aparece no cliente como pedido pendente com Desligar, Bloquear e Permitir (salvar para investigação precisa de um seletor de pastas local, por isso só é oferecido no próprio Mac). Só a VM afetada fica em pausa; o anfitrião continua a servir todas as outras máquinas. Um pedido sem resposta desliga a VM ao fim de 3 minutos.
Uma máquina marcada como comprometida recusa-se a arrancar até remediar a situação. Ao iniciá-la, aparece «To continue, the VM disk image and the persistent home folder must be wiped. Your tokens, ssh keys, and workspace settings are preserved.» com Apagar e iniciar e Cancelar (a tecla Return não confirma a limpeza). Preste atenção ao aviso que a acompanha: as pastas partilhadas NÃO são apagadas, por isso, se o comprometimento veio de um pacote ou ficheiro numa pasta partilhada, pode ainda lá estar — reveja essas pastas antes de retomar o trabalho.
Resposta recomendada a um alerta de compromisso: abra o Inspetor de Rastreios (⇧⌘I) ou execute bromure-cli trace leaks para ver o anfitrião e o pedido ofensivos, decida se uma dependência de projeto ou uma instrução por injeção de prompt foi responsável (consulte Injeção de prompt e Cadeia de fornecimento), depois limpe e reinicie.
Detalhes de âmbito:
- As falsificações sem âmbito estão isentas. Um token manual com um filtro de anfitrião em branco é "qualquer anfitrião" por design e não pode acionar o detetor; os marcadores de posição de subscrição fictícios são igualmente excluídos.
- Os irmãos de primeira parte são tolerados. A correspondência espelha a política de âmbito da troca, com uma relaxação: os anfitriões sob o mesmo domínio registado que o fornecedor da credencial (a infraestrutura do Claude ou do Codex sob
anthropic.com, por exemplo) usam uma correspondência de família, pelo que um token legítimo deapi.anthropic.comvisto emmcp-tools.anthropic.comnão é um alarme falso. Todo o resto é estrito. - Os vazamentos com aparência real também são sinalizados. Independentemente dos fios de disparo falsos, o proxy sinaliza segredos não trocados, com aparência real no tráfego de saída — valores
Beareroux-api-keycom prefixos conhecidos (sk-ant-,ghp_,AKIA, …) ou tokens opacos de 20 caracteres ou mais. Estes aparecem como avisos de vazamento no Inspetor de Rastreios e embromure-cli trace leaks; normalmente significam que um segredo real foi colado na VM à mão, o que a fronteira de transmissão existe para tornar desnecessário.
O detetor em si está sempre ativo. O que pode desligar, por máquina, é a interrupção — consulte a secção seguinte.
Saídas de emergência
Alguns anfitriões e clientes não funcionam com interceção total: um servidor com CA privada em que o anfitrião não confia, um cliente que fixa o certificado do seu servidor, ou uma configuração legítima que dispara o alerta de comprometimento vezes sem conta. Três definições por máquina, no fundo do painel Salvaguardas, aliviam a fronteira nesses casos sem a desligar. As três aplicam-se de imediato, sem reinício.
| Definição | Predefinição | O que faz |
|---|---|---|
| Permitir bypass inseguro por requisição (X-bromure-insecure) | Ligado | Quando um pedido para um anfitrião autoassinado ou com CA privada falha a validação do certificado, o agente pode repeti-lo com o cabeçalho X-bromure-insecure: yes para saltar a validação do certificado desse servidor a montante. A interceção, o rastreio e a proteção contra fugas continuam ativos, e o Bromure não injeta nenhuma credencial real nesse pedido — só saem os valores falsos do convidado. Cada utilização fica registada na Linha do tempo de segurança como linha TLS upstream: «allowed — certificate validation skipped (X-bromure-insecure); no credentials injected». Ligado por predefinição porque só atua quando o convidado envia o cabeçalho; desligue-o para proibir o cabeçalho de todo. |
| Desativar interceptação transparente | Desligado | Para o desvio ao nível da rede que obriga o HTTP/HTTPS da VM a passar pelo Bromure. Os sockets em bruto e os clientes com certificado fixado chegam então diretamente à rede real e ao certificado real a montante. O proxy continua: HTTP(S)_PROXY mantém-se definido, por isso as ferramentas que respeitam o proxy (apt, git, pip, curl, node…) e as chamadas de API do próprio agente continuam a passar pelo Bromure e mantêm a troca de credenciais, o rastreio e as salvaguardas. O tráfego que ignora as definições de proxy deixa de estar coberto pelas regras de saída. |
| Não alertar sobre exfiltração de credenciais | Desligado | Suprime o alerta de comprometimento e a pausa da VM. O pedido que tenta vazar é ainda assim bloqueado com um 451 e ainda assim registado na Linha do tempo de segurança («blocked — exfiltration attempt (alerts off, VM not paused)»); só a interrupção desaparece. |
Aviso: Cada uma destas definições troca alguma proteção por compatibilidade. Prefira a mais restrita: o cabeçalho por pedido para um certificado não fidedigno, Permitir no alerta de comprometimento para um destino de confiança, e os interruptores de toda a máquina só para uma máquina que não consegue funcionar de outra forma.
Onde os segredos residem no anfitrião
Tudo o que é sensível é encriptado em repouso com AES-GCM sob uma chave-mestra de 256 bits por instalação — o cofre de segredos. A chave-mestra reside no Keychain de Proteção de Dados do macOS, com âmbito na identidade de assinatura da aplicação, com acessibilidade kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly e sincronização iCloud desativada. Nunca solicita, nunca sincroniza e nunca sai do Mac. Se o keychain estiver inalcançável (uma compilação não assinada ou não aprovisionada), a aplicação recorre a um ficheiro de chave em modo 0600 armazenado ao lado do texto cifrado — mais fraco, uma vez que a chave e o texto cifrado partilham então um disco, mas mantém a encriptação em repouso a funcionar; uma versão totalmente aprovisionada usa o keychain.
Consequências práticas:
- As cópias de segurança e as cópias são texto cifrado. Uma cópia de segurança do Time Machine ou uma pasta
Application Supportcopiada contém apenas blobs encriptados; sem a entrada de keychain deste Mac não podem ser desencriptados (a menos que a chave de recurso em ficheiro estivesse em uso e fosse copiada juntamente). - Limpar a entrada do keychain roda a chave. Os blobs encriptados existentes tornam-se ilegíveis e você reintroduz as suas credenciais. Os metadados não sensíveis em
profile.jsonnão são afetados. - Nada é sincronizado para lado nenhum. Nenhuma credencial, arquivo de tokens ou material de chave é carregado, sincronizado ou copiado pela própria aplicação.
Localizações em disco, todas sob ~/Library/Application Support/BromureAC/ salvo indicação em contrário:
| Localização | Conteúdo |
|---|---|
ca/cert.pem, ca/key.pem | A Bromure Agentic Coding Root CA (chave em modo 0600). Elimine o diretório para rodar. |
fake-salt.bin | O salt HKDF de 32 bytes por instalação por detrás da derivação de falsificações (0600). Eliminá-lo roda cada falsificação neste Mac. |
claude-subscription.enc, codex-subscription.enc, grok-subscription.enc, kimi-subscription.enc | Repositórios de subscrições encriptados com AES-GCM: o início de sessão partilhado mais o início de sessão próprio de cada máquina, 0600. |
models.enc | As definições globais de modelos de Preferências › Modelos, incluindo as chaves de API dos fornecedores, encriptadas com a chave do cofre. |
pii/<workspace-id>.key | A chave própria de cada máquina por trás dos substitutos da proteção de dados pessoais (0600). |
secrets-master.key | A chave-mestra de recurso em modo 0600 — presente apenas quando o Keychain de Proteção de Dados está inalcançável. |
default-ssh/id_ed25519.raw, default-ssh/id_ed25519.pub | O par de chaves SSH predefinido partilhado, copiado para as máquinas novas. |
profiles/<id>/ssh/ | As chaves SSH emitidas para cada máquina (o diretório do agente). |
Keychain: io.bromure.agentic-coding.master-key | A chave-mestra do cofre AES-256 (conta v1), Keychain de Proteção de Dados. |
Keychain: io.bromure.agentic-coding.ssh-key-passphrases | Palavras-passe de chaves SSH importadas, um item por perfil/ficheiro de chave. |
As leituras do lado do anfitrião para importações — ~/.aws/config, ~/.aws/sso/cache/*.json, ~/.docker/config.json, ficheiros kubeconfig — acontecem apenas no anfitrião; nenhum desses ficheiros é alguma vez montado numa VM. Os corpos de rastreio encriptados (consulte Rastreio) usam a mesma chave de cofre.
Verificar a fronteira você mesmo
A fronteira de transmissão é concebida para ser verificável, não aceite por fé. A partir de uma shell dentro de qualquer sessão:
1. O ambiente contém falsificações.
echo "$ANTHROPIC_API_KEY"
# sk-ant-api03-brm-… ← a fake, not your key
env | grep -E 'TOKEN|KEY'
# every value is brm_/ghp_/glpat_/dop_v1_/lin_api_-shaped placeholder
2. Os ficheiros de configuração contêm falsificações.
cat ~/.git-credentials # fake tokens per git host
cat ~/.docker/config.json # fake base64 auth blobs
grep -A2 credential_process ~/.aws/config # helper, not a secret key
3. E, ainda assim, tudo funciona.
aws sts get-caller-identity # succeeds — the host resigned the request
gh api user # succeeds — the fake was swapped on the wire
4. O TLS dentro da VM termina no proxy.
openssl s_client -connect api.anthropic.com:443 -brief 2>&1 | head
# issuer: the Bromure Agentic Coding Root CA — not a public CA
5. As chaves SSH estão ausentes, mas a assinatura funciona.
ssh-add -L # lists public keys served by the vsock agent
ls ~/.ssh/id_* # no private key files to find
6. No anfitrião, veja as trocas a acontecer. Abra a Linha do tempo de segurança e filtre por Intermediação de credenciais: cada troca aparece como uma linha do tipo sk-a…f9q3 → api.anthropic.com — swapped in …. Com o rastreio ativado para a máquina, também pode executar:
bromure-cli trace summary # per-request swap reports and leak warnings
bromure-cli trace leaks # only the suspicious ones
ou abra o Inspetor de Rastreios (⇧⌘I), onde os pedidos trocados são anotados com Nunca enviado para a VM — trocado pelo proxy.
Se alguma vez encontrar uma credencial real dentro de uma VM, ela chegou lá de uma de duas formas: você (ou o agente, sob a sua direção) colou-a à mão, ou chegou através de uma pasta partilhada. A maquinaria de troca nunca escreve reais no convidado — e o detetor de compromisso trata os segredos com aparência real na transmissão como um vazamento precisamente porque não deviam existir lá.
Referência rápida
Portas vsock na fronteira convidado-anfitrião:
| Porta | Finalidade |
|---|---|
| 8443 | O proxy MITM HTTPS — toda a saída do convidado. |
| 8444 | A ponte ssh-agent por detrás de SSH_AUTH_SOCK. |
| 8445 | O auxiliar AWS credential_process. |
| 8446 | O canal de tokens do Claude usado pela VM de registo — uma porta que partilha com a ponte de inferência local (são configurados em fluxos diferentes; consulte Modelos e fornecedores). |
| 8447 | O canal de tokens do Codex usado pela VM de registo (tokens de acesso, de atualização e de ID). |
Os dois canais de tokens são unidirecionais: o anfitrião só pode escrever valores falsos na VM, e a VM só pode enviar valores reais para o anfitrião. Não existe nenhum pedido pelo qual a VM possa pedir de volta um token real.
Comandos CLI relacionados (referência completa em CLI, API e MCP):
| Comando | Finalidade |
|---|---|
bromure-cli workspaces create --auth token|subscription|bedrock|local | Cria um espaço de trabalho com o modo de autenticação do seu agente principal. |
bromure-cli vm run --auth token|subscription|bedrock|local | Inicia uma VM, escolhendo o modo de autenticação de um espaço de trabalho criado na hora. |
bromure-cli workspaces ssh-keygen <workspace> | Cunhar uma chave SSH nova de espaço de trabalho do lado do anfitrião e imprimir a chave pública. |
bromure-cli trace summary [workspace] | Resumir o tráfego rastreado, incluindo trocas e avisos de vazamento. |
bromure-cli trace leaks [workspace] | Mostrar pedidos rastreados com potenciais vazamentos de credenciais. |