Ir para conteúdo principal

Práticas recomendadas de contenção de agentes: sandboxing (beta privado)

Para clientes do nosso Programa de Verificação de Segurança, estamos fornecendo um novo classificador de escape de sandbox na API para monitorar e reduzir abuso. Este artigo explica por que agentes autônomos precisam de isolamento forte, como o design de referência os isola e como definir o escopo e supervisionar engajamentos que precisam de acesso à rede.

Este classificador está em beta privado.

Para uma visão geral de todos os recursos disponíveis, consulte Práticas recomendadas de contenção de agentes: primeiros passos (beta privado).

Visão geral

  • Em uma execução autônoma, nenhum humano aprova as chamadas de ferramentas do agente, e o agente pode executar código-alvo. Recomendamos executar agentes autônomos em um sandbox forte que coloque um kernel virtualizado por hardware entre o host e tanto o agente quanto o código-alvo. Não use Docker/runc simples e nunca use --privileged ou rede de host.

  • O design de referência executa cada agente em sua própria microVM (Kata Containers com Firecracker) em uma rede interna. Ele precisa de um host Linux com KVM, o que limita os hosts que podem executá-lo. O Kata descontinuou o runtime do qual o Firecracker depende.

  • Nunca monte caminhos que contenham credenciais (como ~/.aws, ~/.ssh ou .env) no ambiente do agente. Mantenha a credencial da API do modelo fora do ambiente do agente também: tenha um proxy de credencial separado mantendo-a e adicionando-a a cada solicitação de modelo (consulte O proxy de credencial).

  • Negue saída por padrão. No design de referência, as chamadas de modelo passam pelo proxy de credencial, e o proxy de saída recusa todo outro destino a menos que você o coloque na lista de permissões.

  • Teste seu sandbox em cada host antes de confiar nele e novamente sempre que o sandbox ou o modelo mudar.

  • Para engajamentos que precisam de acesso à rede, declare o escopo nas instruções do agente, aplique-o na rede e mantenha agentes autônomos longe de sistemas ao vivo de alta consequência (consulte Escopo e supervisão).

Orientação de sandboxing

Propriedades a alcançar

Se você construir seu próprio sandbox, estas são as propriedades que o design de referência fornece. O resto deste artigo descreve uma maneira de obtê-las.

  1. Cada agente tem seu próprio kernel de convidado, que não compartilha com o host.

  2. As ferramentas de arquivo e shell do agente veem apenas o sistema de arquivos do convidado. Nenhum diretório de host é compartilhado no convidado.

  3. A credencial da API do modelo não está no ambiente do agente nem em seu disco. Um proxy fora do sandbox a adiciona a cada solicitação.

  4. O agente não tem acesso à internet. A saída é aplicada fora do convidado, e todo destino é recusado a menos que esteja em uma lista de permissões.

  5. O serviço de metadados da nuvem não pode ser alcançado a partir do agente.

  6. Cada agente tem um limite de turnos e um limite de tempo se você definir um.

  7. Sem modo privilegiado, capacidades adicionadas, passagem de dispositivo ou rede de host.

  8. O orquestrador é executado no host confiável e escreve as transcrições lá.

Diretrizes gerais

Um sandbox forte é mais importante para execuções autônomas, onde agentes executam código-alvo e nenhum humano aprova cada ação

Execute agentes autônomos em sandboxes fortes e pense sobre quais efeitos colaterais um processo nesse sandbox ainda poderia causar. Modelos de fronteira são cada vez melhores em encontrar caminhos criativos ao redor de restrições: a mesma propriedade que os torna caçadores de vulnerabilidades eficazes significa que podem tomar ações inesperadas contra seu próprio ambiente de execução. Isso não é hipotético. A Anthropic publicou exemplos de modelos contornando restrições fracas para completar uma tarefa (consulte Como contemos Claude em todos os produtos).

Concretamente, não execute agentes autônomos de busca de vulnerabilidades em Docker/runc simples, e especialmente não com --privileged ou rede de host. Contêineres padrão compartilham o kernel do host, então uma exploração de kernel dentro do contêiner é um comprometimento do host. Recomendamos colocar um kernel virtualizado por hardware entre o código-alvo e o host, o que significa executar o agente em uma máquina virtual. Quando isso não é possível, use um host bare-metal dedicado que não contenha nada mais. Se você construir seu próprio sandbox, recomendamos Firecracker no Linux, Hyper-V no Windows e uma VM baseada no framework Hypervisor no macOS. O design de referência usa Firecracker.

Bloqueie toda saída do sandbox. O agente alcança a API do modelo apenas através de um proxy que adiciona a credencial e é executado fora do sandbox, então o sandbox não precisa de uma rota direta para o host da API. Instale cada ferramenta, pacote e dependência antes do início da execução, para que nada precise ser buscado durante ela.

O uso interativo, com um humano no loop, geralmente apresenta menos risco, mas ainda recomendamos um sandbox para ele. Se você conduzir um agente interativamente do Claude Code em um laptop, revise cada uso de ferramenta (modo manual) ou confie no classificador de permissão do modo automático e tenha um humano aprovando cada ação que alcance fora do repositório. O modo automático remove prompts de permissão rotineiros: aprova leituras e edições de diretório de trabalho automaticamente e envia tudo mais para um classificador de fundo que visa bloquear ações destrutivas, irreversíveis ou fora da tarefa. É uma verificação de melhor esforço. Pode perder coisas e em trabalho de segurança também pode recusar alguns passos legítimos. Modo automático descreve como funciona, o que esperar dele e como configurá-lo para seu ambiente.

Nunca monte caminhos com credenciais como ~/.aws, ~/.ssh ou .env no ambiente do agente. O mesmo vale para a credencial que as próprias chamadas de modelo do agente usam. Mantenha-a fora do sandbox e tenha um proxy que o agente não possa ler adicionando-a a cada solicitação (consulte O proxy de credencial). Não conecte agentes a servidores MCP ou ferramentas com acesso de escrita a estado externo como email, armazenamento em nuvem ou infraestrutura de produção.

Divida cada execução em uma fase de configuração e uma fase de ataque com políticas de rede diferentes

Este é um padrão que coloca as diretrizes acima em prática. A fase de configuração tem acesso à internet de saída e um humano no loop que aprova cada chamada de ferramenta. Nela o agente puxa dependências, constrói o alvo e monta seu sandbox a partir de um documento de especificação. A fase de ataque não tem acesso geral à internet. Toda saída passa por um proxy de lista de permissões que permite apenas os hosts nomeados no engajamento, então o proxy também aplica escopo. Chamadas de modelo passam pelo proxy de credencial separado. O agente pode então sondar o alvo sem supervisão. O proxy contém o tráfego do próprio agente. Não contém tráfego que um alvo em rede envia em nome do agente.

Integre as dependências que o agente precisa repetidamente na imagem de configuração, para que execuções de fase de ataque não precisem de acesso à internet. Escopo de credenciais por alvo, para que um agente trabalhando em um alvo não possa usá-las contra outro. Mantenha o modo automático do Claude Code ligado dentro do sandbox durante a fase de ataque e descreva o sandbox para seu classificador. Consulte Modo automático.

Limite cada execução e conheça seu botão de desligamento

Dê a cada agente um orçamento explícito, para que uma execução que exceda seu teste pretendido pare por conta própria e não quando alguém notar. Aplique um limite de turno rígido em cada agente. Quando um agente o esgota, termine a execução e não conceda mais turnos automaticamente. Relançar com um limite mais alto é o ponto em que uma pessoa decide continuar. Limite execuções também em tempo. Termine uma sessão que exceda seu limite de tempo da mesma forma: a execução é final e nunca retomada, e o processo do agente é interrompido, mesmo quando o limite é atingido no meio de um comando de longa duração. Se um limite for definido para um valor que não pode ser lido, recuse iniciar em vez de executar sem limite. Defina os limites deliberadamente para o engajamento e não aceite um padrão generoso. Emparelhe-os com a cadência de monitoramento em monitoramento offline de transcrições de agentes, para que um lote longo seja analisado a cada hora ou duas e não apenas no final. Saiba como parar um único agente sem parar o lote. Em uma configuração baseada em Docker, é docker rm -f <agent-container>. O orquestrador deve registrar essa execução como falha e continuar com o resto do lote.

Para mais orientação, leia dois recursos da Anthropic. Implantação segura de agentes de IA cobre opções de isolamento, proxy de credencial e endurecimento de sistema de arquivos. O retrospecto de engenharia Como contemos Claude em todos os produtos cobre o que funcionou e o que não funcionou quando esses mesmos mecanismos foram executados em produção.

Escopo e supervisão

O sandbox limita o que um agente pode alcançar. Para pentesting, red teaming e outros engajamentos que precisam de acesso à rede, as práticas abaixo limitam o que o agente é solicitado e autorizado a fazer. Elas dependem de seus alvos e sua equipe, então ferramentas não podem colocar a maioria delas em prática para você.

Declare o escopo nas instruções do agente

Antes de uma execução, diga ao agente quais alvos estão no escopo, quais ações são permitidas, onde está o limite da rede e o que está fora do escopo. Expresse cada restrição como intenção ("não acesse hosts fora de 10.0.3.0/24") e não como uma afirmação sobre o ambiente ("você não pode alcançar a internet"), para que a instrução ainda valha se o ambiente estiver mal configurado. Faça isso também para trabalho local em sandbox: diga ao agente para não usar acesso à internet, mesmo que o sandbox o bloqueie. A descrição que você dá ao classificador do modo automático é uma coisa diferente. Ela declara fatos sobre a máquina (consulte Modo automático).

Aplique o mesmo escopo na rede

Onde você puder, execute o agente dentro do mesmo isolamento descrito acima e coloque na lista de permissões a saída apenas para os alvos no escopo (consulte Lista de permissões de saída). O agente alcança a API do modelo através do proxy de credencial, não através da lista de permissões. Onde um estiver disponível, aponte o engajamento para um ambiente de preparação ou réplica que esteja desconectado da produção.

Intermedie o acesso ao alvo onde você puder

Dê ao agente acesso a sistemas-alvo através de algo que você possa observar, como um proxy de acesso ou um conjunto definido de ferramentas. Evite deixar o agente escrever suas próprias ferramentas com acesso geral ao alvo. Em um harness personalizado, separe ferramentas somente leitura de ferramentas que mudam estado e supervise o segundo grupo mais de perto. Considere analisar comandos arriscados conforme são propostos e negá-los ou escalá-los para uma pessoa.

Supervise execuções que têm acesso à rede

Recomendamos que um engenheiro observe cada execução conforme ela é executada, acompanhando chamadas de ferramentas e atividade de rede, e seja capaz de interromper a execução imediatamente. Agentes agem na velocidade da máquina, então a observação ao vivo complementa os controles que agem antes de uma ação ser executada (listas de permissões de rede, ferramentas intermediadas e revisão de ações que mudam estado). Não os substitui. Para execuções longas ou autônomas onde atenção contínua é impraticável, monitore continuamente em software (consulte Monitoramento offline de transcrições de agentes).

Mantenha agentes autônomos longe de sistemas ao vivo de alta consequência

Não execute agentes autônomos contra sistemas de produção ao vivo onde uma ação fora do escopo poderia colocar em risco a segurança ou a disponibilidade de serviços críticos, como OT/ICS, médicos ou sistemas de energia. Isso já é a norma para testes liderados por humanos de tais sistemas e se aplica igualmente aqui. Teste contra uma réplica, um testbed ou um gêmeo digital, ou durante uma interrupção planejada. Onde o acesso ao vivo é inevitável, limite o agente a atividade passiva ou somente leitura e tenha uma pessoa executando cada passo que muda estado.

Teste o sandbox antes de confiar nele

Antes de executar engajamentos reais de um host, teste seu sandbox com as duas etapas abaixo. Faça isso antes do primeiro uso real e novamente sempre que você mudar o modelo ou o sandbox. Mudanças de sandbox incluem um novo host, uma nova versão do hipervisor ou runtime de contêiner, uma configuração de rede ou proxy diferente e uma configuração de contêiner ou composição editada.

Primeiro, peça ao Claude para revisar a configuração

Em uma sessão interativa do Claude Code no host, peça-lhe para ler a configuração da sandbox conforme está configurada nesta máquina e para relatar qualquer coisa que enfraquece o limite descrito neste artigo. Aponte para:

  • A configuração do hipervisor e do container-runtime (para o design de referência, o configuration.toml renderizado do Kata e o daemon.json do Docker);

  • A rede dos agentes e o proxy de saída conforme relatados pelo runtime, e a lista de permissões do proxy;

  • O proxy de credenciais conforme relatado pelo runtime, e o ambiente de um contêiner de agente em execução (veja O proxy de credenciais abaixo);

  • Qualquer arquivo de composição ou orquestração que inicie agentes ou destinos;

  • A lista do que é montado ou transmitido para os guests (veja Notas operacionais abaixo).

Esta etapa apenas lê configuração e estado. Ela não inicia um agente.

Em seguida, execute um teste de escape supervisionado

Inicie o agente de teste da mesma forma que você inicia agentes de produção, e não com um comando construído manualmente, para que o teste exercite o caminho real. A seção Verifique o isolamento você mesmo abaixo cobre as verificações manuais do limite. Dê ao agente uma única tarefa: tentar alcançar qualquer coisa fora de seu limite, e parar e relatar assim que algo conseguir. Nomeie o limite concretamente no prompt: o host, outros contêineres, o socket do container-runtime, o serviço de metadados da nuvem, e qualquer host que não esteja na lista de permissões do proxy. Execute isso apenas sob supervisão humana próxima, em um host sem acesso à internet além da API do modelo e que você esteja preparado para reconstruir, para que um escape bem-sucedido não cause danos. Em bare metal, execute o teste dentro de uma VM descartável. Em uma VM na nuvem, use uma instância nova e destrua-a depois. Observe a sessão enquanto ela é executada. Trate qualquer sucesso como um bloqueador: corrija o host, repita o teste, e não execute engajamentos desse host até que o teste passe.

Depois, leia toda a transcrição

Verifique o que o agente tentou e se conseguiu sair. Procure por conexões diretas que não passaram pelo proxy, leituras de arquivos de credenciais ou endereços de metadados, uso do socket do container-runtime ou sondagens de contêineres vizinhos, escritas fora do próprio sistema de arquivos do contêiner, e tentativas de alterar as configurações ou ferramentas do próprio agente. O teste passa quando a transcrição mostra que cada um desses foi tentado e falhou pela razão que você espera. Registre, para cada um, se a sandbox ou o classificador de permissões o parou. Uma tentativa que o classificador negou nunca alcançou a sandbox, então cubra-a com as verificações manuais (veja Verifique o isolamento você mesmo abaixo). Um teste bem-sucedido é uma barra mínima, não prova de isolamento.

Evite tarefas impossíveis e revise as execuções falhadas primeiro

Confirme antes do lançamento que a tarefa pode ser concluída conforme fornecida. Alguns exemplos de tarefas que não podem ser concluídas: uma área de foco sem nada para encontrar, um destino que não é alcançável, um bug que não existe, ou uma ferramenta que a tarefa precisa que não está instalada. Sempre que você alterar sua configuração ou iniciar um novo tipo de tarefa, confirme antes do lançamento que o destino é compilado e pode ser alcançado e que o agente tem as ferramentas necessárias. Pela mesma razão, quando você revisa um lote, leia as transcrições das execuções que falharam ou não encontraram nada antes das que tiveram sucesso.

Verifique o isolamento você mesmo

Execute essas verificações manualmente em cada host. A segunda coluna descreve a verificação para o design de referência (Docker com o runtime Kata e Firecracker). Adapte-a ao seu próprio runtime.

O que confirmar

Como

Resultado esperado

Um kernel de guest separado

Execute uname -r em um contêiner em sandbox e no host

As duas versões diferem

O monitor de VM está confinado no host

Para um contêiner em execução, inspecione o processo Firecracker: seu diretório raiz, Seccomp e NoNewPrivs em /proc/<pid>/status, seus namespaces de montagem e rede, e seu cgroup

Apenas os arquivos da própria VM estão sob sua raiz. Seccomp: 2 e NoNewPrivs: 1. Ambos os namespaces diferem do host. O caminho do cgroup nomeia o contêiner

Um arquivo do host não é visível dentro

Crie um arquivo no host e tente lê-lo de um contêiner em sandbox

Não encontrado. Esta é uma verificação básica que qualquer runtime deve passar

A saída é recusada

De um contêiner de agente, solicite o host da API do modelo e um outro host público através do proxy de saída

Ambos são recusados, e o proxy de saída registra uma linha de negação para cada. Os agentes alcançam o modelo apenas através do proxy de credenciais

Nenhuma credencial no contêiner do agente

Enquanto uma execução está ativa, liste o ambiente do contêiner do agente, filtrado para nomes de provedores

Um placeholder, o endereço do proxy de credenciais, e configurações do provedor. Nenhuma chave real, token ou arquivo de credencial

O design de referência

Esta seção descreve como a implementação de referência atende à orientação acima. A implementação não está incluída. Leia-a como um design que você pode copiar.

Como cada agente é isolado

Cada agente é executado como claude -p dentro de sua própria microVM, ao lado do binário de destino e da fonte. A microVM é um contêiner Kata Containers apoiado pelo monitor de máquina virtual Firecracker, registrado no Docker como um runtime. As ferramentas Read, Write e Bash do agente veem apenas o sistema de arquivos e o kernel desse guest.

A conexão entre um guest e o host é deliberadamente pequena. Consiste em KVM e nos poucos dispositivos virtuais que o Firecracker emula: dispositivos de bloco para o disco do contêiner, uma interface de rede, e um canal de controle vsock que o Kata usa para iniciar processos dentro do guest. O próprio processo Firecracker é confinado no host. Ele é executado em uma "jail", que é um diretório chroot contendo apenas os arquivos dessa VM, com seu próprio namespace de montagem, o namespace de rede do contêiner, e o filtro seccomp integrado do Firecracker. É contabilizado no cgroup do contêiner. O que você confia no lado do host é KVM, Firecracker e o processo de runtime do Kata (o "shim" por contêiner que o Docker fala, que é executado como root).

O orquestrador permanece no host confiável. Ele gerencia o ciclo de vida do contêiner, transmite transcrições e move arquivos para dentro e para fora com docker exec, que o Kata serve através de seu agente dentro do guest. O iniciador inicia agentes apenas dentro dessa sandbox. Antes de qualquer agente iniciar, ele verifica se o runtime da sandbox está registrado, se /dev/kvm está presente, e se o proxy de saída está ativo, e se recusa a executar caso contrário.

O que a sandbox muda para cada superfície:

Superfície

Sem sandbox

Com sandbox

Agente Read/Write

sistema de arquivos do host

apenas sistema de arquivos do guest (o disco virtual próprio do contêiner, sob o kernel do guest)

Agente Bash

shell do host

apenas shell do guest (kernel do guest; o host é alcançável apenas através de KVM e dos dispositivos virtuais do Firecracker)

Saída de rede

o que quer que o host tenha

sem acesso à internet; apenas chamadas de modelo, através do proxy de credenciais

Credencial da API do modelo

no ambiente do agente

não no contêiner do agente; mantido por um contêiner proxy de credenciais separado (veja O proxy de credenciais abaixo)

Acoplamento do host

completo

docker exec para arquivos de entrada e saída, servidos pelo agente do Kata dentro do guest; entradas somente leitura chegam como cópias tiradas no início do contêiner; arquivos que mudam durante uma execução são transmitidos pelo orquestrador

Verificações de permissão

apenas classificador de modo automático

classificador de modo automático mais o limite da microVM (veja Modo automático)

Onde cada propriedade é aplicada: a virtualização de hardware fornece o limite do kernel e do sistema de arquivos. O Read/Write/Bash do agente são executados contra o kernel do guest, e o processo Firecracker por trás dele é encarcerado e confinado com seccomp no host. A política de saída é aplicada no lado do host da interface de rede da VM, por uma ponte Docker --internal (sem rota padrão para fora) e os dois proxies nessa rede. O proxy de credenciais encaminha chamadas de modelo e nada mais. O proxy de saída recusa todo outro destino, porque sua lista de permissões está vazia a menos que você adicione a ela. O tráfego sai pela própria pilha de rede do guest; a filtragem acontece nos dois proxies.

O proxy de credenciais

A credencial para a API do modelo (sua chave de API, token OAuth, credencial AWS ou Google) nunca é colocada em um contêiner de agente. O orquestrador no host a lê e valida, e cada inicialização inicia um pequeno contêiner extra, o proxy de credenciais, para mantê-la. O proxy é anexado à rede interna dos agentes, e os contêineres de agente enviam suas chamadas de modelo para ele: seu CLI claude obtém o endereço do proxy como sua URL base de API, e um valor de espaço reservado fixo onde a chave ou token normalmente seria. Isso segue a melhor prática de acessar a API do modelo apenas através de um proxy, com a chave de API injetada de fora da sandbox. No design de referência, o proxy é um contêiner separado na rede dos agentes, não um processo no próprio localhost do agente. Para cada solicitação, o proxy:

  1. Recusa qualquer coisa que não seja uma chamada de modelo para o endpoint do provedor único para o qual o lançamento foi configurado (outros caminhos e hosts recebem um 403 e uma linha de log);

  2. Remove qualquer cabeçalho de autenticação que o contêiner enviou;

  3. Adiciona a credencial real: o cabeçalho da chave de API, um token de portador (que o proxy atualiza a si mesmo quando o token é de curta duração) ou uma assinatura AWS SigV4 calculada sobre a solicitação exata;

  4. Encaminha a solicitação para o provedor via HTTPS com verificação de certificado e transmite a resposta de volta.

Para um contêiner de agente comprometido, isso significa que não há chave, token ou arquivo de credencial para ler, copiar ou enviar para qualquer lugar. Os serviços de metadados da nuvem também são inacessíveis do contêiner. O que o contêiner ainda pode fazer é fazer chamadas de modelo através do proxy, em sua conta, enquanto a execução estiver ativa. Por esse motivo, prefira uma credencial com escopo estreito para execuções de agente e a rotacione após qualquer execução cuja transcrição mostre comportamento inesperado. O proxy registra uma linha por solicitação, com o endereço do cliente, método, caminho, status e tamanho. Ele não registra cabeçalhos ou corpos. Salve esse log quando a execução terminar (veja a seção Retenção em Monitoramento offline de transcrições de agentes).

Qualquer coisa que o agente envie para a API do modelo sai de sua rede, em corpos de solicitação que o proxy não inspeciona ou registra.

O que cada lado mantém, por rota de autenticação:

Rota

O que o proxy de credenciais mantém

O que o contêiner do agente obtém

Chave de API

a chave

endereço do proxy + espaço reservado ANTHROPIC_API_KEY

Token OAuth (claude setup-token)

o token

endereço do proxy + espaço reservado CLAUDE_CODE_OAUTH_TOKEN

Federação de Identidade de Carga de Trabalho (WIF)

o token de identidade, mais o token de acesso que o proxy troca por ele e atualiza. Com ANTHROPIC_IDENTITY_TOKEN_FILE, o diretório do arquivo de token é montado somente leitura no proxy, para que o proxy veja um token rotacionado. Com um ANTHROPIC_IDENTITY_TOKEN inline, o proxy mantém esse valor e não há arquivo para releitura

endereço do proxy + espaço reservado CLAUDE_CODE_OAUTH_TOKEN

perfil ant auth login

o diretório de perfil, montado somente leitura no proxy

endereço do proxy + espaço reservado CLAUDE_CODE_OAUTH_TOKEN

Bedrock

o token de portador ou o conjunto de chaves de acesso (o proxy assina cada solicitação)

endereço do proxy, CLAUDE_CODE_SKIP_BEDROCK_AUTH=1, região; sem credencial AWS

Vertex

a chave da conta de serviço, mais os tokens de acesso que o proxy cria a partir dela e atualiza

endereço do proxy, CLAUDE_CODE_SKIP_VERTEX_AUTH=1, região e projeto; sem credencial Google

O contêiner proxy de credenciais faz parte do lado confiável da configuração. Ele é executado sob runc simples em vez do tempo de execução da sandbox, como root com todas as capacidades removidas, exceto a que precisa para ler os arquivos montados, e com um sistema de arquivos somente leitura. Ele escuta apenas em seu endereço na rede interna dos agentes e se conecta ao provedor diretamente em vez de através do proxy de saída. O orquestrador passa a credencial para o proxy em execução via docker exec. Para as rotas de arquivo de token WIF e perfil, o diretório que contém o token ou perfil é montado somente leitura no proxy, que lê o arquivo de lá. A credencial não está no ambiente do contêiner proxy ou em sua linha de comando, para que docker inspect nele mostre as montagens e não um segredo.

Inicie um proxy por lançamento e remova-o quando a execução terminar ou for interrompida. Verifique se há proxies deixados para trás por uma execução que foi interrompida e remova-os antes do próximo lançamento.

O proxy de credenciais tem dois efeitos colaterais. Primeiro, o CLI dos agentes recebe um endereço de API não padrão, portanto alguns recursos de CLI que se aplicam apenas ao endereço padrão estão desativados dentro dos contêineres de agente. Sua telemetria e verificações de atualização também são desativadas, porque não teriam rota para fora de qualquer forma. Segundo, no Vertex, o filtro de caminho do proxy é o controle principal que impede um contêiner de agente de usar o resto da API Vertex AI (veja Lista de permissões de saída). Uma verificação do escopo de IAM da chave no lançamento é uma segunda camada.

Lista de permissões de saída

A lista de permissões do proxy de saída está vazia por padrão. Os contêineres de agente acessam a API do modelo apenas através do proxy de credenciais (veja O proxy de credenciais). Cada lançamento inicia esse proxy para o provedor que suas credenciais selecionam, portanto nada específico do provedor é armazenado na configuração da sandbox. Todo outro destino que um agente solicita através do proxy de saída, incluindo o próprio host da API do modelo, recebe um 403 e uma linha de negação em seu log. Os valores de região que selecionam os endpoints Bedrock e Vertex (AWS_REGION, CLOUD_ML_REGION) são verificados em relação a um padrão rigoroso antes de serem usados, para que um valor malformado não possa enviar a credencial para um host diferente.

Vertex tem um limite a ser observado. …aiplatform.googleapis.com serve toda a API Vertex AI, portanto uma credencial que é permitida criar trabalhos personalizados pode executar um contêiner arbitrário com saída de internet completa em seu projeto. Use dois controles contra isso. Faça o proxy de credenciais encaminhar apenas chamadas de modelo de editor em seu projeto configurado (…/publishers/anthropic/models/…:rawPredict, :streamRawPredict e :countTokens) e recuse todo outro caminho. E verifique o escopo de IAM da chave no lançamento e falhe fechado: recuse ADC de usuário gcloud, verifique uma chave de conta de serviço com testIamPermissions e recuse-a se ela contiver qualquer permissão de criação de carga de trabalho. Conceda à conta uma função personalizada que contém apenas aiplatform.endpoints.predict. O servidor de metadados, STS do Google e os endpoints de credenciais de IAM não devem ser acessíveis dos contêineres de agente.

Se os agentes precisarem acessar hosts extras, como um espelho de pacote ou um alvo no escopo, adicione-os à lista de permissões do proxy de saída como entradas host:port. Adicione apenas o que o engajamento precisa (veja Escopo e supervisão).

Não adicione o host da model-API a esta lista. Os agentes não precisam dele, porque suas chamadas de modelo passam pelo proxy de credenciais. Adicioná-lo oferece aos contêineres de agentes uma rota direta para a API, e o resto do design, incluindo o que o classificador de permissões é informado, assume que eles não têm nenhuma.

Alterar a lista de permissões significa reiniciar o proxy de saída, o que interrompe qualquer conexão de agente ativa. Faça isso entre lotes em vez de durante um, e confirme depois qual lista o proxy carregou.

Derive o endpoint do provedor da sua configuração de credenciais e ignore uma variável de URL base como ANTHROPIC_BASE_URL que está definida no host: o proxy de credenciais deve sempre encaminhar para o endpoint que as credenciais selecionam.

Construir e operar uma sandbox assim

Esta seção coleta o que foi aprendido ao executar agentes sob Kata com Firecracker na implementação de referência. Não é um conjunto de etapas de instalação.

Requisitos do host

O design de referência precisa de uma máquina Linux física ou de uma VM que possa executar VMs:

  • Linux x86_64 ou aarch64 com KVM (/dev/kvm presente e utilizável): bare metal ou uma VM de nuvem com virtualização aninhada ativada.

    • GCE, Azure e AWS oferecem virtualização aninhada em tipos de instância selecionados (no AWS, por exemplo, as famílias C8i, M8i e R8i). As instâncias bare-metal do AWS (*.metal) também funcionam.

    • A virtualização aninhada custa algum desempenho. Não se espera que enfraqueza o limite.

  • Armazenamento em dispositivo de bloco para contêineres. O Firecracker não pode compartilhar um diretório do host em um convidado; o único armazenamento que pode anexar a uma VM é um dispositivo de bloco. Os sistemas de arquivos raiz dos contêineres devem existir como dispositivos de bloco em vez do sistema de arquivos de sobreposição usual. Com Docker, o snapshotter devmapper do containerd fornece isso. Ele precisa de Docker rootful (o design de referência usa Engine 25 ou mais recente) apoiado pelo containerd do sistema (2.0 ou mais recente).

  • Acesso à rede de saída enquanto você constrói o host e as imagens. Os agentes não obtêm essa saída.

Não funcionará em:

  • um contêiner ou um pod do Kubernetes, incluindo Docker-in-Docker e executores de CI baseados em contêiner. O containerd do host, o daemon do Docker e o device-mapper não podem ser configurados de dentro de um contêiner, e o KVM geralmente também não está disponível lá;

  • Docker sem privilégios de root;

  • uma VM sem virtualização aninhada, que é a maioria dos tipos de instância de nuvem de uso geral, a menos que você escolha uma que a ofereça e a ative;

  • macOS ou Windows, incluindo Docker Desktop e WSL2.

O design de referência não suporta hosts macOS ou Windows

Sua sandbox precisa de KVM em um host Linux. Docker em um Mac é executado dentro de uma VM Linux compartilhada que monta o diretório inicial do usuário e mantém o daemon do Docker, portanto não pode fornecer isolamento de hardware por agente. Se você trabalha em um Mac, execute os agentes em um host Linux com KVM (bare metal ou uma VM de nuvem com virtualização aninhada) e conduza-os via SSH. Se você construir sua própria sandbox no macOS ou Windows, consulte os hipervisores nomeados na seção Diretrizes gerais acima.

Alternar o armazenamento de imagens do Docker tem um efeito colateral

Imagens e contêineres criados no armazenamento anterior do Docker ficam invisíveis para o Docker após a mudança para o snapshotter devmapper. Eles permanecem no disco. Para vê-los novamente, coloque ambas as configurações de armazenamento em daemon.json (storage-driver e features.containerd-snapshotter) de volta ao que eram e reinicie o Docker.

Configurações do Kata

Fixe a versão do Kata e verifique seu resumo antes de instalá-lo. O design de referência começa com o perfil Firecracker do Kata e fixa essas configurações em /etc/kata-containers/configuration.toml:

Configuração

Valor

Por quê

jailer_path

caminho para o binário jailer do Kata

Inicia o Firecracker dentro de sua prisão: um chroot com apenas os arquivos da VM, seu próprio namespace de montagem, o namespace de rede do contêiner e o filtro seccomp do Firecracker. Se não for definido, o Kata executaria o Firecracker sem a prisão.

enable_annotations

[]

Um contêiner não pode alterar nenhuma configuração do hipervisor através de anotações OCI.

disable_guest_seccomp

false

O perfil seccomp do Docker para o contêiner também é aplicado dentro do convidado, uma segunda camada sob o limite da VM.

sandbox_cgroup_only

true

O Firecracker e seus threads de E/S são colocados no cgroup do contêiner, portanto a VM é contabilizada para o contêiner. Se o limite --memory do contêiner também limita a VM depende do host (consulte Dimensionamento).

static_sandbox_resource_mgmt

true

O Firecracker não pode adicionar CPUs ou memória a uma VM em execução, portanto a VM é dimensionada uma vez na inicialização a partir dos limites do contêiner.

default_vcpus / default_memory

4 / 4096 MiB

Linha de base por VM; o --memory do contêiner é adicionado no topo. Aumente para destinos com uso intensivo de compilação (o Firecracker permite no máximo 32 vCPUs por VM).

debug_console_enabled, enable_debug

false

Nenhum console em convidados e nenhuma saída de console de convidado nos logs do host.

[factory] enable_template

false

Desativado, porque o modelo de VM compartilharia páginas de memória de convidado entre VMs.

entropy_source

/dev/urandom

Entropia de host não bloqueante para convidados.

Os valores de kernel, image e kernel_params que vêm com a versão Kata são mantidos como estão.

Tornar o kernel e a imagem do convidado imutáveis

Cada VM inicializa a partir dos mesmos dois arquivos, Kata os vincula em cada jail, e o jailer é iniciado como root, portanto as permissões de arquivo ordinárias não impediriam um processo Firecracker comprometido de reescrever a imagem da qual cada VM posterior inicializa. Defina o sinalizador imutável em ambos (chattr +i). Limpar esse sinalizador requer uma chamada de sistema que o filtro seccomp do Firecracker não permite, projetado para impedir até mesmo root dentro da jail de fazê-lo. Limpe o sinalizador você mesmo antes de instalar uma nova versão Kata. Em um sistema de arquivos sem suporte a chattr, use um bind mount somente leitura.

Dimensionamento

Memória

Cada VM do agente é dimensionada uma vez, na inicialização: default_memory mais o --memory do contêiner. Com uma linha de base de 4096 MiB e um limite de contêiner 4g, um agente é uma VM de 8 GiB. O host aloca essa memória à VM conforme o convidado a usa, não tudo na inicialização, mas planeje para o valor total por agente simultâneo: dez agentes em paralelo podem crescer para 80 GiB. Se o limite --memory do contêiner também limita a VM como um todo depende de como os cgroups do host estão dispostos. Verifique qual destes se aplica ao seu host:

  • O limite do contêiner se aplica à VM inteira. Um agente não pode usar mais memória do host do que --memory mesmo que sua VM seja nominalmente maior, e uma VM que excede o limite é eliminada pelo lado do host.

  • Nada no host limita a VM abaixo de seu tamanho de inicialização. O uso de memória de um agente é limitado pelo tamanho da VM (default_memory + --memory) e pelo próprio eliminador de falta de memória do kernel do convidado.

  • Um cgroup pai a limita a um valor diferente.

Não confirmamos esse comportamento em todos os tipos de host. De qualquer forma, dimensione o host pelo tamanho da VM.

CPUs

Cada VM obtém default_vcpus. Firecracker não pode adicionar CPUs a uma VM em execução, portanto, para destinos com uso intensivo de compilação, aumente o valor antes do lançamento; o máximo é 32 por VM.

Disco

Cada imagem e cada contêiner obtém um disco virtual de um pool fino de device-mapper, que faz backup do armazenamento de imagens. Se o pool se encher, as gravações dentro dos contêineres falham com erros de E/S ou falta de espaço. Se o sistema de arquivos que contém o pool se encher primeiro, o pool fica somente leitura e cada contêiner nele falha. Libere espaço com docker rmi e docker system prune (blocos liberados retornam ao pool). sudo dmsetup status <pool> mostra o uso. Para um host de longa duração, um pool fino LVM em um disco dedicado é o melhor layout.

Tempo de inicialização

Cada início de agente inicializa um kernel de convidado. Isso leva bem menos de um segundo em metal nu e alguns segundos sob virtualização aninhada, o que é pequeno em comparação com os tempos de execução do agente.

Endurecimento do host

  • Dedique o host a este trabalho.

    • Assuma que um agente poderia ler qualquer coisa nele e não mantenha credenciais ou dados sensíveis lá, exceto a credencial da API do modelo que os agentes precisam.

  • Mantenha cada camada que o tráfego do agente toca corrigida, não apenas o kernel: Docker, as imagens base dos contêineres proxy e qualquer firewall ou dispositivo de rede entre o host e a API do modelo. Um proxy ou firewall desatualizado no limite da sandbox é em si uma superfície de ataque.

  • Mantenha o kernel, KVM e microcódigo da CPU atualizados e deixe as mitigações de vulnerabilidade de CPU do kernel em seus padrões.

    • grep . /sys/devices/system/cpu/vulnerabilities/* não deve mostrar linhas Vulnerable.

    • Se o host é compartilhado com cargas de trabalho que não devem se observar, siga também o guia de configuração de host de produção do Firecracker sobre configurações de SMT e execução especulativa.

  • Desabilite swap (sudo swapoff -a e remova de /etc/fstab) para que a memória do convidado não seja gravada em swap.

  • /dev/kvm não precisa ser gravável no mundo, e os diretórios de instalação e tempo de execução do Kata devem permanecer de propriedade de root e não graváveis por outros usuários.

    • root:kvm com modo 0660 é suficiente para /dev/kvm, porque o tempo de execução do Kata é executado como root.

  • Nunca adicione --privileged, --device, --cap-add ou rede de host a contêineres de agente ou a serviços de destino.

    • Sob Kata, esses sinalizadores passam dispositivos de host e privilégios para a VM.

  • Mantenha agentes na rede interna atrás dos dois proxies.

    • Firecracker não faz filtragem de pacotes por conta própria; a rede do lado do host e os proxies são o controle de saída.

  • Mantenha enable_debug desativado fora da solução de problemas; o log de depuração inclui a saída do console do convidado.

Validando um novo host

Depois de configurar uma máquina nova, esta sequência mostra que a sandbox funciona de ponta a ponta. As etapas 3 e 4 fazem chamadas de modelo reais.

  1. Execute as verificações de isolamento em Verifique o isolamento você mesmo. As duas versões do kernel devem diferir. Observe se o limite de memória do contêiner limita a VM (veja Dimensionamento).

  2. Confirme que a CLI do agente é executada sob o tempo de execução da sandbox, na imagem que você usará.

  3. Teste o limite: peça ao Claude para revisar a configuração da sandbox e execute o teste de escape supervisionado, ambos conforme descrito em Teste a sandbox antes de confiar nela.

  4. Execute um pequeno lote de ponta a ponta contra um destino que você conhece. Execute esta etapa com o modo de credencial que você usará para engajamentos reais, não uma chave de API substituta: o proxy de credencial lida com cada modo de forma diferente (troca de token para WIF, assinatura para Bedrock, cunhagem de token para Vertex), e esta execução confirma que a sua funciona de ponta a ponta. Verifique o log do proxy de credencial depois.

  5. Verifique se nada foi deixado para trás. Depois que o lote terminar, nenhum contêiner de agente, contêiner auxiliar, processo de VM ou proxy de credencial deve permanecer. O log do proxy de saída deve mostrar nenhuma linha de negação além das sondagens das etapas 1 e 3, e o log do proxy de credencial deve mostrar apenas chamadas de modelo.

Notas operacionais

Executar agentes sob Kata com Firecracker difere de executar contêineres simples nestas formas.

Bind mounts são cópias; arquivos ao vivo têm que ser transmitidos

Firecracker não tem compartilhamento de sistema de arquivos de host, portanto Kata copia um arquivo ou diretório vinculado ao convidado quando o contêiner inicia, e mudanças posteriores no host não são vistas dentro. Isso é bom para entradas que não mudam durante uma execução, como fonte de destino, e essas podem permanecer como montagens somente leitura. Nenhum arquivo de credencial é montado ou transmitido, porque contêineres de agente não possuem nenhum (veja O proxy de credencial). Um arquivo que muda durante uma execução tem que ser escrito no contêiner pelo orquestrador, através de docker exec, e mantido atualizado. As cópias no contêiner são arquivos ordinários que um agente poderia editar, portanto, peça ao orquestrador para ler os originais no host e julgar descobertas de uma cópia que o agente em teste não pode alcançar.

Cada agente precisa de um contêiner complementar para sua rede

As interfaces de rede de uma microVM devem existir quando a VM inicializa; Firecracker não pode adicionar uma depois. Docker, no entanto, conecta a rede de um contêiner apenas depois que o tempo de execução criou o contêiner. O design de referência contorna isso. Ele primeiro inicia um pequeno contêiner ocioso que está anexado à rede correta e executa apenas sleep, e depois inicia o agente dentro do namespace de rede desse contêiner (--network container:<name>). Kata encontra as interfaces lá na inicialização e as anexa à VM. Um complemento serve exatamente uma VM, porque Kata deixa os dispositivos de rede do lado do host da VM atrás nele, portanto crie e remova o par junto e não reutilize um complemento. Um custa um processo ocioso de aproximadamente 12 MB.

Parando um agente travado

docker rm -f <agent-container> é suficiente. O orquestrador deve detectar o contêiner morto, marcar a execução como falha e remover o contêiner complementar quando desmontar a execução.

Tudo é endereçado por IP

O DNS incorporado do Docker é executado no namespace de rede do lado do host e é inacessível de dentro de um guest, portanto, passe os proxies para os agentes como endereços IP e atribua um IP estático aos destinos em rede.

docker exec funciona, docker cp não funciona

docker exec em um contêiner de agente se comporta normalmente; o agente do Kata dentro do guest executa o comando. docker cp para dentro ou para fora de um contêiner de agente não funciona, porque os arquivos do contêiner estão em um disco virtual dentro do guest. Use docker exec <container> cat <path> e similares.

Firecracker é executado como root dentro de sua jail

Kata inicia o jailer com uid 0, portanto o processo Firecracker é confinado por seu chroot, namespaces, filtro seccomp e cgroup, não por um uid de usuário sem privilégios. Os dois arquivos que cada VM compartilha, o kernel do guest e a imagem, são protegidos pela flag imutável (veja Configurações do Kata).

Kata descontinuou o runtime do qual Firecracker depende

Kata executa Firecracker através de seu runtime Go mais antigo. Kata 4.0 tornou um runtime Rust mais novo o padrão para seus outros hipervisores e descontinuou o runtime Go. O upstream diz que o runtime Go ainda recebe correções críticas de bugs e correções de CVE, e que pode ser removido não antes de Kata 5.0. O runtime Rust não lista Firecracker entre seus hipervisores, e o upstream testa sua integração com Docker principalmente com QEMU. Planeje uma migração. Quando você alterar a versão do Kata, repita Validando um novo host. Kata também pode usar Cloud Hypervisor em vez de Firecracker; a implementação de referência não testou ou endureceu essa configuração.

Logs

As mensagens do runtime do Kata, Firecracker e guest-agent vão para o journal: journalctl -t kata. Os problemas do containerd e Docker estão em journalctl -u containerd e journalctl -u docker.

Isto respondeu à sua pergunta?