Tips & Tricks (Diperbarui: 3/6/2026)

Insiden produksi Claude Code: deteksi, rollback, RCA, dan pencegahan

Panduan insiden Claude Code: kebocoran rahasia, salah hapus, basis data, biaya, rollback, RCA, dan pencegahan.

Insiden produksi Claude Code: deteksi, rollback, RCA, dan pencegahan

Claude Code mempercepat pekerjaan karena dapat membaca berkas, mengubah kode, dan menjalankan perintah. Di repositori produksi, kecepatan itu juga mengubah risiko: satu persetujuan yang terlalu cepat dapat membocorkan rahasia, menghapus berkas, menimpa main, menjalankan migrasi basis data yang berbahaya, atau menaikkan panggilan API.

Artikel ini bukan laporan insiden rahasia dari perusahaan tertentu. Isinya adalah skenario gabungan dari latihan ClaudeCodeLab, tinjauan repositori, dan operasi konten. Waktu serta angka hanya contoh, tetapi polanya cukup nyata untuk dilatih sebelum kejadian sebenarnya.

Insiden adalah peristiwa yang memengaruhi pengguna, data, keamanan, biaya, atau ketersediaan. Penahanan berarti menghentikan kerusakan agar tidak meluas. RCA adalah analisis akar masalah. Rollback berarti kembali ke versi aman terakhir.

Untuk sintaks terbaru, lihat dokumentasi resmi Claude Code settings dan hooks guide. Di sini kita susun menjadi alur: deteksi, tahan, diagnosis, rollback, komunikasi, postmortem, dan pencegahan.

Alur respons insiden

TahapTujuanYang diminta ke Claude Code
DeteksiMemahami perubahan dan dampakRingkas alert, log, diff, deploy, dan perintah terbaru
PenahananMenghentikan kerusakanUsulkan pencabutan kunci, jeda job, flag OFF, atau endpoint dimatikan
DiagnosisMempersempit penyebab langsungBandingkan deploy sehat terakhir dengan perubahan gagal
RollbackKembali ke kondisi amanDaftar target versi, risiko data, dan perintah verifikasi
KomunikasiMenyamakan pemahaman timTulis status, dampak, pembaruan berikutnya, dan pemilik
PostmortemMengubah kegagalan menjadi pelajaranIsi RCA, garis waktu, celah deteksi, dan tindakan
PencegahanMembuat pengulangan lebih sulitTambahkan permission, hooks, CI, alert, dan review gate

Untuk rahasia, tagihan, data pribadi, dan penulisan basis data, tahan dulu lalu selidiki.

Tujuh pola konkret

PolaYang terjadiLangkah pertamaKesalahan umum
Kebocoran rahasia.env, log, atau tangkapan layar memuat API keyCabut, rotasi, periksa logMembersihkan git tetapi lupa log CI
Hapus berbahayarm -rf menghapus berkas pentingHentikan kerja, cek cadangan, daftar berkas tak terlacakgit checkout . tidak memulihkan berkas tak terlacak
Force pushmain menimpa commit timHentikan push, cek reflog, buat branch pemulihanMencampur --force-with-lease dan --force
Migrasi basis dataDrop, update massal, atau lock merusak produksiJeda penulisan, simpan status, pulihkan amanSQL belum diuji dijalankan di produksi
API retry tanpa batasKegagalan menaikkan biayaMatikan proses, jeda antrean, cek batas”Retry” berubah menjadi loop tak terbatas
Dependensi rusakDeploy menghasilkan 503Aktifkan deploy sebelumnya, cek lockfilenpm update menaikkan major version
Autentikasi hilangEndpoint admin terbukaMatikan endpoint, periksa access logKata “admin” tidak menjadi syarat auth

Tiga contoh insiden

Kebocoran API key dapat terdeteksi lewat GitHub secret scanning, alert cloud, atau halaman tagihan. Tindakan pertama adalah mencabut kunci. Setelah itu baru periksa repositori publik, PR, log CI, chat, dan monitoring.

git status --short
git diff --cached --name-only
git log --all -- .env .env.local
git grep -n "sk-" -- ':!node_modules' ':!dist'

Pada kegagalan migrasi basis data, hentikan penulisan sebelum menjelaskan penyebab. Kode bisa rollback cepat, tetapi data yang terhapus memerlukan cadangan, WAL, audit log, atau sinkronisasi ulang.

psql "$DATABASE_URL" -c "select now();"
psql "$DATABASE_URL" -c "\d users"
pg_dump "$DATABASE_URL" --schema-only > schema_before_repair.sql

Untuk retry API, pasang batas keras di batch. Simpan sebagai 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("pakai: node incident-budget-runner.mjs <perintah> [...argumen]");
  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(`dihentikan: perkiraan biaya ${estimatedCost} sen`);
    process.exit(1);
  }
  const delayMs = Math.min(1000 * 2 ** (attempt - 1), 10_000);
  await new Promise((resolve) => setTimeout(resolve, delayMs));
}

console.error(`gagal setelah ${maxAttempts} percobaan`);
process.exit(1);

Guardrail 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 "Perintah berbahaya diblokir: $command" >&2
  exit 2
fi

exit 0

Template komunikasi dan postmortem

## Pembaruan insiden
- Status: investigasi / tertahan / validasi pemulihan
- Dampak: fitur, pengguna, waktu mulai
- Aksi saat ini: job dihentikan, deploy rollback, log diperiksa
- Pembaruan berikutnya: YYYY-MM-DD HH:mm
- Pemilik:
# Postmortem: [judul]

## Ringkasan
- Mulai:
- Terdeteksi:
- Pulih:
- Dampak:
- Tingkat: P0/P1/P2/P3

## Garis waktu
| Waktu | Peristiwa |
| --- | --- |
| HH:mm | |

## Penyebab
- Penyebab langsung:
- Akar masalah:
- Mengapa deteksi terlambat:

## Pencegahan
| Aksi | Pemilik | Tenggat |
| --- | --- | --- |
| | | |

Referensi eksternal yang baik adalah Postmortem Culture dari Google SRE.

Bacaan dan CTA

Baca juga praktik keamanan Claude Code, panduan permission, panduan biaya API, dan alur bukti verifikasi.

Jika bekerja sendiri, mulai dari cheatsheet gratis untuk membiasakan perintah berbahaya dan verifikasi. Untuk template siap pakai, lihat produk ClaudeCodeLab. Untuk tim, pelatihan dan konsultasi Claude Code membantu merapikan CLAUDE.md, permission, hooks, review, dan latihan insiden.

Saat diuji dalam latihan ClaudeCodeLab, perubahan paling berguna adalah menulis penahanan sebelum diagnosis. Memvalidasi JSON, Bash, dan Node sebelum publikasi juga mengurangi kesalahan sederhana. Latihan 20 menit biasanya langsung menunjukkan alert yang hilang, cadangan yang belum diuji, dan permission Claude Code yang terlalu luas.

#claude-code #incident #production #sre #security #postmortem
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.