Pular para o conteúdo
Zumkai

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
Diagrama da ordem de avaliação das permissões do Claude Code: deny, ask e allow.
Sumário
  1. Três camadas que as pessoas tratam como uma
  2. A ordem que decide tudo
  3. Os seis modos
  4. O que o auto mode bloqueia sem você pedir
  5. Onde as regras casam, e onde escorregam
  6. Regra de argumento não é fronteira
  7. Caminhos que regra nenhuma libera
  8. Uma configuração inicial que se defende
  9. Perguntas frequentes
  10. Fontes

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.

CamadaO que controlaOnde é aplicada
Regras de permissãoQuais ferramentas, comandos, arquivos e domíniosPelo cliente, antes de a chamada rodar
Modo de permissãoQuanto ele pergunta antes de agirPelo cliente, por sessão
Sandbox do BashO que o processo consegue tocar de fatoPelo 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:

json
{
  "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.

ModoO que roda sem perguntarPara quando
default (Manual)Nada além dos comandos de leitura embutidosTrabalho em código que você não conhece
acceptEditsEdições de arquivo e mkdir, touch, mv, cp no diretório de trabalhoRefatoração ampla e mecânica
planLeitura e comandos somente-leitura, sem editar fonteInvestigação antes de decidir
autoChamadas aprovadas por um classificador que roda em segundo planoPadrão inicial em Pro, Max e Team
dontAskSó o que já está em permissions.allow; o resto é negado, não perguntadoExecução automatizada com escopo fechado
bypassPermissionsQuase tudoContainer 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/xyz apontando 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:

json
{
  "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

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

Claude Code

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