Pular para o conteúdo
Menu
Preciso disso?O que um agente alcança na sua máquinaComo funcionaAs camadas entre o agente e o seu sistemaCompararSandboxes embutidos, Docker e VMsConfigurarAbra só o que a tarefa precisaSegurançaO modelo de ameaças e seus limitesDownloadBinários, checksums e notas da releaseInstalar
Segurança

Uma camada útil, com limites conhecidos

O ai-jail é feito para conter os erros de um agente confiável e manter o estrago dentro do projeto: o diretório do projeto é o raio de impacto, e o seu home, as suas chaves e a rede ficam fora dele. É um sandbox de processo que compartilha o seu kernel, então não é uma fronteira contra código hostil nem contra um atacante motivado, e não substitui uma máquina virtual descartável.

Para quem assina embaixo, e depois para o engenheiro de segurança.

O que ele foi feito para barrar

Um agente confiável ainda erra um comando, roda um script que sobe acima da raiz do projeto, ou é enganado por uma página web ou um pacote. É isto que ele vai procurar em seguida, e não vai encontrar.

↔ Deslize para o lado para ver o diagrama inteiro

Os padrões. Cada item do lado de fora continua lá até você mesmo abrir.

Fora de alcance

  • Seu diretório home e as credenciais que estão nele. O agente recebe um home novo e vazio, então ~/.ssh e ~/.aws não existem lá dentro.
  • Segredos no seu shell. O ai-jail reduz as variáveis de ambiente a uma allowlist pequena, então os tokens exportados ficam de fora. A única exceção é a chave de API do próprio harness iniciado, por exemplo ANTHROPIC_API_KEY para o Claude, copiada por padrão junto com o login dele; --no-agent-state impede isso.
  • A rede. Ela fica fechada, com duas exceções que passam pelo proxy filtrado: uma lista curta de registries de pacotes quando as toolchains estão ligadas, o padrão no Linux, e, para um agente conhecido, o host da API dele, nas duas plataformas. Os hosts de telemetria continuam fechados. --no-network fecha as duas.
  • A memória compartilhada do host, o seu servidor gráfico e o seu clipboard. A saída do agente passa por um filtro que descarta sequências de terminal de clipboard e de consulta.
  • Digitar no seu terminal. O Linux bloqueia a chamada TIOCSTI, que simula teclas, e o macOS restringe o controle de terminal ao único terminal que o ai-jail criou para aquela execução.
  • As próprias regras. Um arquivo .ai-jail dentro de um repositório não é confiável: ele pode apertar o sandbox, nunca abrir.
Como cada camada faz isso

Onde o muro acaba

A jaula e o seu sistema se apoiam no mesmo kernel. Um bug nesse kernel, num driver ou no backend do sandbox é um caminho por fora do muro, e o ai-jail não tem o que fazer a respeito. Uma máquina virtual traz o próprio kernel, e por isso é a fronteira mais forte.

↔ Deslize para o lado para ver o diagrama inteiro

Um sandbox divide o chão com aquilo que protege, e uma VM traz o próprio chão.

O que isso significa para os seus dados

  • Segredos dentro do projeto. Um arquivo .env no repositório pode ser lido, a menos que você o mascare. Veja como mascarar arquivos.
  • As máscaras cobrem só os caminhos que existem quando o sandbox inicia. Um arquivo de segredos criado depois, durante a sessão, não fica escondido.
  • Um host permitido é confiável por inteiro. Liberar github.com com --allow-host deixa o agente fazer push em qualquer repositório de lá, não só nos seus.
  • --network abre a rede inteira, então tudo o que o agente consegue ler, o seu projeto incluído, ele consegue enviar para fora.
  • O ai-jail monta o login do próprio agente por padrão, com leitura e escrita, então um agente enganado pode usá-lo enquanto a execução durar. O projeto documenta isso como uma troca por conveniência; --no-agent-state dá uma execução sem login.
  • O git do lado do host confia no .git/ do projeto, que é gravável. Um programa nomeado em .git/config, como core.fsmonitor ou core.pager, ou colocado em .git/hooks/ roda como você, fora do sandbox, na próxima vez que um comando git correspondente rodar no host; para core.fsmonitor basta um git status, mesmo um que o seu editor roda em segundo plano, e nada aparece no git diff. --lockdown fecha isso deixando o projeto somente leitura, e --map .git mantém o repositório somente leitura numa execução normal, ao custo de não poder commitar de dentro. Depois de uma sessão que te surpreendeu, leia o .git/config e liste o .git/hooks com ferramentas de arquivo comuns antes de rodar git no host, porque o próprio git config --list abre o pager configurado.
  • --mask e --deny-path mudam só o que o sandbox vê. Qualquer coisa fora do sandbox que age em nome do agente continua lendo os arquivos reais: o daemon do Docker com --docker, um servidor MCP alcançado por um socket mapeado ou um serviço atrás de --forward-port.
Para o engenheiro de segurança
  • Vulnerabilidades de kernel e de drivers. Todo processo em sandbox fala com o mesmo kernel que o resto da sua máquina.
  • Bugs no seu emulador de terminal, principalmente com --terminal-passthrough, que desliga o filtro de saída.
  • Defeitos no próprio backend do sandbox: bubblewrap, Landlock e seccomp no Linux, sandbox-exec no macOS.
  • O Landlock, as regras do próprio kernel, só cerca sockets Unix abstratos e sinais em kernels 6.12 ou mais novos, em modo best-effort. Kernels mais antigos ficam só com as regras de sistema de arquivos e de rede, então com --x11, --network ou --systemd-user os sockets abstratos e os sinais do host não ficam cercados.
  • Side channels e algumas classes de comunicação entre processos.
  • A saída filtrada é só TCP. Não há UDP, então um programa que precisa dele não funciona; por outro lado, também não vaza por ali.
  • DNS com --allow-host. No Linux, as consultas de nome dentro do sandbox falham, então não existe canal de DNS para fora. No macOS o resolver do sistema não fica cercado, então sobra um canal de DNS de baixa largura de banda, a mesma brecha que a Anthropic documenta para o sandbox-runtime dela.
  • O proxy vê o host, a porta e o horário de cada conexão. O que passa lá dentro fica entre as duas pontas. Como a saída filtrada é construída.
  • As credenciais fantasma transferem a confiança para o próprio ai-jail. Com --secret, as requisições para o host vinculado passam pelo ai-jail em claro, para que ele insira a chave real, e ele as criptografa de novo na saída. Os túneis para todos os outros hosts continuam opacos. Só cobre clientes que conseguem falar HTTP puro com o proxy para esse host.
  • Credenciais que você passa com --github, --aws, --kube, --gcloud ou --docker-config. Somente leitura protege o arquivo contra alterações, não a credencial contra o uso: qualquer coisa dentro do sandbox pode agir como você naquele serviço enquanto ela for válida.
  • No macOS, o sandbox-exec foi marcado como obsoleto pela Apple e não equivale ao isolamento do Linux. Veja as diferenças no macOS.

Opções que abrem o muro

Tudo o que está abaixo fica desligado até você ligar, exceto duas opções que vêm ligadas por padrão: --toolchains no Linux e --agent-state em todo lugar. A maioria dá acesso real ao agente. Como definir cada um está na página Configurar.

Mostrar todas as opções e consequências
OpçãoO que qualquer coisa no sandbox passa a poder fazer
--networkEnviar para qualquer lugar tudo o que consegue ler, sem nenhuma restrição de tráfego. O padrão libera só o host da API de um agente conhecido e, no Linux, os registries de pacotes; --allow-host é a alternativa mais apertada.
--allow-hostAlcançar exatamente os hosts que você lista, e seus subdomínios, por TCP, através de um proxy embutido. Cada host listado é confiável por inteiro. Sua lista soma ao host da API do próprio agente; --no-network com uma lista deixa só essa lista.
--forward-portUsar por inteiro um serviço no loopback do seu host. O que o servidor MCP, o socket do editor ou o banco de dados nessa porta aceitar, o agente pode pedir, sem allowlist, sem inspeção e sem registro no log de auditoria. Todas as outras portas do host continuam fechadas. Só no Linux, e recusado com --network.
--toolchainsLigado por padrão no Linux. Rodar as suas toolchains: ~/.cargo/bin e ~/.rustup somente leitura, um cache de dependências próprio da jaula em ~/.local/share/ai-jail/cache/ que sobrevive entre execuções, e saída filtrada para os registries de pacotes. Os caches reais do host nunca são montados. Desligado sob --lockdown e com --no-toolchains.
--secretNada de novo. O valor real dessa chave nunca entra no sandbox: o agente vê um placeholder, e o proxy troca pelo valor real só nas requisições em HTTP puro para o único host ao qual você a vinculou. O próprio processo do ai-jail vê essa requisição em claro.
--audit-logNada de novo. Esta opção não enfraquece nada: ela grava uma linha por inicialização num arquivo com modo 0600 fora do sandbox, então o agente nunca o vê.
--dockerAgir como root na sua máquina por meio do daemon do Docker.
--kvmAbrir /dev/kvm, a interface de virtualização do kernel, para que QEMU, Firecracker ou o emulador do Android rodem na velocidade do hardware. Só no Linux. Os guests só têm a rede do sandbox, e nenhum /dev/net/tun é passado.
--x11Capturar teclas e tirar screenshots de outras janelas X11.
--systemd-userPedir ao seu gerenciador de usuário do systemd para rodar serviços no host.
--inherit-envLer o ambiente inteiro do seu shell, com os segredos. Para chaves de API, --env-from-file passa um arquivo no lugar.
--agent-stateLigado por padrão. Usa o login salvo do próprio agente, por exemplo o ~/.claude do Claude ou o ~/.local/share/devin e o ~/.config/devin do Devin, montado com leitura e escrita, mais a chave de API dele copiada do seu shell quando estiver definida, então ele começa logado. Tudo o que está no sandbox pode usar essas credenciais enquanto a execução durar. --no-agent-state dá uma execução isolada, sem login; desligado no --lockdown.
--githubAgir como você no GitHub. O diretório de configuração do gh é montado somente leitura, e o token ativo do github.com é lido do keyring do sistema no host e repassado como GH_TOKEN para essa execução, nunca na linha de comando nem em disco. Somente leitura protege o arquivo; o token continua funcionando enquanto for válido.
--awsAgir como você na AWS com ~/.aws, montado somente leitura.
--kubeAgir como você em todos os clusters de ~/.kube, montado somente leitura.
--gcloudAgir como você no Google Cloud com ~/.config/gcloud, montado somente leitura.
--docker-configUsar seus logins de registries de containers em ~/.docker/config.json, montado somente leitura.
--audioGravar e reproduzir áudio enquanto estiver ligada.
--no-private-homeVer o seu diretório home real. É uma exceção ampla; prefira mapear só o caminho de que você precisa.

Na dúvida, ele se recusa a iniciar

Um sandbox que inicia, sem avisar, mais fraco do que você pediu é pior do que um que para com um erro. Nestes casos o ai-jail para.

  • Um arquivo de configuração que existe e está inválido ou ilegível.
  • Um .ai-jail de projeto que é um symlink. Um ~/.ai-jail global que é symlink só é seguido até um arquivo regular que pertence a você, em que ninguém mais pode escrever, fora do projeto.
  • --lockdown quando o Landlock, as regras de sistema de arquivos do próprio kernel, está ausente, parcial ou falha ao ser aplicado. --lockdown --no-landlock também é rejeitado.
  • --allow-tcp-port. Essa interface não consegue restringir UDP, então a flag é aceita por compatibilidade, a inicialização falha e o erro aponta para --allow-host.
  • --network junto com --allow-host, ou --browser com --allow-host. As duas se contradizem, então o ai-jail se recusa a iniciar.
  • --forward-port junto com --network, quando o loopback do host já está alcançável; fora do Linux; e para a porta 0 ou uma porta abaixo de 1024, que o sandbox não consegue abrir. Uma entrada forward_ports na tabela base do arquivo global esbarra nos dois primeiros casos em toda inicialização com navegador e toda inicialização no macOS.
  • Um arquivo de --env-from-file que é um symlink, que o grupo ou todo mundo consegue ler, que pertence a outra pessoa ou que está dentro do projeto.
  • Um BWRAP_BIN que aponta para um binário do bubblewrap que alguém além do root poderia ter trocado. Ele é ignorado com um aviso, e sem um bubblewrap confiável a inicialização falha.
  • Um overlay que não consegue ser montado: origem ausente, destino que se sobrepõe a outro mapeamento ou falha no armazenamento. Desde a 2.4 a inicialização aborta em vez de cair para um bind simples de leitura e escrita dos arquivos reais.

Como o projeto é verificado

Um único mantenedor toca o projeto, tudo em aberto. Abaixo está o que é verificado e o que não é.

23
testes de integração de fuga do sandbox, que tentam escrever em /usr, ler ~/.ssh, chamar ptrace e bpf, e esperam falhar
959
testes unitários na árvore de código-fonte na versão 2.9.0
0
requisições de rede na inicialização. A checagem de atualização é opt-in, com --update-check

Correções de segurança recentes

  • 2.9.0: --x11 sozinho passa o X11 para dentro. Antes, ele não fazia nada sem --display, em silêncio.
  • 2.9.0: O auto-save não grava mais no arquivo de projeto opt-ins que a carga não confiável depois recusa, então um arquivo salvo nunca avisa na execução seguinte.
  • 2.9.0: macOS: o Codex inicia de novo sob o Seatbelt com um ps shim privado no lugar do ps setuid do host.
  • 2.8.0: macOS: o perfil do seatbelt mantém o login do Claude Code no Keychain e libera o socket de controle do Codex, então os dois iniciam logados.
  • 2.8.0: Pedidos de posição do cursor vindos de um launcher são respondidos pelo terminal virtual, então os launchers não travam mais.
  • 2.6.2: --lockdown sempre isola o network namespace, mesmo com --network. Antes, esse par contraditório deixava o namespace compartilhado.
  • 2.6.2: Os valores de --env e --env-from-file não ficam mais na linha de comando do launcher, onde qualquer processo rodando como você podia lê-los. Eles passam por um arquivo em memória.
  • 2.4.0: Os metadados de worktree de um repositório não conseguem mais montar um diretório qualquer do host em leitura e escrita.
  • 2.4.0: Uma entrada duplicada no ambiente não deixa mais o valor real de uma chave --secret escapar para dentro do sandbox.
  • 2.4.0: Um comando de navegador num .ai-jail de projeto não confiável não desliga mais o lockdown.
  • 2.4.0: TIOCSTI é comparado como o kernel lê, em 32 bits, então uma variante com bit alto não passa mais pelo seccomp.
  • 2.4.0: O Landlock cerca sockets Unix abstratos e sinais em kernels 6.12 ou mais novos.
  • 2.4.0: macOS: o acesso ao terminal fica restrito aos terminais da própria execução, em vez de todos os /dev/ttys*.
  • 2.4.0: macOS: caminhos com --mask são negados para escrita, além de leitura.
  • 2.4.0: O filtro de saída não desmonta mais com um ESC duplicado, que podia contrabandear uma escrita no clipboard.
  • 2.4.0: As saídas de emergência de teste do proxy ficam fora dos builds de release.

Como uma release é feita

  • As tags de release são assinadas, e o CI verifica cada uma contra um fingerprint de chave fixado no repositório.
  • Cada GitHub Action é fixada num SHA de commit, e as actions são restritas a uma allowlist.
  • Os builds usam uma toolchain de Rust fixada e dependências com --locked.
  • Os binários de macOS são assinados e notarizados pela Apple.
  • Cada arquivo compactado vem com um checksum SHA-256, e o job de publicação confere todos de novo.

O que o documento de release diz que ainda falta

  • Os segredos de assinatura e de publicação ainda ficam guardados no nível do repositório e deveriam ir para os ambientes de release.
  • Ainda não há um ruleset que obrigue toda tag v* a ser assinada.
  • Releases imutáveis não estão habilitadas.
  • A publicação no crates.io ainda usa um token. O trusted publishing está planejado.
  • Com um único mantenedor, não há um segundo revisor para as mudanças nem para as releases.

Ler o RELEASE_SECURITY.md

Reportar uma vulnerabilidade

Não abra uma issue pública. Use o relato privado de vulnerabilidades do GitHub, inclua os passos para reproduzir e as versões afetadas, e dê tempo para coordenar uma correção.

Perguntas comuns

O agente consegue escapar?
Os padrões são feitos e testados para bloquear os caminhos comuns de um agente que erra: arquivos, ambiente, rede e IPC do host. Eles não são feitos para resistir a um atacante determinado: algo que tenta escapar de propósito poderia usar um bug de kernel, de driver, de terminal ou do backend do sandbox, e por isso o lugar de código hostil é uma VM descartável.
É seguro rodar com a rede ligada?
É mais seguro do que rodar o agente sem nada, porque as suas chaves e o seu diretório home continuam fora, sem ter como ser enviados. Com --network, tudo o que o agente consegue ler, ele consegue enviar, e o ai-jail não é feito para impedir um atacante determinado de fazer isso. O meio-termo é --allow-host: o agente alcança só os hosts que você lista, e cada um é confiável por inteiro. Mascare antes os segredos dentro do projeto. Veja como mascarar.
Ele já foi auditado?
Às claras: pelo próprio projeto antes da 1.0 e por duas auditorias de código independentes da 2.3.0, publicadas no repositório em setembro de 2026; a 2.4.0 fechou os dois advisories que elas geraram. Nenhuma empresa externa auditou o ai-jail. O código é aberto sob a GPL 3.0, e relatos privados de vulnerabilidade são bem-vindos.

Coloque seu agente atrás das grades

O ai-jail é um binário único que não precisa de daemon nem de root. Você acrescenta uma palavra na frente do comando que já usa.

terminal
brew tap akitaonrails/tap && brew install ai-jailai-jail claude