Incidentes de produção com Claude Code: detecção, rollback, RCA e prevenção
Guia prático para incidentes com Claude Code: segredos, exclusões, BD, custos, rollback, RCA e prevenção.
Claude Code acelera o trabalho porque consegue ler arquivos, alterar código e executar comandos. Em um repositório de produção, essa velocidade também muda o risco: uma aprovação apressada pode expor um segredo, apagar arquivos, sobrescrever main, rodar uma migração perigosa ou gerar milhares de chamadas de API.
Este artigo não descreve o incidente privado de uma empresa real. Ele reúne cenários compostos de exercícios do ClaudeCodeLab, revisões de repositório e operações de conteúdo. Horários e valores são exemplos, mas os padrões são úteis para treinar antes de uma crise.
Incidente é qualquer evento que afeta usuários, dados, segurança, custo ou disponibilidade. Conter significa impedir que o dano aumente. RCA é análise de causa raiz. Rollback é voltar para a última versão segura.
Confira a sintaxe atual na documentação oficial de Claude Code settings e hooks. Aqui usamos essas peças em um fluxo: detectar, conter, diagnosticar, reverter, comunicar, fazer postmortem e prevenir recorrência.
Fluxo de resposta
| Fase | Objetivo | Pedido útil ao Claude Code |
|---|---|---|
| Detectar | Entender mudança e impacto | Resumir alertas, logs, diff, deploys e comandos recentes |
| Conter | Parar o dano | Sugerir revogação de chave, pausa de job, flag OFF ou endpoint desligado |
| Diagnosticar | Isolar a causa direta | Comparar a última versão saudável com a mudança suspeita |
| Rollback | Voltar ao estado seguro | Listar alvo, risco de dados e comandos de verificação |
| Comunicar | Alinhar as pessoas | Redigir status, impacto, próxima atualização e responsável |
| Postmortem | Transformar falha em aprendizado | Preencher RCA, linha do tempo, detecção perdida e ações |
| Prevenir | Dificultar repetição | Adicionar permissões, hooks, CI, alertas e revisão |
Para segredos, cobrança, dados pessoais e escritas em banco, contenha primeiro e investigue depois.
Sete padrões concretos
| Padrão | O que acontece | Primeiro passo | Falha comum |
|---|---|---|---|
| Vazamento de segredo | .env, logs ou imagens expõem chave | Revogar, rotacionar, revisar logs | Limpar git e esquecer logs de CI |
| Exclusão perigosa | rm -rf remove arquivos necessários | Parar, verificar backup, listar arquivos sem versionamento | git checkout . não restaura arquivos não rastreados |
| Force push | main sobrescreve commits do time | Parar push, verificar reflog, criar branch de recuperação | Confundir --force-with-lease com --force |
| Migração de BD | Drop, update em massa ou lock derruba produção | Pausar escritas, salvar estado, restaurar com cuidado | Rodar SQL não testado em produção |
| API em loop | Retentativas elevam custo | Matar processo, pausar fila, checar limites | ”Retry” vira loop infinito |
| Dependência quebrada | Deploy sobe com 503 | Reativar deploy anterior, revisar lockfile | npm update sobe versão major |
| Auth ausente | Endpoint admin fica público | Desligar endpoint, revisar logs de acesso | ”Admin” não vira requisito de autenticação |
Três casos de incidente
Em vazamento de chave, a detecção pode vir do secret scanning do GitHub, alerta de nuvem ou tela de cobrança. A primeira ação é revogar. Depois, revisar repositório, PR, logs de CI, chat e monitoramento.
git status --short
git diff --cached --name-only
git log --all -- .env .env.local
git grep -n "sk-" -- ':!node_modules' ':!dist'
Em migração de banco, pare escritas antes de explicar. Código volta rápido; dados apagados dependem de backup, WAL, auditoria ou sincronização externa.
psql "$DATABASE_URL" -c "select now();"
psql "$DATABASE_URL" -c "\d users"
pg_dump "$DATABASE_URL" --schema-only > schema_before_repair.sql
Em retentativas de API, coloque limite explícito no batch. Salve como incident-budget-runner.mjs.
#!/usr/bin/env node
import { spawn } from "node:child_process";
const command = process.argv.slice(2);
const maxAttempts = Number(process.env.MAX_ATTEMPTS || 3);
const maxCostCents = Number(process.env.MAX_COST_CENTS || 200);
const costPerAttempt = Number(process.env.COST_PER_ATTEMPT_CENTS || 0);
if (command.length === 0) {
console.error("uso: node incident-budget-runner.mjs <comando> [...args]");
process.exit(2);
}
let estimatedCost = 0;
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
const child = spawn(command[0], command.slice(1), {
stdio: "inherit",
shell: process.platform === "win32"
});
const exitCode = await new Promise((resolve) => {
child.on("exit", (code) => resolve(code ?? 1));
});
estimatedCost += costPerAttempt;
if (exitCode === 0) process.exit(0);
if (estimatedCost >= maxCostCents) {
console.error(`parado: custo estimado ${estimatedCost} centavos`);
process.exit(1);
}
const delayMs = Math.min(1000 * 2 ** (attempt - 1), 10_000);
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
console.error(`falhou após ${maxAttempts} tentativas`);
process.exit(1);
Guardrails para Claude Code
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(git push --force *main*)",
"Bash(git push -f *main*)",
"Bash(rm -rf /*)",
"Bash(rm -rf ~*)"
],
"ask": [
"Bash(git push*)",
"Bash(rm*)",
"Bash(npm install*)",
"Bash(*migrate*)",
"Bash(*deploy*)"
]
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-danger.sh"
}
]
}
]
}
}
#!/usr/bin/env bash
set -euo pipefail
payload="$(cat)"
command="$(node -e 'const fs = require("fs"); const raw = fs.readFileSync(0, "utf8") || "{}"; const json = JSON.parse(raw); console.log(json.tool_input?.command || "");' <<< "$payload")"
blocked='(rm[[:space:]]+-rf[[:space:]]+(/|~)|git[[:space:]]+push[[:space:]].*(-f|--force)([[:space:]]|$)|DROP[[:space:]]+TABLE|TRUNCATE[[:space:]])'
if [[ "$command" =~ $blocked ]]; then
echo "Comando perigoso bloqueado: $command" >&2
exit 2
fi
exit 0
Comunicação e postmortem
## Atualização de incidente
- Status: investigando / contido / validando recuperação
- Impacto: funcionalidade, usuários, início
- Ação atual: job parado, deploy revertido, logs em revisão
- Próxima atualização: YYYY-MM-DD HH:mm
- Responsável:
# Postmortem: [título]
## Resumo
- Início:
- Detecção:
- Resolução:
- Impacto:
- Severidade: P0/P1/P2/P3
## Linha do tempo
| Hora | Evento |
| --- | --- |
| HH:mm | |
## Causa
- Causa direta:
- Causa raiz:
- Por que a detecção atrasou:
## Prevenção
| Ação | Responsável | Prazo |
| --- | --- | --- |
| | | |
A referência externa mais útil é Postmortem Culture do Google SRE.
Leituras e CTA
Leia também boas práticas de segurança, guia de permissões, guia de custos de API e workflow de verificação.
Se você trabalha sozinho, comece pela cheatsheet gratuita. Para modelos reutilizáveis, veja produtos ClaudeCodeLab. Para equipes, treinamento e consultoria Claude Code ajuda a organizar CLAUDE.md, permissões, hooks, revisão e simulados.
Ao testar estes modelos em exercícios do ClaudeCodeLab, a maior melhoria foi escrever a contenção antes do diagnóstico. Validar JSON, Bash e Node antes de publicar também removeu erros simples. Um ensaio de 20 minutos mostra alertas ausentes, backups não testados e permissões amplas demais.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Claude Code Harness Smoke Test: prova de 15 minutos antes de confiar em um agente
Um smoke test para escopo, áreas bloqueadas, comandos de prova, URL pública e CTAs de receita no Claude Code.
Escada de segurança de permissões no Claude Code
Amplie de read-only para edições limitadas, comandos de prova e deploy checks sem perder controle.
Claude Code Small PR Proof Pack: pequenas mudanças fáceis de revisar
Um pacote de prova para PRs do Claude Code: diff, checks, URL pública, CTA e rollback.