Home / Claude Code / PermissionDenied Hook: Seu Auto Mode Bloqueia Ações e Você Nem Sabe?

PermissionDenied Hook: Seu Auto Mode Bloqueia Ações e Você Nem Sabe?

Imagina o seguinte cenário: você configurou o Claude Code em auto mode pra rodar uma refatoração longa enquanto faz uma call. Quando volta, o agente está parado. Nada aconteceu nos últimos 40 minutos. O classifier do auto mode bloqueou uma ação que parecia arriscada — mas era perfeitamente segura — e o Claude ficou ali, tentando, sendo bloqueado de novo, até atingir o limite e pausar.

Na minha experiência com 300+ software houses, essa é a reclamação número um de quem adota auto mode: “funciona lindo até parar sem avisar.”

A Anthropic acabou de lançar na versão 2.1.88 um hook que resolve exatamente isso: o PermissionDenied. E se você usa auto mode em qualquer capacidade — seja interativo, pipeline CI/CD ou agent teams — precisa entender o que ele faz.

O que é o PermissionDenied Hook

O PermissionDenied é um novo evento de hook que dispara imediatamente após o classifier do auto mode negar uma tool call. Ele não impede o bloqueio — o classifier já decidiu. Mas ele te dá a chance de reagir: logar o evento, notificar alguém, e até permitir que o modelo tente novamente retornando {retry: true}.

Pra entender o valor, precisa entender o problema que ele resolve.

Como o auto mode decide

O auto mode usa o Claude Sonnet 4.6 como classifier separado. Não é o mesmo modelo que está trabalhando no seu código — é uma instância dedicada que avalia cada tool call antes de executar. Funciona em dois estágios:

  1. Stage 1 — Fast filter: decisão binária (bloquear ou permitir) em um único token. Rápido.
  2. Stage 2 — Chain-of-thought: se o Stage 1 sinaliza risco, o classifier faz raciocínio profundo antes de decidir.

Detalhe crucial: o classifier não vê a resposta do Claude nem os resultados de ferramentas anteriores. Ele vê apenas as mensagens do usuário e as tool calls. Isso é uma proteção contra prompt injection — conteúdo malicioso dentro de arquivos ou páginas web não consegue manipular a decisão do classifier.

As estatísticas reais

A Anthropic publicou os números do classifier com transparência rara:

Métrica Tráfego real (n=10k) Ações overeager reais (n=52) Exfiltração sintética (n=1k)
Stage 1 FPR 8,5% 6,6% FNR 1,8% FNR
Pipeline completo 0,4% FPR 17% FNR 5,7% FNR

Traduzindo: a cada 250 tool calls legítimas, 1 é bloqueada por engano (0,4% de falsos positivos). Parece pouco? Faça a conta numa sessão longa com agent teams rodando 500+ tool calls. São 2 bloqueios falsos. E cada um desses bloqueios pode cascatear.

O efeito cascata sem o hook

Sem o PermissionDenied hook, quando o classifier bloqueia uma ação:

  1. O Claude recebe uma mensagem: “ação negada, encontre um caminho alternativo”
  2. O Claude tenta outra abordagem — que muitas vezes é bloqueada também (mesmo falso positivo, padrão similar)
  3. 3 bloqueios consecutivos OU 20 bloqueios totais na sessão → auto mode pausa completamente
  4. O Claude Code volta a pedir permissão manual pra cada ação
  5. Em modo não-interativo (-p): a sessão é abortada

Esse é o cenário silencioso que destrói pipelines de CI/CD. O agente trava, a pipeline fica hanging, e só descobre quando o timeout mata o processo.

Como funciona na prática

Configuração básica

O PermissionDenied hook se configura como qualquer outro hook no settings.json:

{
  "hooks": {
    "PermissionDenied": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionDenied\",\"retry\":true}}'"
          }
        ]
      }
    ]
  }
}

Esse é o caso mais simples: sempre permite retry. Quando o classifier bloqueia qualquer ação, o hook retorna {retry: true} e o modelo tenta novamente. Útil pra ambientes onde você confia no escopo do trabalho e quer que falsos positivos não interrompam a execução.

Retry seletivo com logging

Na prática, você não quer retry cego. Você quer logar e decidir:

#!/bin/bash
# .claude/hooks/handle-denial.sh

INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
REASON=$(echo "$INPUT" | jq -r '.denial_reason // "unknown"')
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

# Loga pra auditoria
echo "{\"timestamp\":\"$TIMESTAMP\",\"tool\":\"$TOOL_NAME\",\"reason\":\"$REASON\"}" >> ~/.claude/denial-audit.log

# Retry seletivo: permite retry pra git e npm, mas não pra Bash genérico
case "$TOOL_NAME" in
  "Bash")
    COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
    if echo "$COMMAND" | grep -qE "^(git|npm|yarn|pnpm) "; then
      echo '{"hookSpecificOutput":{"hookEventName":"PermissionDenied","retry":true}}'
    else
      echo '{"hookSpecificOutput":{"hookEventName":"PermissionDenied","retry":false}}'
    fi
    ;;
  *)
    echo '{"hookSpecificOutput":{"hookEventName":"PermissionDenied","retry":true}}'
    ;;
esac
{
  "hooks": {
    "PermissionDenied": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/handle-denial.sh"
          }
        ]
      }
    ]
  }
}

Notificação via Slack/webhook

Pra quem roda pipelines autônomas, a combinação com HTTP hooks é natural:

{
  "hooks": {
    "PermissionDenied": [
      {
        "hooks": [
          {
            "type": "http",
            "url": "https://hooks.slack.com/services/T00/B00/xxx",
            "headers": { "Content-Type": "application/json" }
          }
        ]
      }
    ]
  }
}

O endpoint Slack recebe o JSON do evento com tool_name, denial_reason e pode postar no canal da equipe: “⚠️ Auto mode bloqueou git push na sessão abc123 — verificar.”

Por que isso importa para sua Software House

O problema real: auto mode em produção

Toda software house que escala automação com IA enfrenta o mesmo dilema:

  • bypassPermissions é rápido mas perigoso — zero proteção contra prompt injection ou ações destrutivas
  • auto mode é seguro mas pode travar — false positives pausam a execução sem aviso
  • default é seguro mas lento — pede permissão pra tudo

O PermissionDenied hook resolve o “mas” do auto mode. Ele transforma falsos positivos de interrupção silenciosa em eventos observáveis e acionáveis.

Custo operacional de denials não-tratados

Faz a conta:

  • Uma sessão com agent teams faz 500 tool calls
  • 0,4% de FPR = 2 bloqueios falsos por sessão
  • Se 1 desses gera cascata → 3 denials consecutivos → auto mode pausa
  • Pipeline de CI/CD com -p: sessão abortada
  • Tempo do dev pra diagnosticar: 30+ minutos (“por que a pipeline falhou?”)
  • Com o hook: zero downtime — retry automático, log pra auditoria

Se sua SH roda 10 pipelines por dia com auto mode, são potencialmente 20 falsos positivos por dia. Sem observabilidade, você só descobre quando algo quebra.

Completando o ecossistema de hooks

Se você acompanha esta série, o PermissionDenied fecha um gap importante:

Hook O que monitora Artigo
HTTP Hooks Todas as tool calls via webhook v2.1.63
StopFailure Erros de API (rate limit, auth) v2.1.78
Conditional if Filtragem cirúrgica por args v2.1.85
CwdChanged/FileChanged Mudança de diretório e arquivos v2.1.83
PermissionDenied Bloqueios do auto mode classifier v2.1.88

Juntos, esses hooks formam uma camada de observabilidade completa sobre o Claude Code. Você sabe quando uma tool call é executada (PostToolUse), quando falha (PostToolUseFailure/StopFailure), quando o environment muda (CwdChanged/FileChanged), e agora quando o auto mode bloqueia algo (PermissionDenied).

Detalhe técnico: o classifier por dentro

Pra quem quer entender a fundo — porque na minha experiência, donos de SH que entendem a mecânica tomam decisões melhores sobre quando confiar e quando não confiar.

O classifier do auto mode tem uma arquitetura fixa com três slots customizáveis:

  1. Infraestrutura confiável: repos, buckets, serviços internos que o classifier deve considerar seguros
  2. Categorias de bloqueio: ações que sempre devem ser barradas
  3. Exceções: overrides pra casos específicos

As 4 categorias padrão de bloqueio:

  • Destruir ou exfiltrar — deletar dados, enviar info pra endpoints externos
  • Degradar postura de segurança — modificar permissões, desabilitar proteções
  • Cruzar fronteiras de confiança — acessar sistemas que o classifier não reconhece
  • Bypass de review — pular verificações, force push, deploy direto

E aqui está o ponto-chave: o classifier não conhece a infra da sua empresa por padrão. Seus repos internos, buckets S3, serviços — tudo é “externo não-confiável” até você configurar. É por isso que muitos false positives acontecem em SHs: o classifier bloqueia push pro repo da empresa porque não sabe que é confiável.

A solução: configurar autoMode.environment nos managed settings. Mas mesmo com isso, false positives vão acontecer. E é aí que o PermissionDenied hook salva.

O que eu penso

Eu venho acompanhando a evolução dos hooks do Claude Code desde a v2.1.63. Cada release adiciona uma peça no quebra-cabeça da observabilidade. O PermissionDenied era a peça que faltava pra fechar o ciclo do auto mode.

Minha provocação: se você está usando auto mode sem nenhum hook configurado, você está voando cego. É como rodar um servidor em produção sem monitoring. Funciona 99,6% do tempo — mas os 0,4% que não funcionam são exatamente os que precisam de atenção.

O PermissionDenied hook não é sexy. Não é uma feature que vai pra demo no pitch de vendas. Mas é a diferença entre uma automação que funciona e uma automação que funciona e você sabe quando não funciona.

E na minha experiência mentoringando 300+ software houses: saber quando algo não funciona é mais valioso do que fazer funcionar.

Conclusão

O PermissionDenied hook transforma denials silenciosos do auto mode em eventos que você pode interceptar, logar e reagir. Com {retry: true}, falsos positivos viram inconveniências de 1 retry em vez de sessões abortadas. Com logging, você tem auditoria completa de tudo que o classifier bloqueia. Com webhooks, sua equipe é notificada em tempo real.

Se você usa auto mode — ou planeja usar — configure esse hook antes de colocar em pipeline de produção. É 5 minutos de setup que podem economizar horas de diagnóstico.

Se você quer implementar esse nível de automação com IA na sua software house, vem pro nosso próximo evento presencial. É onde a gente destrincha isso na prática, com código rodando ao vivo.

Sou Thulio, mentoro 300+ SHs desde 2016.

Marcado:

Deixe um Comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *