Permissões e auto mode: o que liberar e o que travar
Deny vence ask, que vence allow, e especificidade não muda nada. As três camadas de permissão do Claude Code e as regras que parecem proteger sem proteger.
- claude code
- permissões

Sumário
A regra que mais custa tempo: deny vence ask, que vence allow, e a especificidade não muda essa ordem. Um Bash(aws *) na lista de negação bloqueia todas as chamadas que casam, inclusive um Bash(aws s3 ls) que você tenha liberado logo abaixo. Não existe exceção dentro de uma negação.
Quem descobre isso depurando gasta uma tarde. Quem lê antes, gasta cinco minutos.
Três camadas que as pessoas tratam como uma
Antes de escrever qualquer regra, vale separar o que é o quê. As três camadas são independentes e se combinam.
| Camada | O que controla | Onde é aplicada |
|---|---|---|
| Regras de permissão | Quais ferramentas, comandos, arquivos e domínios | Pelo cliente, antes de a chamada rodar |
| Modo de permissão | Quanto ele pergunta antes de agir | Pelo cliente, por sessão |
| Sandbox do Bash | O que o processo consegue tocar de fato | Pelo sistema operacional |
A terceira é opcional e a mais forte. O sandbox usa Seatbelt no macOS e bubblewrap no Linux e no WSL2, com o sistema operacional aplicando o limite a todo comando e a todo processo filho. Windows nativo não é suportado. Liga com /sandbox.
A diferença prática entre a primeira camada e a terceira: regra de permissão impede o Claude de tentar; sandbox impede o processo de conseguir, mesmo que uma injeção de prompt tenha passado pela decisão do modelo. A comparação com o modelo do Codex, que traz sandbox ligado por padrão, está em Claude Code, Codex e Cursor lado a lado.
A ordem que decide tudo
Três tipos de regra, avaliados sempre nesta sequência: deny, depois ask, depois allow. A primeira que casar determina o resultado, e regra mais específica não sobe na fila.
Isso vale entre escopos também. Se as configurações de usuário liberam e as de projeto negam, a negação vence. O inverso também vale. Configuração gerenciada por organização fica no topo, e nem argumento de linha de comando derruba uma negação vinda dali.
Há uma diferença de comportamento entre as duas formas de negar que muda o que o agente sequer considera:
{
"permissions": {
"deny": [
"WebFetch",
"Bash(rm *)"
]
}
}O primeiro, com nome puro, remove a ferramenta do contexto. O Claude nunca vê que ela existe. O segundo deixa a ferramenta disponível e bloqueia quando a chamada casa com o padrão.
A escolha importa por dois motivos. Remover a ferramenta economiza contexto, porque a definição dela some do prompt de sistema. Em compensação, mexer nessa lista no meio da sessão invalida o cache inteiro, já que definições de ferramenta ficam na camada que menos muda. O post sobre por que seu agente esquece trata dessa conta.
Uma linha da documentação que vale colar na parede: as regras são aplicadas pelo Claude Code, não pelo modelo. Instrução no CLAUDE.md molda o que ele tenta fazer, e não muda o que ele consegue.
Os seis modos
A maioria dos textos cita três ou quatro. São seis, e dois deles quase nunca aparecem.
| Modo | O que roda sem perguntar | Para quando |
|---|---|---|
default (Manual) | Nada além dos comandos de leitura embutidos | Trabalho em código que você não conhece |
acceptEdits | Edições de arquivo e mkdir, touch, mv, cp no diretório de trabalho | Refatoração ampla e mecânica |
plan | Leitura e comandos somente-leitura, sem editar fonte | Investigação antes de decidir |
auto | Chamadas aprovadas por um classificador que roda em segundo plano | Padrão inicial em Pro, Max e Team |
dontAsk | Só o que já está em permissions.allow; o resto é negado, não perguntado | Execução automatizada com escopo fechado |
bypassPermissions | Quase tudo | Container descartável, e só |
O dontAsk é o mais subestimado. Ele nunca interrompe e nunca cede: o que não estiver liberado antes é recusado. Para tarefa longa rodando sem ninguém olhando, é o modo que combina previsibilidade com limite real.
Para impedir que alguém entre em bypassPermissions ou em auto, existem permissions.disableBypassPermissionsMode e permissions.disableAutoMode com o valor "disable". Em configuração gerenciada, viram política que o desenvolvedor não sobrepõe.
O que o auto mode bloqueia sem você pedir
No auto mode, um segundo modelo revisa as ações no lugar de você. Ele confia no seu diretório de trabalho e nos remotes que já estavam configurados quando a sessão abriu. Remote adicionado ou repontado no meio da sessão com git remote add ou set-url não entra nessa confiança.
O que ele bloqueia por padrão inclui baixar e executar código no estilo curl | bash, envio de dado sensível para fora, deploy e migração de produção, exclusão em massa em armazenamento na nuvem, concessão de permissão de IAM ou de repositório, force push, e o conjunto de comandos que descarta trabalho não commitado: git reset --hard, git checkout -- ., git restore ., git clean -fd, git stash drop e git stash clear. Também bloqueia terraform destroy e equivalentes de Pulumi, CDK e Terragrunt.
Tem um comportamento que quase ninguém conhece e que é útil todo dia: limite declarado na conversa conta como sinal de bloqueio. Se você escreve "não faça push" ou "espere eu revisar antes de publicar", o classificador passa a bloquear as ações correspondentes mesmo quando as regras padrão permitiriam. O limite vale até você mesmo levantar, e a avaliação do próprio Claude de que a condição foi cumprida não levanta.
A ressalva é séria: esses limites não viram regra. O classificador relê a conversa a cada verificação, então um limite some se a compactação levar embora a mensagem que o declarou. Para garantia dura, o que serve é uma regra de negação.
Quando o classificador bloqueia três vezes seguidas ou vinte vezes no total, o auto mode pausa e o Claude Code volta a perguntar. Os dois limiares não são configuráveis. Aprovar a ação perguntada religa o modo.
Onde as regras casam, e onde escorregam
Esta seção é a que separa configuração que protege de configuração que parece proteger.
Fronteira de palavra. Bash(ls *), com espaço antes do asterisco, casa com ls -la e não com lsof. Bash(ls*), sem espaço, casa com os dois. O espaço é a diferença entre liberar um comando e liberar todos que começam com aquelas letras.
Comando composto. O Claude Code entende operadores de shell, então Bash(safe-cmd *) não autoriza safe-cmd && other-cmd. Cada subcomando precisa casar por conta. Os separadores reconhecidos são &&, ||, ;, |, |&, & e quebras de linha.
Envelopes removidos. Antes de casar, o Claude Code tira um conjunto fixo de invólucros: timeout, time, nice, nohup, stdbuf, os builtins command e builtin, o noglob do zsh e o xargs sem flags. Por isso Bash(npm test *) também casa com timeout 30 npm test.
Envelopes que não são removidos, e aqui mora o problema. direnv exec, devbox run, mise exec, npx e docker exec ficam de fora dessa lista, e todos executam o que vem depois deles. Uma regra Bash(devbox run *) casa com devbox run rm -rf .. A lista é embutida e não configurável. Para liberar trabalho dentro de um runner, escreva a regra com o comando interno junto, como Bash(devbox run npm test), uma por comando.
Redirecionamento é escrita. O alvo de >, >> ou 2> é verificado como escrita de arquivo, contra suas regras de Edit, os caminhos protegidos e os diretórios de trabalho. Bash(git commit *) libera o comando, não o alvo. Um alvo que comece com ~ ou contenha glob pede aprovação, e /dev/null não é verificado.
Atribuição de variável. Regras de negação e de pergunta casam depois de qualquer atribuição no início, então Bash(rm *) em deny continua pegando FOO=bar rm -rf tmp/. Regras de liberação só atravessam um conjunto conhecido de variáveis seguras.
Comandos de leitura como ls, cat, grep, head, wc, diff e as formas somente-leitura do git já rodam sem prompt em qualquer modo. Liberá-los na configuração é ruído. O conjunto é embutido e não configurável, e para exigir prompt em um deles o caminho é uma regra de ask ou deny.
Regra de argumento não é fronteira
A documentação traz um aviso que merece seção própria. Uma regra como Bash(curl http://github.com/ *), que pretende restringir o curl a um domínio, não casa com nenhuma destas variações:
- Opção antes da URL:
curl -X GET http://github.com/... - Outro protocolo:
curl https://github.com/... - Redirecionamento:
curl -L http://encurtador.exemplo/xyzapontando para o GitHub - Variável:
URL=http://github.com && curl $URL - Espaço a mais:
curl http://github.com
Três alternativas que funcionam de verdade, em ordem de firmeza:
1. Negue as ferramentas de rede do Bash e use o WebFetch com allowlist de domínio. WebFetch(domain:example.com) casa pelo hostname, e o curinga tem semântica cuidadosa: *.example.com pega qualquer subdomínio e não pega example.com; example.* casa com example.org e não com example.evil.com, porque o curinga não atravessa ponto. Isso é o que impede um atacante de registrar um domínio que caia na sua regra.
2. Use um hook PreToolUse. Um hook que sai com código 2 interrompe a chamada antes de as regras de permissão serem avaliadas, então o bloqueio vale mesmo com uma regra de liberação casando. O caminho inverso não existe: hook que devolve "allow" não derruba deny nem ask. A mecânica de hooks está em hooks no Claude Code.
3. Ligue o sandbox. É a única camada que continua valendo se o modelo for enganado.
Um detalhe que economiza uma sessão de depuração: você não consegue casar o campo principal de conteúdo de uma ferramenta por parâmetro. Bash(command:rm *) seria contornável por comando composto, então o Claude Code ignora a regra e emite aviso na inicialização. As formas válidas são Bash(rm *), Read(./caminho) e WebFetch(domain:host).
Caminhos que regra nenhuma libera
Duas listas embutidas que existem como disjuntor contra erro do modelo.
Caminhos protegidos. Escrita neles nunca é aprovada em automático, exceto em bypassPermissions. Regras em permissions.allow não pré-aprovam: a verificação roda antes de as regras de liberação serem avaliadas, então um Edit(.claude/**) nas configurações não muda nada. São .git, .config/git, .vscode, .idea, .husky e .cargo.
Caminhos críticos. Nem regra de liberação nem hook devolvendo "allow" aprovam um rm ou rmdir que os tenha como alvo. Entram na lista a raiz do sistema de arquivos, qualquer diretório de primeiro nível como /usr ou /etc, seu diretório pessoal, raízes de unidade no Windows como C:\, e seu diretório de trabalho junto com os pais dele.
Duas finuras nessa verificação. Um glob logo abaixo de uma variável, como rm -rf "$DIR"/*, conta como remoção crítica, porque o comando vira remoção a partir da raiz se a variável estiver vazia. E esconder a remoção dentro de $(...), de crase ou de <(...) não escapa da checagem.
Uma configuração inicial que se defende
Ponto de partida para projeto normal, com o raciocínio de cada bloco:
{
"permissions": {
"defaultMode": "default",
"allow": [
"Bash(npm run test *)",
"Bash(npm run lint *)",
"Bash(npm run build)",
"WebFetch(domain:docs.meuprojeto.com)"
],
"ask": [
"Bash(git push *)",
"Bash(npm publish *)",
"Bash(gh pr merge *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(npx *)",
"Bash(docker exec *)"
]
}
}O allow não lista ls, cat nem git status, porque já rodam sem prompt. Lista só o que é repetitivo e seguro no seu fluxo.
O ask cobre o que muda o mundo fora da sua máquina. Note que git push em ask prompta mesmo se houver um allow mais específico casando, e mesmo com o sandbox ligado.
O deny faz duas coisas distintas. Bloqueia leitura de segredo, e fecha as portas de execução indireta: curl, wget, npx e docker exec são os quatro caminhos mais comuns para rodar código que a sua lista de liberação nunca viu.
Para servidores MCP, a sintaxe é por servidor e por ferramenta: mcp__github pega todas do servidor, mcp__github__get_* pega as de leitura. Vale ler o guia de MCP na prática antes de liberar um servidor inteiro.
Depois de escrever isso, rode /permissions para ver todas as regras ativas e de qual arquivo cada uma vem. O checklist mais amplo de operação está em Claude Code em produção.
Para o caso específico de git, que tem lista de recusa própria no auto mode, veja git com agente.
Perguntas frequentes
Uma regra de liberação específica supera uma negação ampla?
Não. A ordem é deny, ask, allow, e a primeira que casar decide. Especificidade não altera a fila, então Bash(aws s3 ls) em allow não abre exceção dentro de Bash(aws *) em deny. Se você precisa de exceção, escreva a negação de forma mais estreita.
Qual a diferença entre negar Bash e negar Bash(rm *)?
Negar o nome puro remove a ferramenta do contexto do Claude, que nunca fica sabendo que ela existe. Negar com escopo mantém a ferramenta disponível e bloqueia quando a chamada casa com o padrão. A primeira forma economiza contexto e invalida o cache quando mudada no meio da sessão.
Se eu disser ao Claude para não fazer deploy, isso vira uma garantia?
No auto mode vira sinal de bloqueio para o classificador, que passa a barrar ações correspondentes. Mas o limite é relido da conversa a cada verificação e se perde se a compactação apagar a mensagem. Para garantia que não depende de contexto, use uma regra de negação.
O sandbox substitui as regras de permissão?
Não, eles são camadas complementares. As regras impedem o Claude de tentar; o sandbox impede o processo de conseguir. Mesmo com o sandbox ligado, negações explícitas continuam valendo, ask com escopo como Bash(git push *) continua perguntando, e rm em caminho crítico continua passando pelo fluxo normal.
Fontes
- Anthropic — Claude Code Docs: Configure permissions. Acesso em 20/08/2026.
- Anthropic — Claude Code Docs: Choose a permission mode. Acesso em 20/08/2026.
- Anthropic — Claude Code Docs: Configure the sandboxed Bash tool. Acesso em 20/08/2026.
- Anthropic — Claude Code Docs: Automate actions with hooks. Acesso em 20/08/2026.
- Anthropic — Claude Code Docs: How Claude Code works. Acesso em 20/08/2026.
Verificado em 20 de agosto de 2026.
Gatilho de reavaliação: revisar quando (a) a lista de invólucros removidos antes do casamento de regra mudar, (b) os limiares de três bloqueios seguidos e vinte no total do auto mode virarem configuráveis, ou (c) o sandbox passar a suportar Windows nativo.
Leia também
Plugins e marketplaces: como avaliar antes de instalar
A documentação diz que plugin executa código arbitrário com seus privilégios. O checklist de cinco minutos usando as ferramentas que já vêm no Claude Code.
- claude code
- plugins
Hooks: a única camada que garante
Um hook que nega bloqueia a ferramenta até com bypassPermissions. Hooks apertam restrição e nunca afrouxam, e é isso que os torna a camada de política.
- claude code
- hooks
Git com agente: commit, branch e code review assistido
A lista de operações git que o auto mode recusa sozinho, worktrees para trabalho paralelo, e por que /rewind não desfaz o que o review de fundo escreveu.
- claude code
- git


