Hooks no Claude Code: guardrails, contexto e automação no ciclo de execução

English summary: Claude Code hooks make operational policy executable at lifecycle boundaries. This production guide explains where pre- and post-tool hooks help, where they do not, and how to build small, observable, idempotent guardrails without turning automation into a hidden control plane.
Published: August 2026
Reading time: 18 min
Keywords: Claude Code hooks, PreToolUse, PostToolUse, guardrails, automação agentic, segurança de IA, observabilidade
Exemplo concreto: um hook pode negar `deploy` quando não há aprovação, antes que qualquer side effect aconteça.
Um agente pode receber uma instrução impecável e ainda rodar o comando errado no lugar errado.
Esse é o ponto em que muita estratégia de IA para engenharia quebra: o time tenta resolver um problema operacional com um lembrete em linguagem natural. “Não mexa em produção”, “rode testes”, “não exponha segredos” e “use rg, não grep” acabam presos em um prompt que compete com urgência, contexto parcial e dezenas de decisões no meio do loop.
A tese deste artigo é simples: hooks do Claude Code são úteis quando transformam uma regra pequena, objetiva e verificável em uma decisão executável no ponto exato do ciclo de vida; eles são perigosos quando viram uma segunda aplicação invisível, com permissões demais e sem dono.
Vamos focar no que funciona em produção: lifecycle hooks, PreToolUse e PostToolUse, validação, bloqueio, logging seguro, idempotência, limites e verificação. O objetivo não é “automatizar tudo”. É reduzir classes concretas de erro sem criar um plano de controle impossível de auditar.
No Claude Code, hooks são comandos shell, endpoints HTTP, chamadas MCP ou prompts que rodam automaticamente em eventos do ciclo de vida. Eles recebem contexto em JSON e podem, conforme o evento, adicionar contexto, registrar um fato, pedir aprovação ou bloquear uma ação. A referência oficial lista eventos de sessão, de turno e do loop agentic; entre os últimos estão PreToolUse, PostToolUse, PostToolUseFailure e PostToolBatch.[^hooks]
Isso torna o hook uma peça de controle de fronteira. Ele não é o cérebro do agente e não deveria reimplementar seu plano.
| Mecanismo | Pergunta que responde | Melhor uso | Limite principal |
|---|---|---|---|
CLAUDE.md e skills | “Como este projeto funciona?” | contexto, convenções e playbooks | instrução não é imposição |
| Permissões | “Esta categoria de ação é permitida?” | política estável e escopo de tools | pode ser ampla demais para condição contextual |
| Hook | “Esta ação, agora, passa nesta regra?” | validação de fronteira, bloqueio e telemetria | adiciona latência e superfície operacional |
| CI/CD | “A mudança entregue atende ao contrato?” | testes, análise estática, deploy gates | normalmente só vê depois do trabalho local |
| Workflow comum | “Qual passo fixo vem agora?” | tarefas determinísticas | não precisa de loop agentic |
Um hook também não é um firewall, um SIEM, um mecanismo de autorização corporativa nem uma garantia de que produção está segura. Se um comando tem credenciais de produção e pode ser executado fora do Claude Code, a proteção real precisa existir no provedor, na identidade e na pipeline. O hook reduz risco no caminho que ele observa; não elimina as outras rotas.
Há casos em que um hook é a escolha errada. Formatar todos os arquivos ao salvar pode caber melhor no editor ou no linter. Validar um pull request inteiro deve continuar na CI. Uma decisão que depende de semântica de negócio ambígua deve parar para uma pessoa, em vez de ser escondida em um script de 400 linhas. Use hook para regra de borda; use workflow para sequência previsível; use humano para exceção relevante.
O repositório declara “nunca faça deploy” em um documento, mas nada impede Bash de invocar um deploy. A regra até pode estar no contexto do modelo; não está no caminho de execução.
O antídoto é escolher poucas invariantes que podem ser decididas sem interpretação. “Nunca terraform apply neste projeto” é uma boa candidata. “Não faça mudanças arriscadas” não é: alguém precisa definir risco, escopo e exceções.
PostToolUse acontece depois que a tool concluiu. Ele é excelente para registrar um evento, iniciar uma verificação ou acrescentar feedback ao agente, mas não desfaz um arquivo gravado, um comando executado ou uma requisição enviada. A documentação também deixa claro que substituir a saída pós-tool muda o que o modelo vê, não o efeito que já ocorreu.[^hooks]
Para prevenir um efeito, a fronteira é PreToolUse. Para aprender com um efeito já ocorrido, a fronteira é PostToolUse ou PostToolUseFailure. Confundir os dois produz um “guardrail” que só explica o acidente.
Receber JSON completo no stdin é útil para decisão, mas é uma péssima justificativa para gravar tudo. Comandos podem conter tokens, URLs assinadas, nomes de clientes, paths internos e argumentos sensíveis. Saídas podem carregar PII ou dados de banco. Um arquivo de auditoria com esses valores vira um novo ativo sensível, frequentemente sem retenção, acesso ou alerta definidos.
Logue o mínimo que permite responder “qual regra decidiu o quê e quando?”: evento, tool, resultado, versão da política e identificador técnico pseudônimo. Não registre prompt, comando, conteúdo de arquivo, resposta de tool ou segredo. E não imprima diagnósticos no stdout de um hook que precisa devolver JSON: a documentação exige que esse stdout contenha somente o objeto JSON de controle.[^hooks]
PostToolUse pode disparar em chamadas paralelas, e retries existem. Um hook que abre ticket, manda mensagem ou altera estado remoto em toda invocação cria duplicatas e ruído. Pior: ninguém sabe se o dono é a plataforma, segurança ou o time que criou o script.
Toda ação com efeito deve ter uma chave de deduplicação, prazo de retenção e responsável. Quando não houver uma chave confiável, prefira logging local de baixo risco e deixe uma automação posterior consolidar os eventos. “Rodou sem erro” não prova correção; prova apenas que o processo chegou ao fim.
Um agente confiável não é apenas um modelo com terminal. Ele combina contexto, tools, permissões, ambiente e verificação. O hook entra como uma camada estreita entre a intenção do modelo e a ação observável.
Essa ordem importa. As permissões são a política ampla: ferramentas ou padrões que em geral devem ser negados, perguntados ou permitidos. O PreToolUse é a avaliação contextual antes da chamada. O PostToolUse observa o resultado já produzido. Testes, git diff, linters e CI fecham a verificação fora do hook.
As permissões continuam prevalecendo como defesa em camadas. Segundo a documentação, uma regra deny ou ask aplicável não é anulada por um allow devolvido pelo hook; hooks de bloqueio também têm precedência sobre regras permissivas.[^permissions] Isso é uma boa propriedade: o script não deve ter poder para ampliar uma política mais restritiva por acidente.
Evolua em degraus. Não pule para hooks HTTP e integrações remotas porque o JSON parece poderoso.
CLAUDE.md ou runbook.if.PreToolUse local para regra determinística; conecte dados externos apenas quando aumentarem a qualidade da decisão.ask para transições sensíveis.O ganho dessa escada é reversibilidade. Um shell hook no projeto pode ser revisado junto do código. Um endpoint que decide permissões para toda a empresa exige autenticação, versionamento, disponibilidade, observabilidade e processo de mudança. Comece no menor mecanismo que prova valor.
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
13 produtos disponíveisContinue explorando tópicos similares

# Subagents ou Agent Teams no Claude Code: como paralelizar sem criar caos English summary: A practical guide to choosing Claude Code subagents or experimental agent teams, defin

# Permissões do Claude Code: como desenhar autonomia sem abrir a produção English summary: A practical framework for using Claude Code permissions, settings, allow/deny rules, ho

# Como Criar um Agent de Code Review com Claude Code que Encontra Risco Real English summary: A practical, security-minded guide to building a Claude Code review agent that inspe
Checklist prático para validar segurança, custos, avaliações e observabilidade antes de colocar seu app com IA em produção.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.
O exemplo abaixo é deliberadamente pequeno. Ele usa jq, disponível em muitos ambientes de desenvolvimento, e dois hooks de projeto. O primeiro barra padrões destrutivos e pede aprovação para git push; o segundo escreve uma auditoria mínima. Ele não substitui controles do seu cloud, não entende todos os shells e não deve ser copiado sem ajustar os padrões e o owner.
Crie .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-bash.sh",
"timeout": 5
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash|Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/audit-tool-use.sh",
"timeout": 5
}
]
}
]
}
}
Crie .claude/hooks/guard-bash.sh e marque-o como executável (chmod +x .claude/hooks/guard-bash.sh):
#!/usr/bin/env bash
set -euo pipefail
input="$(cat)"
command="$(jq -r '.tool_input.command // empty' <<<"$input")"
deny() {
jq -n --arg reason "$1" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: $reason
}
}'
}
ask() {
jq -n --arg reason "$1" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "ask",
permissionDecisionReason: $reason
}
}'
}
case "$command" in
*"terraform apply"*|*"kubectl "*"prod"*|*"git push --force"*|*"rm -rf /"*)
deny "Blocked by project policy: destructive or production-like command."
;;
*"git push "*)
ask "A remote write needs explicit human approval."
;;
*)
exit 0
;;
esac
E crie .claude/hooks/audit-tool-use.sh, também executável:
#!/usr/bin/env bash
set -euo pipefail
# Best-effort, local audit: no prompts, commands, file contents or tool output.
input="$(cat)"
tool_use_id="$(jq -r '.tool_use_id // empty' <<<"$input")"
tool_name="$(jq -r '.tool_name // "unknown"' <<<"$input")"
# A missing ID means no safe deduplication key. Do not invent one from sensitive input.
[ -n "$tool_use_id" ] || exit 0
runtime_dir="${CLAUDE_PROJECT_DIR}/.claude/runtime"
seen_dir="${runtime_dir}/hook-seen"
mkdir -p "$seen_dir"
# mkdir is atomic on a local filesystem: retries for the same tool use do not log twice.
mkdir "${seen_dir}/${tool_use_id}" 2>/dev/null || exit 0
jq -cn \
--arg time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg id "$tool_use_id" \
--arg tool "$tool_name" \
--arg policy "hooks-v1" \
'{time: $time, event: "PostToolUse", tool_use_id: $id, tool: $tool, policy: $policy}' \
>> "${runtime_dir}/tool-audit.jsonl"
O primeiro script escolhe uma semântica de resposta: sai com código zero e escreve JSON estruturado. Isso permite deny e ask. Também seria possível sair com código 2 para bloquear um PreToolUse, mas não se deve misturar essa saída com JSON: Claude Code ignora JSON quando o hook sai com código 2.1
O segundo script não anuncia uma garantia de entrega. Ele usa tool_use_id como chave de deduplicação e mkdir como operação atômica local; se o ID não vier, não inventa um hash de prompt ou comando. O diretório .claude/runtime/ deve ser ignorado pelo Git e ter retenção definida. Em produção, substitua esse arquivo por um coletor autorizado, com acesso restrito, rotação e deduplicação também no destino.
Teste o contrato antes de ativar em um time:
printf '%s' '{"tool_name":"Bash","tool_input":{"command":"git push --force origin main"}}' \
| .claude/hooks/guard-bash.sh | jq .
printf '%s' '{"tool_name":"Bash","tool_input":{"command":"pnpm test"}}' \
| .claude/hooks/guard-bash.sh
O primeiro caso deve devolver permissionDecision: "deny"; o segundo não deve escrever nada e deve sair com sucesso. Adicione casos para comandos compostos, aliases, paths esperados e um stdin inválido. Depois abra /hooks para confirmar que o Claude Code carregou a configuração; os detalhes de execução também podem ser gravados com claude --debug-file <caminho>.1
| Decisão | Escolha conservadora | Quando aceitar mais autonomia | Evidência para revisar |
|---|---|---|---|
| Ação remota | ask ou deny | ação reversível, escopo pequeno e owner definido | aprovação, ID da mudança, rollback |
| Logging | metadados mínimos locais | coletor central com acesso e retenção aprovados | amostra sem segredo, política de retenção |
| Falha do hook | falhar fechado para bloqueios críticos | falhar aberto somente para telemetria não crítica | teste de timeout e indisponibilidade |
| Regex/padrões | lista curta de comandos proibidos | parser ou política central após medir escapes | corpus de comandos reais e falsos positivos |
| Pós-tool | verificar e registrar | side effect remoto idempotente | chave de dedupe e teste de retry |
O “fail closed” merece cuidado. Em PreToolUse, falhar fechado protege uma ação crítica, mas um jq ausente pode paralisar trabalho legítimo. A solução não é esconder o erro: é declarar a dependência, testá-la no setup e escolher uma política por classe de risco. Telemetria pode falhar aberta; um bloqueio de produção provavelmente não deveria.
Também evite usar o hook como filtro de prompt injection. Dados vindos de uma tool ou de um MCP podem tentar influenciar o agente, mas um regex sobre texto não é uma defesa geral contra instruções adversariais. Reduza tools e permissões, trate conteúdo externo como não confiável, separe credenciais e mantenha ações de alto impacto sob aprovação. A própria documentação de MCP recomenda cautela com servidores e conteúdo de terceiros.2
Antes de chamar um hook de “produção”, responda estas perguntas sem abstração:
Permissões, hooks e CI precisam concordar. Um hook que permite uma ação que a CI bloqueia cria frustração; um hook que bloqueia tudo e faz a equipe desativá-lo cria uma falsa sensação de segurança. Use a telemetria mínima para calibrar padrões. Se as pessoas pedem exceção todos os dias, a regra está mal recortada ou o workflow precisa de uma rota legítima.
Um teste unitário que alimenta JSON no shell é necessário, mas não suficiente. A configuração pode estar no escopo errado, o matcher pode não corresponder ao nome real da tool, uma regra de permissão pode mudar o resultado ou um hook concorrente pode decidir diferente. Exercite o fluxo em uma cópia segura do repositório: inicie uma sessão, invoque uma ação permitida, uma que pede aprovação e uma que deve ser bloqueada. Confirme na interface que a decisão aparece como esperado e consulte o arquivo de debug apenas em ambiente sem dados sensíveis.
Para regras que dependem de mais de uma tool chamada em paralelo, PostToolBatch pode ser um ponto melhor do que vários PostToolUse: ele roda uma vez após a resolução do lote, antes da próxima chamada ao modelo. Isso reduz mensagens repetidas, mas continua não sendo uma transação distribuída. Se a correção depende de consistência remota, a fonte de verdade precisa deduplicar e validar de novo no destino.3
matcher limita o hook à tool e ao escopo necessários?stdout contém somente JSON de protocolo quando há decisão estruturada?deny, ask e observação pós-execução?Hooks não tornam um agente confiável por si só. Eles tornam algumas promessas operacionais executáveis: bloquear uma classe pequena de comando, exigir uma aprovação, injetar contexto de verificação ou registrar um evento sem reter conteúdo perigoso.
O custo é coordenação. Cada hook adiciona um contrato, uma dependência, uma latência e alguém responsável por corrigir um falso positivo às 18h de sexta-feira. Por isso, o sucesso não é o número de automações instaladas. É conseguir demonstrar que uma regra importante passou a ser aplicada no ponto certo, com efeito reversível, logs seguros e menos incidentes ou retrabalho.
Comece por um PreToolUse que resolve uma fronteira real. Meça. Teste as negações e exceções. Só depois avance para context injection, integrações remotas e autonomia. Em sistemas agentic, o guardrail mais valioso raramente é o mais inteligente; é o que ainda funciona quando o contexto está confuso e a ação precisa acontecer agora.
Claude Code Docs, Automate workflows with hooks — documentação consultada em 12 de agosto de 2026. ↩ ↩2
Claude Code Docs, Connect Claude Code to tools via MCP — documentação consultada em 12 de agosto de 2026. ↩
Claude Code Docs, Hooks reference — documentação consultada em 12 de agosto de 2026. ↩