Sem nenhuma opção, o agente recebe o seu projeto, as suas ferramentas de build no Linux, o próprio login e o próprio host da API, e nenhuma rede além disso e de uma lista curta de registries de pacotes. Você fecha uma coisa de cada vez, e o lockdown fecha quase tudo de uma vez só.
As configurações vêm de um arquivo dentro do projeto, de um arquivo no seu diretório home e das flags que você digita. A lista vai da menor para a maior autoridade.
↔ Deslize para o lado para ver o diagrama inteiro
Um repositório que você clonou não consegue abrir a própria jaula.
.ai-jail do projeto
O ai-jail trata esse arquivo como não confiável: ele pode apertar a jaula, nunca abrir. Pode encurtar uma lista allow_hosts ou forward_ports, nunca acrescentar a ela. O ai-jail nunca o segue através de um symlink, e o agente vê um arquivo vazio no lugar dele.
~/.ai-jail global
É seu, então o ai-jail confia nele. Ele guarda uma tabela base para todas as execuções, mais tabelas [commands.<name>] escolhidas pela primeira palavra do comando.
Flags de linha de comando
As flags têm a maior autoridade. A maioria das opções vem em pares, como --network e --no-network, então uma flag também fecha o que um arquivo abriu.
Numa tabela de comando, valores simples substituem os da base, e listas como mapeamentos e máscaras são somadas a ela.
~/.ai-jail
# base: vale para todos os comandoshide_dotdirs = [".my_secrets"]mask = [".env", ".env.*"]# só quando o comando começa com "claude"[commands.claude]network = trueenv_pass = ["ANTHROPIC_BASE_URL"]mask = ["*.pem"]
As opções
Cada linha fica desligada até você pedir, com exceção das duas linhas em ciano, que vêm ligadas por padrão. Cada flag de recurso tem uma gêmea --no- que fecha de novo. Um selo vermelho marca uma opção que enfraquece a jaula. Segurança tem a lista completa e os motivos.
Rede e serviços
Flag
Chave de configuração
O que faz
Risco
--network
network = true
A rede inteira. Tudo o que o agente consegue ler, ele consegue enviar para fora. Se o agente só precisa de alguns hosts, --allow-host é a escolha mais apertada. Sem nenhuma das duas flags, o sandbox alcança só o host da API de um agente conhecido e, no Linux, os registries de pacotes que as toolchains abrem pelo proxy; --no-network fecha os dois.
Enfraquece a jaula
--allow-host <HOST>
allow_hosts = [...]
O sandbox alcança só o host listado e seus subdomínios, por TCP, pelo proxy embutido do ai-jail. A flag pode ser repetida. Desde a 2.8.1 a lista soma ao padrão, então um agente conhecido continua com o próprio host da API. Não combina com --network nem com --browser, e um arquivo de projeto só pode encurtar a lista.
Abre uma coisa
--forward-port <PORT>
forward_ports = [...]
Uma porta do loopback do host, repassada para o loopback do próprio sandbox. Um servidor MCP local, o socket de um editor ou um banco de dados de desenvolvimento no 127.0.0.1 do host responde na mesma porta lá dentro, e todas as outras portas do host continuam fechadas. Repita a flag para mais portas. Só no Linux, e recusada com --network e para portas abaixo de 1024. Funciona com --allow-host e sob --lockdown. O serviço atrás da porta é confiável por inteiro, sem allowlist e sem registro no log de auditoria. Um arquivo de projeto só consegue encurtar a lista. Onde forward_ports entra no arquivo de configuração.
Enfraquece a jaula
--ssh
ssh = true
O seu ~/.ssh, somente leitura, e o socket do seu agente SSH, para o git push funcionar.
Abre uma coisa
--docker
no_docker = false
O socket do Docker. Na prática é root na sua máquina, porque o daemon pode subir containers que montam o host.
Enfraquece a jaula
--tailscale
tailscale = true
O socket do Tailscale.
Abre uma coisa
--systemd-user
systemd_user = true
O barramento de usuário do systemd. O agente pode pedir ao seu gerenciador de usuário para rodar serviços no host. Só no Linux.
Enfraquece a jaula
Agente e ambiente
Flag
Chave de configuração
O que faz
Risco
--agent-state
agent_state = true
O login do próprio agente. O estado do harness iniciado, como ~/.claude, ~/.codex ou, no caso do Devin, ~/.local/share/devin e ~/.config/devin, é montado com leitura e escrita, e a chave de API dele é copiada do seu shell quando estiver definida: ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY ou GOOGLE_API_KEY, XAI_API_KEY, MOONSHOT_API_KEY. O agente começa logado, e tudo o que roda na jaula pode usar esse login. --no-agent-state dá uma execução sem login. Desligado no lockdown, e um arquivo de projeto só pode desligar.
Ligado por padrão
--claude-dir <PATH>
claude_dir = "..."
Usa o diretório informado como estado do Claude e define CLAUDE_CONFIG_DIR.
Abre uma coisa
--env <NAME[=VALUE]>
nenhuma
Repassa uma variável do seu shell, ou define uma com NAME=VALUE. Pode ser repetida e nunca é salva em disco. No Linux os valores viajam até o sandbox por um arquivo em memória e nunca aparecem na linha de comando do launcher, mas um NAME=VALUE literal continua visível na linha de comando do próprio ai-jail, então para um segredo prefira --env NAME ou --env-from-file.
Abre uma coisa
--env-from-file <PATH>
env_from_file = [...]
Lê linhas KEY=VALUE estritas de um arquivo e as repassa como --env, que ganha em caso de conflito. O arquivo precisa ser seu, um arquivo regular, com modo 0600 ou mais restrito e fora do projeto, senão a inicialização falha. O ai-jail nunca grava os valores em disco, e a chave de configuração só funciona a partir do arquivo global.
Abre uma coisa
--secret <KEY=host>
secret_hosts = { ... }
Mantém o valor real de KEY fora do sandbox. O agente vê um placeholder, e o proxy coloca o valor real só nas requisições para aquele único host. Precisa de --allow-host, e a chave já precisa entrar por --env ou --env-from-file. Só no arquivo global, nunca salva. Cobre clientes que conseguem falar HTTP puro com o proxy para esse host; túneis HTTPS não são tocados.
Abre uma coisa
--inherit-env
inherit_env = true
Repassa o ambiente inteiro do seu shell, com todos os segredos que houver nele. Evite.
Enfraquece a jaula
nenhuma
env_pass = ["NAME"]
O mesmo que --env, só a partir do arquivo global. Um arquivo de projeto que defina essa chave é ignorado.
Abre uma coisa
Toolchains e credenciais de ferramentas
Flag
Chave de configuração
O que faz
Risco
--toolchains
no_toolchains = false
Seus compiladores e gerenciadores de pacotes em somente leitura, os caches de dependências num store que pertence à jaula, e os registries de pacotes alcançáveis pelo proxy filtrado. Só no Linux, e lá ligado por padrão; no macOS nada é mapeado e nenhum registry é alcançável. O lockdown desliga, e um arquivo de projeto só pode desligar. Detalhes abaixo.
Ligado por padrão
--github
github = true
O seu diretório de configuração do gh, somente leitura, mais o seu token ativo do github.com repassado como GH_TOKEN naquela execução, para o gh estar logado mesmo quando o token mora no keyring do sistema. O ai-jail roda gh auth token no host e passa o resultado por um arquivo em memória, nunca por linha de comando nem em disco; --dry-run nunca busca o token, e um GH_TOKEN que você passa com --env pula a consulta. Só github.com e só a conta ativa. Tudo o que roda na jaula ainda pode agir no GitHub como se fosse você.
Abre uma coisa
--aws
aws = true
O seu ~/.aws, somente leitura. Tudo o que roda na jaula pode agir na AWS como se fosse você enquanto a credencial for válida.
Abre uma coisa
--kube
kube = true
O seu ~/.kube, somente leitura. Tudo o que roda na jaula pode falar com os seus clusters como se fosse você.
Abre uma coisa
--gcloud
gcloud = true
O seu ~/.config/gcloud, somente leitura. Tudo o que roda na jaula pode agir no Google Cloud como se fosse você.
Abre uma coisa
--docker-config
docker_config = true
O seu ~/.docker/config.json, somente leitura, onde ficam os seus logins de registry. Tudo o que roda na jaula pode usá-los.
Abre uma coisa
Desktop e hardware
Flag
Chave de configuração
O que faz
Risco
--gpu
no_gpu = false
Os dispositivos de GPU, e com eles a superfície de ataque do driver. Só no Linux.
Abre uma coisa
--kvm
kvm = true
O /dev/kvm, para máquinas virtuais com aceleração de hardware, como o QEMU ou um emulador Android. Expõe a interface KVM do kernel do host. Os guests recebem só a rede do sandbox, e nenhum dispositivo tun ou vhost. Só no Linux.
Abre uma coisa
--display
no_display = false
O socket do Wayland e mais nada da sua sessão. Só no Linux.
Abre uma coisa
--x11
x11 = true
O socket do X11. O X11 permite que um programa capture teclas e tire screenshots.
Enfraquece a jaula
--audio
audio = true
Os sockets do PipeWire e do PulseAudio e o /dev/snd. Tudo o que roda na jaula pode gravar e reproduzir áudio. Só no Linux.
Abre uma coisa
--host-shm
host_shm = true
O /dev/shm do host, que abre memória compartilhada com processos de fora da jaula.
Abre uma coisa
--pictures
pictures = true
O seu ~/Pictures, somente leitura.
Abre uma coisa
--browser[=hard|soft]
browser_profile = "hard"
Um perfil de navegador separado. hard (o padrão) não guarda nada entre execuções, soft mantém um perfil em ~/.local/share/ai-jail/browsers.
Abre uma coisa
Arquivos
Flag
Chave de configuração
O que faz
Risco
--map <PATH|SOURCE:DEST>
ro_maps = [...]
Monta mais um caminho como somente leitura. Escreva SOURCE:DEST para montar em outro lugar. Pode ser repetida.
Abre uma coisa
--rw-map <PATH|SOURCE:DEST>
rw_maps = [...]
Monta mais um caminho com leitura e escrita. Pode ser repetida.
Abre uma coisa
--overlay-map <PATH>
overlay_maps = [...]
Monta um caminho em copy-on-write: o que o agente escreve vai para uma camada à parte e o original fica intacto. Só no Linux; no macOS vira uma montagem somente leitura.
Abre uma coisa
--hide-dotdir <NAME>
hide_dotdirs = [...]
Nunca monta o diretório oculto indicado, por exemplo .my_secrets. Pode ser repetida.
Camadas que você pode desligar, e não deveria
Flag
Chave de configuração
O que faz
Risco
--no-landlock
no_landlock = true
Desliga o Landlock, a cópia das regras de arquivo que fica no próprio kernel. É recusada com --lockdown.
Enfraquece a jaula
--no-seccomp
no_seccomp = true
Desliga o filtro que bloqueia chamadas de sistema perigosas.
Enfraquece a jaula
--no-rlimits
no_rlimits = true
Desliga os limites que seguram processos fora de controle.
Enfraquece a jaula
--no-private-home
private_home = false
Abre mão do diretório home novo. É acesso amplo ao seu home real. Prefira --map para o único caminho de que você precisa.
Acrescenta um registro por inicialização em ~/.local/share/ai-jail/history.jsonl (diretório 0700, arquivo 0600): hora, comando, recursos efetivos, origens da configuração, código de saída e duração. Com --allow-host, cada conexão permitida ou negada também é registrada, e com --secret, cada injeção. Cada linha carrega o hash da linha anterior. Vem desligado por padrão, e um arquivo de projeto pode desligar, mas não ligar.
Abre uma coisa
--audit-show
nenhuma
Imprime um resumo legível do log e sai: inicializações, decisões da rede filtrada e substituições de segredos. Não confere a cadeia. Sai com 0 depois de mostrar, 1 com registros malformados ou erro de leitura, 2 quando não há log. Os registros de inicialização podem incluir os argumentos do comando, então deixe segredos fora deles.
--audit-verify
nenhuma
Percorre a cadeia de hashes do log de auditoria e sai: 0 quando ela está intacta, 1 no primeiro elo quebrado, 2 quando não há log. Registros gravados antes da 2.2 aparecem como legados, o que não é erro.
Utilitários
Flag
O que faz
--dry-run
Imprime o comando de sandbox e não roda nada. Nunca grava arquivo de configuração.
--init
Grava ou atualiza o .ai-jail do projeto e sai.
--clean
Ignora o .ai-jail do projeto nesta execução.
--bootstrap
Gera configurações de permissão para as próprias ferramentas de IA.
status
Mostra a configuração atual do .ai-jail.
-v, --verbose
Mostra cada montagem enquanto a jaula é construída.
Rode ai-jail --help para ver o resto: a barra de status, worktrees, mise e opções de terminal. A chave das toolchains é invertida como as mais antigas: no_toolchains = true desliga.
Esconda segredos dentro do projeto
Seu arquivo .env mora no projeto, e o projeto tem leitura e escrita. Com a rede ligada, o agente pode enviar para fora o que conseguir ler ali. Mascarar tira esses arquivos do alcance dele.
↔ Deslize para o lado para ver o diagrama inteiro
O resto do projeto continua como estava.
--mask <PATH|GLOB>
Substitui cada arquivo que bate com o padrão por um placeholder vazio. O agente vê que o arquivo existe e não recebe conteúdo nenhum, então ferramentas que só checam a existência dele continuam funcionando. A máscara muda só o que o sandbox vê. Um ajudante no host que age em nome do agente, como o daemon do Docker ou um servidor MCP, continua lendo o arquivo real.
--deny-path <PATH|GLOB>
Transforma cada caminho que bate com o padrão num erro de permissão.
--mask-except e --deny-path-except
Tiram um caminho de dentro de uma regra. Elas enfraquecem a proteção, então um arquivo de projeto não pode defini-las.
Como flags
# coloque os globs entre aspas para o ai-jail receber o padrão, e não a expansão do seu shellai-jail --mask .env --mask '.env.*' --mask '*.pem' --deny-path secrets/ claudeai-jail --mask '.env.*' --mask-except .env.example claude
.ai-jail
# um arquivo de projeto pode apertar, então isto também funciona no repositóriomask = [".env", ".env.*", "*.pem"]deny_paths = ["secrets/"]
Mantenha chaves de API fora de todo arquivo de configuração
Mascarar cobre arquivos do projeto. Para a chave do próprio agente, passe do seu shell com --env NAME, ou de um arquivo que só você consegue ler com --env-from-file. Nenhuma das duas é gravada num arquivo .ai-jail, e um arquivo de projeto não pode defini-las. Com a saída filtrada ligada, --secret KEY=host também mantém o valor real fora do sandbox; a receita abaixo mostra como.
terminal
# o arquivo precisa ser seu, com modo 0600 e fora do projetochmod 600 ~/.secrets/claude.envai-jail --env-from-file ~/.secrets/claude.env claude
~/.ai-jail
# só no arquivo global; um arquivo de projeto que defina isto é ignorado[commands.claude]env_from_file = ["~/.secrets/claude.env"]
Suas toolchains vão junto
Um build precisa de compiladores, gerenciadores de pacotes e seus caches. No Linux, o ai-jail leva tudo isso para dentro por padrão: as ferramentas em somente leitura, os caches num store que pertence à jaula, e os registries de pacotes alcançáveis pelo proxy filtrado.
↔ Deslize para o lado para ver o diagrama inteiro
Os caches do próprio host ficam do lado de fora, então um build na jaula não consegue envenenar o que o host compila a partir deles. O proxy deixa passar os registries e o host da API do próprio agente, e nada mais.
Ferramentas, somente leitura
Desde a 2.4.1, o ai-jail mapeia as instalações e a configuração do mise em somente leitura. Para Rust, mapeia ~/.cargo/bin e ~/.rustup do mesmo jeito, para o cargo e o rustc resolverem. As credenciais do Cargo e o config.toml ficam de fora. Como o mise não consegue instalar nada num mapeamento somente leitura, o ai-jail define MISE_NOT_FOUND_AUTO_INSTALL=false lá dentro, então uma ferramenta que falta falha uma vez, em vez de a cada chamada.
Um cache da própria jaula
Os caches de dependências ficam em ~/.local/share/ai-jail/cache/ e sobrevivem entre sessões. O registry e os caches de git do Cargo vão para lá. O cache padrão de pip, uv, Go, npm, yarn, pnpm, bun, deno, Maven, Gradle, Coursier, Composer, Crystal e Zig também, quando o diretório daquela ferramenta existe na sua máquina.
Registries, pelo proxy
Com as toolchains ligadas e nenhuma flag de rede, o sandbox alcança crates.io, npm, PyPI, o proxy do Go, Maven Central, Clojars, Packagist e github.com, cada um com seus subdomínios, pelo mesmo proxy de --allow-host. O host da API de um agente conhecido passa pelo mesmo caminho, no macOS também; os registries são só no Linux.
terminal
# o padrão no Linuxai-jail claude# caches ligados, nenhuma redeai-jail --no-network claude# nada mapeado, nada alcançávelai-jail --no-toolchains --no-network claude
Apertando a jaula
O padrão é ajustado para o trabalho render. Cada passo abaixo fecha mais uma coisa, e --lockdown fecha quase todas de uma vez. Segurança explica do que cada uma protege.
O padrão: o login do agente e o próprio host da API, as suas toolchains no Linux, os registries de pacotes e o projeto com leitura e escrita.
--no-network: totalmente offline. Junto com uma lista de --allow-host, o sandbox alcança só os hosts que você nomear, sem os padrões automáticos.
--no-agent-state: sem login. O estado do harness fica de fora e a chave de API dele não é copiada.
--no-toolchains: sem caches de dependências e sem registries de pacotes.
--mask, --deny-path e --hide-dotdir tiram caminhos específicos, e um --map ou --rw-map estreito substitui uma permissão ampla. Eles mudam o que o sandbox vê; um ajudante no host, como o daemon do Docker ou um serviço atrás de --forward-port, continua lendo os arquivos reais.
--lockdown: o projeto em somente leitura, sem login, sem toolchains, sem registries, Landlock e seccomp estritos, e ainda assim não é uma VM.
Lockdown: o agente lê o código e não pode alterar nada
--lockdown serve para revisões e auditorias. O agente lê o projeto e responde perguntas sobre ele, mas não consegue alterar nenhum arquivo.
↔ Deslize para o lado para ver o diagrama inteiro
O agente e o projeto são os mesmos, e só um diretório temporário é gravável.
O que muda
O projeto é montado como somente leitura
Só o /tmp é gravável no Linux. No macOS, nada é
Nenhum diretório oculto do seu home, nenhum mapeamento extra, nenhum overlay
O ambiente é limpo e o PATH fica fixo nos diretórios do sistema
O Landlock é obrigatório: se não puder ser aplicado, a inicialização falha
Limites mais apertados de processos, arquivos abertos e tamanho de arquivo
Sem tela, áudio, GPU, KVM, Docker, agente SSH ou mise, não importa o que mais você tenha passado
Sem caches de toolchain, saída para registries ou credenciais de ferramentas
Nenhum login do agente, então o harness começa deslogado
terminal
ai-jail --lockdown claude
Receitas
Copie uma. Para ver o que ela monta, rode antes com --dry-run.
Um agente em nuvem, no dia a dia
Um agente conhecido começa logado e alcança o próprio host da API pelo proxy filtrado, mais os registries de pacotes no Linux. Quando uma tarefa precisa de mais, coloque allow_hosts no arquivo global com os hosts extras, ou abra a rede inteira com network = true.
~/.ai-jail
# nada a acrescentar: login e api.anthropic.com já vêm por padrãoai-jail claude# quando uma tarefa precisa de mais, uma vez em ~/.ai-jail (somado ao host da API e, no Linux, aos registries)[commands.claude]allow_hosts = ["api.example.com"]# ou abra a rede inteira: network = true
Um agente que o ai-jail não conhece
O ai-jail libera o host da API por conta própria para cinco agentes. Qualquer outro agente recebe o host de você, com --allow-host. Se o host estiver faltando na lista, o aviso de inicialização diz qual é.
terminal
ai-jail --allow-host api.example.com myagent# um agente conhecido não precisa de flag: o ai-jail libera o host da API dele sozinho
Uma execução sem login
Quando o agente não deve ter credencial nenhuma, --no-agent-state deixa de fora o diretório de estado e a chave de API dele. Ele começa deslogado, e qualquer login que fizer dentro do home novo some quando a execução termina.
terminal
ai-jail --no-agent-state claude
Hosts permitidos no arquivo global
A lista vale para toda execução daquele comando, além do host da API do próprio agente. No Linux, github.com e os registries de pacotes já estão alcançáveis, então você só os lista no macOS. Um host permitido é confiável por inteiro: o agente pode pedir a ele qualquer coisa que as suas credenciais de lá permitirem.
Sem --network o sandbox tem o próprio loopback, então um servidor no 127.0.0.1 do seu host fica fora de alcance. --forward-port repassa essa única porta e nada mais, no Linux. No arquivo global, coloque forward_ports embaixo da tabela do comando e nunca na tabela base: a flag é recusada com --network, que --browser normalmente implica, e no macOS, então uma entrada na base faria essas inicializações falharem.
~/.ai-jail
ai-jail --forward-port 49374 claude# ou uma vez em ~/.ai-jail, embaixo da tabela do comando[commands.claude]forward_ports = [49374]
Uma chave que o agente nunca vê
O sandbox recebe um placeholder em ANTHROPIC_API_KEY, e o proxy do ai-jail coloca a chave real só nas requisições para api.anthropic.com. O cliente precisa enviar HTTP puro ao proxy para esse host, e é o que a URL base http:// faz; o ai-jail então leva a requisição até o host real por TLS. Um cliente que só abre túneis HTTPS continua funcionando, sem substituição.
terminal
# a chave mora no arquivo 0600; o sandbox só vê AIJAIL-PHANTOM-...ai-jail --allow-host api.anthropic.com \ --env-from-file ~/.secrets/claude.env \ --secret ANTHROPIC_API_KEY=api.anthropic.com \ --env ANTHROPIC_BASE_URL=http://api.anthropic.com claude
Git push via SSH
--ssh monta ~/.ssh como somente leitura e repassa o socket do seu agente SSH. Ele não abre a rede, por isso a receita o combina com --network. Para um push por HTTPS com o seu token do gh, veja a receita do GitHub CLI.
terminal
ai-jail --network --ssh claude
Compilar e testar dentro da jaula
No Linux, nada a acrescentar. cargo build, npm install ou go get baixam dos registries pelo proxy e guardam o cache no store da própria jaula, e as instalações do mise vão junto em somente leitura. Para uma execução que não toca em nada e não alcança nada, desligue os dois.
terminal
# padrão no Linux: caches ligados, registries alcançáveis pelo proxyai-jail claude# nada mapeado, nada alcançávelai-jail --no-toolchains --no-network claude
GitHub CLI dentro da jaula
--github monta o seu diretório de configuração do gh como somente leitura e repassa o seu token ativo do github.com como GH_TOKEN, então o gh e o git push por HTTPS ficam logados, com keyring ou sem. No Linux, github.com e seus subdomínios já estão na lista padrão, então você não adiciona host nenhum; no macOS, acrescente --allow-host github.com. A partir daí, tudo o que roda na jaula pode agir no GitHub como se fosse você.
terminal
ai-jail --github claude# macOS: github.com não está na lista padrão de láai-jail --github --allow-host github.com claude
Um navegador para o agente
--browser sozinho entrega um navegador que não carrega página nem abre janela. No Linux ele também precisa de --network e --display, e um navegador X11 precisa de --x11 no lugar de --display.
Mantenha o login do trabalho e o pessoal separados apontando cada execução para um diretório do Claude próprio.
terminal
ai-jail --network --claude-dir ~/.claude-work claude
Teste um refactor arriscado numa cópia
Um overlay guarda o que o agente escreve numa camada à parte, em .ai-jail-overlays dentro do projeto. Depois compare com o original e fique com o que gostar. Só no Linux.
terminal
ai-jail --network --overlay-map ~/Projects/my-app/src claude
Configs antigas continuam funcionando
Compatibilidade retroativa é regra do projeto: nenhuma flag ou chave de configuração é removida. Chaves desconhecidas são ignoradas e as que faltam assumem o valor padrão, então um arquivo escrito para uma versão antiga ainda carrega.
As opções mais antigas mantêm os nomes invertidos, em que true desliga a coisa: no_gpu, no_docker, no_display, no_mise, no_toolchains, no_landlock, no_seccomp, no_rlimits. É por isso que --gpu é salvo como no_gpu = false. As opções mais novas usam nomes diretos, como network = true. --allow-tcp-port ainda é interpretada e ainda se recusa a iniciar, porque não consegue cercar UDP. O erro dela aponta para --allow-host.