Tips & Tricks

Guia Completo de Permissões do Claude Code | settings.json, Hooks e Allowlist Explicados

Guia completo das configurações de permissão do Claude Code. Aprenda a usar allow/deny/ask, automação com Hooks, settings.json por ambiente e padrões práticos — com código funcional.

O Claude Code possui capacidades extremamente poderosas de operação de arquivos e execução de comandos. As permissões (permissions) são o que permite controlar esse poder com segurança. Supere o estado de “usar sem realmente entender” e projete um Claude Code que funcione exatamente como pretendido.

Este artigo explica detalhadamente, com código funcional, todas as configurações do .claude/settings.json, os padrões de implementação de Hooks e o design de permissões por ambiente.

Visão Geral das Permissões

As permissões do Claude Code são controladas em 3 níveis.

NívelChaveComportamento
PermitirallowExecuta automaticamente sem diálogo de confirmação
PerguntaraskRequer aprovação do usuário a cada vez
NegardenyNão pode ser executado de forma alguma (bloqueado com erro)

As configurações são escritas no .claude/settings.json. Colocado na raiz do projeto, permite que a equipe compartilhe via git; colocado em ~/.claude.json, torna-se uma configuração global.

Prioridade (maior primeiro):
Projeto .claude/settings.json
    > Global ~/.claude.json
        > Padrão (tudo é ask)

Estrutura Básica do settings.json

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)"
    ]
  },
  "hooks": {
    "PreToolUse": [],
    "PostToolUse": []
  }
}

Nomes de Ferramentas e Sintaxe de Padrões

As permissões são escritas no formato “NomeFerramenta(padrão de argumento)”.

Lista das Principais Ferramentas

Nome da FerramentaDescrição
ReadLeitura de arquivos
WriteCriação de novos arquivos
EditModificação parcial de arquivos existentes
BashExecução de comandos shell
GlobBusca por padrão de arquivos
GrepBusca de conteúdo
WebFetchBusca de URL
AgentInicialização de sub-agente

Sintaxe de Padrões

"Read(**)"          // Permitir leitura de todos os arquivos
"Read(src/**)"      // Permitir apenas sob src/
"Read(*.md)"        // Permitir apenas arquivos .md
"Bash(npm run *)"   // Permitir apenas comandos que começam com npm run
"Bash(git *)"       // Permitir todos os comandos git
"Bash(rm -rf *)"    // Negar rm -rf

** corresponde a todos os caminhos incluindo diretórios; * corresponde a um único segmento.

Padrões Práticos

Padrão 1: Desenvolvimento Solo (relativamente permissivo)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm *)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git add*)",
      "Bash(node *)",
      "Bash(echo *)",
      "Bash(cat *)",
      "Bash(ls *)"
    ],
    "deny": [
      "Bash(rm -rf /)",
      "Bash(rm -rf ~*)",
      "Bash(git push --force *main*)",
      "Bash(git push --force *master*)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(rm *)"
    ]
  }
}

Padrão 2: Desenvolvimento em Equipe (focado em segurança)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(npm run lint)",
      "Bash(npm run test)",
      "Bash(npm run typecheck)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git branch*)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Bash(git push -f*)",
      "Bash(git reset --hard*)",
      "Bash(git rebase *main*)",
      "Bash(git rebase *master*)",
      "Bash(DROP *)",
      "Bash(TRUNCATE *)",
      "Bash(curl * | bash)",
      "Bash(wget * | sh)"
    ],
    "ask": [
      "Write(**)",
      "Edit(**)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(git add*)",
      "Bash(npm install*)",
      "Bash(*deploy*)"
    ]
  }
}

Padrão 3: Ambiente de Produção (somente leitura)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(git show*)",
      "Bash(cat *)",
      "Bash(ls *)",
      "Bash(ps *)",
      "Bash(df *)",
      "Bash(top *)"
    ],
    "deny": [
      "Write(**)",
      "Edit(**)",
      "Bash(git push*)",
      "Bash(git commit*)",
      "Bash(git reset*)",
      "Bash(rm *)",
      "Bash(mv *)",
      "Bash(*deploy*)",
      "Bash(*restart*)",
      "Bash(*kill *)"
    ],
    "ask": []
  }
}

Em produção, isso é especificado com CLAUDE_SETTINGS=.claude/settings.production.json claude.

Padrão 4: Apenas Geração de Conteúdo (o padrão usado neste site)

{
  "permissions": {
    "allow": [
      "Read(**)",
      "Glob(**)",
      "Grep(**)",
      "Write(site/src/content/**)",
      "Write(content/**)",
      "Edit(site/src/content/**)",
      "Edit(content/**)",
      "Bash(git log*)",
      "Bash(git diff*)",
      "Bash(git status*)",
      "Bash(node scripts/*)",
      "Bash(QIITA_TOKEN=* node scripts/qiita-publish.mjs)"
    ],
    "deny": [
      "Bash(rm -rf*)",
      "Bash(git push --force*)",
      "Edit(.env*)",
      "Read(.env*)"
    ],
    "ask": [
      "Bash(git add*)",
      "Bash(git commit*)",
      "Bash(git push*)",
      "Bash(bash scripts/deploy.sh*)"
    ]
  }
}

A chave é restringir as escritas a um diretório específico, como com Write(site/src/content/**).

Hooks: Executar Processos Antes e Depois das Permissões

Hooks são um mecanismo que executa comandos automaticamente antes e depois da execução de ferramentas. Podem ser usados para verificações de segurança e formatação automática.

PreToolUse: Hook Antes da Execução

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(git add*)",
        "hooks": [{
          "type": "command",
          "command": "git diff --cached --name-only | grep -E '^\\.env' && echo '🚨 Adição de .env detectada!' && exit 1 || exit 0"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "node scripts/secret-scan.mjs"
        }]
      },
      {
        "matcher": "Bash(rm*)",
        "hooks": [{
          "type": "command",
          "command": "echo '⚠️ Comando de exclusão detectado. Executando em 5 segundos. Ctrl+C para cancelar.' && sleep 5"
        }]
      }
    ]
  }
}

Se um comando hook retornar código de saída 1, a execução da ferramenta é bloqueada. Este é o ponto mais importante.

PostToolUse: Hook Após a Execução

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "npx tsc --noEmit 2>&1 | head -20 || true"
        }]
      },
      {
        "matcher": "Bash(git commit*)",
        "hooks": [{
          "type": "command",
          "command": "git log --oneline -3"
        }]
      }
    ]
  }
}

PostToolUse é usado para verificações pós-execução e efeitos colaterais — por exemplo, executar automaticamente verificações de tipo após editar arquivos ou exibir as 3 entradas de log mais recentes após um commit.

Coleção de Receitas Práticas de Hooks

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash(npm install*)",
        "hooks": [{
          "type": "command",
          "command": "echo '📦 Adicionando pacote. Por favor, verifique o package.json.'"
        }]
      },
      {
        "matcher": "Bash(*deploy*)",
        "hooks": [{
          "type": "command",
          "command": "read -p '🚀 Prestes a fazer deploy. Continuar? [y/N] ' ans && [ \"$ans\" = 'y' ] || exit 1"
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write(*.ts)|Edit(*.ts)",
        "hooks": [{
          "type": "command",
          "command": "npx eslint --fix $CLAUDE_TOOL_INPUT_FILE_PATH 2>/dev/null || true"
        }]
      }
    ]
  }
}

Modos de Permissão: Nível de Permissão na Inicialização

Você também pode especificar o modo ao iniciar o comando claude.

# Modo normal (segue settings.json)
claude

# Aprovar automaticamente todas as operações (perigoso! apenas para ambientes confiáveis)
claude --dangerously-skip-permissions

# Pular apenas operações específicas
claude --allowedTools "Read,Grep,Glob"

# Modo não-interativo (usado em CI/CD)
claude -p "Execute os testes e relate os resultados" --dangerously-skip-permissions

--dangerously-skip-permissions deve ser usado apenas para automação CI/CD ou scripts de automação completamente compreendidos, e evitado no uso interativo diário.

Prioridade e Substituição de Arquivos de Configuração

Quando existem vários arquivos de configuração:

~/.claude.json              ← Global (compartilhado entre todos os projetos)
    +
.claude/settings.json       ← Projeto (gerenciado pelo git)
    +
.claude/settings.local.json ← Substituições pessoais (gitignore recomendado)
    =
A configuração mesclada é aplicada

Escreva configurações adicionais pessoais em .claude/settings.local.json e adicione ao gitignore. Para evitar que as listas deny da equipe sejam substituídas por configurações pessoais, o design seguro é escrever regras deny apenas no settings.json.

# Adicionar ao .gitignore
.claude/settings.local.json

As 5 Armadilhas Mais Comuns

1. Errar os padrões de wildcard

// ❌ Isso só corresponde ao comando único "git"
"Bash(git)"

// ✅ Também corresponde a git seguido de argumentos
"Bash(git *)"
"Bash(git*)"  // Também funciona sem espaço, mas * explícito é mais seguro

2. Esquecer que deny tem prioridade sobre ask

// Com esta configuração, Bash(rm -rf /tmp/test) é capturado por deny e bloqueado
// Nunca chega a ask
{
  "deny": ["Bash(rm -rf*)"],
  "ask": ["Bash(rm*)"]  // ← rm -rf é tratado por deny
}

3. Não prestar atenção aos códigos de saída dos hooks

# Se o comando do hook PreToolUse sempre retornar exit 0,
# falhas de varredura não bloquearão a execução

# ❌ Passa mesmo em caso de erro
"command": "node scan.mjs"

# ✅ Controlar explicitamente o código de saída
"command": "node scan.mjs || exit 1"

4. Adicionar acidentalmente settings.json ao .gitignore

Algumas equipes adicionam acidentalmente settings.json—que querem compartilhar—ao .gitignore. A abordagem correta é configuração do projeto sob git, apenas settings.local.json no gitignore.

5. Esquecer de trocar manualmente a configuração de produção

# ❌ Trabalhando em produção com as configurações do dia a dia

# ✅ Trocar explicitamente as configurações antes do trabalho em produção
CLAUDE_SETTINGS=.claude/settings.production.json claude

Registrar um alias torna mais difícil de esquecer:

# ~/.bashrc or ~/.zshrc
alias claude-prod='CLAUDE_SETTINGS=.claude/settings.production.json claude'

Depurando a Configuração

Quando não está claro “por que este comando está sendo bloqueado”:

# Verificar as configurações atuais
claude --print-settings 2>/dev/null || cat .claude/settings.json

# Verificar qual regra está correspondendo (modo verbose)
claude --verbose -p "Execute git push"

Resumo: Melhores Práticas para Design de Permissões

1. Começar com deny
   → Listar comandos que nunca devem ser executados
   → rm -rf, git push --force, DROP TABLE são essenciais

2. Depois configurar ask
   → Operações de escrita e deploy que precisam de confirmação

3. Allow para todo o resto
   → Operações de leitura e CI: tudo em allow para eficiência

4. Automatizar segurança com Hooks
   → Varredura pré-commit, verificação de tipos automática após edições

5. Preparar arquivos de configuração específicos por ambiente
   → settings.json (desenvolvimento), settings.production.json (produção)

Com configurações de permissão adequadas, você parará de pressionar mecanicamente botões de aprovação e poderá se concentrar apenas nas operações que realmente precisam de revisão. Dedicar 30 minutos ao design inicial tornará centenas de horas futuras de trabalho mais seguras.

Artigos Relacionados

Referências

#claude-code #permissions #security #hooks #settings #configuration

Leve seu fluxo no Claude Code a outro nível

50 modelos de prompt testados em campo, prontos para colar direto no Claude Code.

Grátis

PDF gratuito: Cheatsheet do Claude Code em 5 minutos

Basta informar seu e-mail e enviamos na hora o cheatsheet em uma página A4.

Cuidamos dos seus dados pessoais e nunca enviamos spam.

Masa

Sobre o autor

Masa

Engenheiro apaixonado por Claude Code. Mantém o claudecode-lab.com, uma mídia tech em 10 idiomas com mais de 2.000 páginas.