Getting Started (Diperbarui: 3/6/2026)

Checklist audit izin Claude Code: cek allow/deny dan command berisiko dalam 5 menit

Audit allow/deny, command berisiko, environment variable, dan log Claude Code setiap pagi dalam 5 menit.

Checklist audit izin Claude Code: cek allow/deny dan command berisiko dalam 5 menit

Audit izin menentukan apa yang boleh dilakukan Claude Code hari ini

Risiko terbesar tidak selalu muncul saat Anda berkata “boleh lakukan semuanya”. Yang lebih sering terjadi adalah kebiasaan kecil: kemarin Anda mengizinkan Bash(git push *) atau WebFetch yang terlalu luas, lalu hari ini membuka repository produksi dan lupa aturan itu masih aktif.

Artikel ini memberi rutinitas audit pagi selama lima menit. allow berarti tool boleh berjalan tanpa konfirmasi lagi, ask berarti harus meminta persetujuan, dan deny berarti diblokir. Untuk pemula, anggap ini sebagai batas meja kerja yang Anda berikan kepada agent.

Per 3 Juni 2026, dokumentasi resmi menjelaskan bahwa /permissions menampilkan izin tool dan sumber file settings-nya. Aturan dievaluasi dengan urutan deny -> ask -> allow, jadi deny menang. Selalu cek dokumen resmi Claude Code Permissions, Settings, dan Environment variables sebelum menjadikannya kebijakan tim.

Gunakan setelah checklist 30 menit pertama dan sebelum setup tim dengan template CLAUDE.md. Tujuannya bukan birokrasi, tetapi membuat pekerjaan cukup kecil untuk bisa direview.

Alur lima menit

Mulai dari risiko tugas hari ini, bukan dari JSON. Dokumentasi, dependency, form, dan deployment butuh batas yang berbeda.

flowchart TD
  A[Start session] --> B[Check git status]
  B --> C[Open /permissions]
  C --> D[Review allow / ask / deny]
  D --> E[Inspect env and logs policy]
  E --> F[Run local audit script]
  F --> G[Write handoff note]
Tempat dicekYang diperiksaTanda bahaya
git status --shortApakah sudah ada perubahanAda diff tetapi pemiliknya tidak jelas
/permissionsFile mana yang memberi tiap aturanBash, WebFetch, atau Edit penuh di allow
.claude/settings.jsonAturan bersama timDeploy, billing, atau link pembayaran otomatis diizinkan
.claude/settings.local.jsonAturan pribadi sementaraAturan eksplorasi kemarin masih aktif
envRiwayat dan subprocessTim butuh log, tetapi CLAUDE_CODE_SKIP_PROMPT_HISTORY=1

Satu detail resmi penting: Bash saja dalam deny menghapus tool Bash dari konteks Claude. Aturan terarah seperti Bash(rm *) tetap menyisakan tool, tetapi memblokir panggilan yang cocok. Instruksi di CLAUDE.md membantu mengarahkan model, tetapi bukan batas teknis.

Contoh settings minimal untuk repo

Settings bersama lebih mudah dijalankan jika aksi berisiko diblokir lebih dulu dan keputusan manusia tetap berada di ask. Contoh ini bisa menjadi dasar .claude/settings.json.

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(git status *)",
      "Bash(git diff *)",
      "Read(./src/**)",
      "Read(./docs/**)"
    ],
    "ask": [
      "Bash(npm install *)",
      "Bash(pnpm add *)",
      "Bash(git push *)",
      "Bash(npm run deploy *)",
      "Edit(./.github/**)"
    ],
    "deny": [
      "Bash(curl *)",
      "Bash(wget *)",
      "Bash(rm -rf *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)",
      "WebFetch(domain:pastebin.com)"
    ],
    "defaultMode": "default",
    "disableBypassPermissionsMode": "disable"
  },
  "env": {
    "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB": "1"
  }
}

Di sini, “harness” berarti pijakan kerja agent: Claude Code, settings, hooks, sandbox, dan kebijakan log. Bukan soal percaya lebih besar, melainkan memberi ruang kerja yang lebih jelas.

Bash(npm run test *) memakai wildcard. Dokumentasi saat ini juga mengenali :* di akhir seperti Bash(ls:*), tetapi hanya di akhir pola. Untuk tim, bentuk Bash(git push *) lebih mudah dibaca.

Checklist repo yang bisa disalin

Audit jangan dibuat menjadi dokumen keamanan panjang. Tempel blok ini ke PR, issue, atau catatan handoff.

claude_code_permission_audit:
  date: "2026-06-03"
  repository:
    name: "your-repo"
    branch: "feature/your-task"
    dirty_before_start: "yes/no"
  allowed_today:
    - "Read project files"
    - "Edit MDX and test files"
    - "Run npm run lint"
    - "Run npm run test -- --runInBand"
  ask_before:
    - "Install or update packages"
    - "Change auth, billing, analytics, or deploy config"
    - "Push commits or create releases"
  never_allow:
    - "Print .env, tokens, cookies, or private keys"
    - "Run curl/wget for arbitrary URLs"
    - "Delete git history or force-push"
  proof_required:
    - "git diff reviewed"
    - "test or build command captured"
    - "rollback note written"
  owner_handoff:
    reviewer: "name"
    open_questions:
      - "Which production URL should be checked?"

Bagian terpenting adalah allowed_today. Ini bukan izin permanen, hanya set izin terkecil agar tugas hari ini selesai dengan bukti.

Mendeteksi pola izin berbahaya dengan Node

Review manual sering melewatkan Bash penuh atau Bash(npx *) yang tertinggal. Simpan sebagai scripts/audit-claude-permissions.mjs dan jalankan dari root repository.

#!/usr/bin/env node
import fs from "node:fs";
import os from "node:os";
import path from "node:path";

const repo = process.cwd();
const settingsFiles = [
  path.join(os.homedir(), ".claude", "settings.json"),
  path.join(repo, ".claude", "settings.json"),
  path.join(repo, ".claude", "settings.local.json"),
].filter((file) => fs.existsSync(file));

const riskyAllowRules = [
  { pattern: /^Bash$/i, severity: "high", reason: "all Bash commands are auto-allowed" },
  { pattern: /^PowerShell$/i, severity: "high", reason: "all PowerShell commands are auto-allowed" },
  { pattern: /^(Edit|Write)$/i, severity: "high", reason: "all file edits are auto-allowed" },
  { pattern: /^WebFetch$/i, severity: "medium", reason: "all web fetches are auto-allowed" },
  {
    pattern: /^Bash\((curl|wget|nc|ncat|ssh|scp|rsync)\b.*\)$/i,
    severity: "high",
    reason: "network or transfer command is auto-allowed",
  },
  {
    pattern: /^Bash\(.*\b(rm\s+-[^\)]*r|git\s+push|npm\s+install|pnpm\s+add|yarn\s+add|npx|docker\s+exec|devbox\s+run|mise\s+exec|terraform\s+apply|kubectl\s+apply)\b.*\)$/i,
    severity: "high",
    reason: "destructive or environment-changing command is auto-allowed",
  },
  {
    pattern: /^PowerShell\(.*\b(Remove-Item|Invoke-WebRequest|Invoke-RestMethod|Start-Process)\b.*\)$/i,
    severity: "high",
    reason: "risky PowerShell command is auto-allowed",
  },
];

const expectedDenyRules = [
  "Read(./.env)",
  "Read(./.env.*)",
  "Read(./secrets/**)",
  "Bash(curl *)",
  "Bash(wget *)",
];

const findings = [];

function add(file, severity, rule, reason) {
  findings.push({ file: path.relative(repo, file) || file, severity, rule, reason });
}

function readJson(file) {
  try {
    return JSON.parse(fs.readFileSync(file, "utf8"));
  } catch (error) {
    add(file, "high", "JSON", `cannot parse settings: ${error.message}`);
    return null;
  }
}

for (const file of settingsFiles) {
  const settings = readJson(file);
  if (!settings) continue;

  const permissions = settings.permissions ?? {};
  const allow = Array.isArray(permissions.allow) ? permissions.allow : [];
  const ask = Array.isArray(permissions.ask) ? permissions.ask : [];
  const deny = Array.isArray(permissions.deny) ? permissions.deny : [];

  if (permissions.defaultMode === "bypassPermissions") {
    add(file, "high", "permissions.defaultMode", "session starts in bypassPermissions");
  }

  if (permissions.disableBypassPermissionsMode !== "disable") {
    add(file, "medium", "permissions.disableBypassPermissionsMode", "bypass mode is not disabled here");
  }

  if (settings.env?.CLAUDE_CODE_SKIP_PROMPT_HISTORY === "1") {
    add(file, "low", "CLAUDE_CODE_SKIP_PROMPT_HISTORY", "prompt history and transcripts are not written");
  }

  if (settings.env?.CLAUDE_CODE_SUBPROCESS_ENV_SCRUB !== "1") {
    add(file, "low", "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB", "subprocess credential scrubbing is not enabled here");
  }

  for (const rule of allow) {
    for (const risky of riskyAllowRules) {
      if (risky.pattern.test(rule)) add(file, risky.severity, rule, risky.reason);
    }
  }

  for (const required of expectedDenyRules) {
    if (!deny.includes(required)) add(file, "low", required, "consider adding this deny rule");
  }

  if (ask.length === 0) {
    add(file, "low", "permissions.ask", "no ask rules are defined");
  }

  for (const rule of [...allow, ...ask, ...deny]) {
    if (/:\*[^)]/.test(rule)) {
      add(file, "medium", rule, "the :* shorthand only behaves as a wildcard at the end of a pattern");
    }
  }
}

if (settingsFiles.length === 0) {
  console.log("No Claude Code settings files found in user or repo scope.");
} else if (findings.length === 0) {
  console.log("No risky Claude Code permission patterns found.");
} else {
  console.table(findings);
}

if (findings.some((finding) => finding.severity === "high")) {
  process.exitCode = 1;
}

Di PowerShell:

New-Item -ItemType Directory -Force -Path .\scripts | Out-Null
node .\scripts\audit-claude-permissions.mjs

Script ini bukan mesin keamanan lengkap. Ia membuat pintu masuk review. Walaupun Bash(curl *) diblokir, command Bash yang diizinkan masih bisa menjalankan script Node yang membuka jaringan. Untuk batas lebih kuat, gabungkan permission dengan sandbox atau container.

Empat use case konkret

1. Artikel dan dokumentasi

MDX, README, terjemahan, dan screenshot biasanya lebih rendah risikonya. Anda bisa mengizinkan Read(./src/**), Edit(./site/src/content/**), Bash(npm run lint), dan Bash(npm run test *), sementara npm install dan git push tetap di ask.

Jebakannya ada di CTA. Link Gumroad, form kontak, dan URL PDF gratis memengaruhi revenue dan lead, jadi cek URL publik harus masuk definition of done.

2. Update dependency

Dependency mengubah package.json, lockfile, build, dan kadang postur keamanan. Taruh instalasi di ask, lalu minta alasan, command test, dan rollback.

Prompt yang baik: “Batasi menjadi tiga kandidat update dan tampilkan risiko breaking change, command verifikasi, dan rollback dalam tabel.”

3. Auth, billing, dan analytics

Login, Stripe, Gumroad, tag iklan, tujuan email, dan webhook harus lewat persetujuan manusia. Test yang lolos belum cukup. Cek data apa yang dikirim, apakah kegagalan bisa membuat double charge, dan apakah log menyimpan data pribadi.

CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 mencegah histori prompt dan transkrip sesi ditulis ke disk. Ini berguna untuk sesi sensitif sementara, tetapi melemahkan audit tim.

4. Handoff tim

Saat menyerahkan pekerjaan, tinggalkan jejak keputusan. Catatan yang baik menjelaskan apa yang diizinkan, diblokir, sudah dibuktikan, dan masih perlu dicek manusia.

Handoff note:
- Allowed today: Edit content files, run lint, run unit tests.
- Asked before: package changes, deploy, payment links, analytics tags.
- Denied: .env reads, arbitrary curl/wget, recursive delete.
- Evidence: npm run lint passed, git diff reviewed.
- Remaining risk: production URL has not been checked after deploy.

Jebakan umum

Pertama, auto-allow terlalu luas. Bash, PowerShell, Edit, atau WebFetch penuh di allow terlihat efisien, tetapi terlalu banyak bergantung pada ingatan dan review manual.

Kedua, filter URL hanya dengan pola Bash. Bash(curl https://github.com *) rapuh karena opsi, redirect, variabel, dan spasi bisa berubah. Blokir curl dan wget; gunakan WebFetch(domain:example.com) atau hook.

Ketiga, wrapper command. Dokumentasi menjelaskan wrapper bawaan seperti timeout dan time, tetapi runner seperti npx, docker exec, devbox run, dan mise exec perlu hati-hati.

Keempat, Read/Edit deny bukan isolasi OS penuh. Itu berlaku untuk tool bawaan dan command file yang dikenali, bukan untuk script apa pun yang membuka file dari dalam.

Prompt tim untuk giliran pertama

Mulai dengan audit, bukan implementasi.

Before changing files, audit Claude Code permissions for this repository.
Return:
1. allow rules that are safe for today's task
2. ask rules that should stay behind human approval
3. deny rules that protect secrets, deploys, and destructive commands
4. environment variables that affect logs or subprocess secrets
5. the smallest task you can complete with proof and rollback notes
Do not edit files until the audit is summarized.

Prompt ini tidak menegakkan keamanan sendirian. Settings dan UI permissions yang melakukannya. Nilainya adalah membuat batas terlihat sebelum edit pertama.

Lindungi jalur revenue

Untuk situs yang mengarah ke PDF gratis, produk Gumroad, atau konsultasi, audit izin melindungi revenue sekaligus keamanan. Jika alur dasar masih dipelajari, mulai dari cheatsheet gratis. Untuk merapikan CLAUDE.md, permissions, hooks, dan MCP dalam tim, Setup Guide adalah jalur cepat. Untuk adopsi langsung di repository nyata, lihat training dan konsultasi.

Setelah dicoba dalam pekerjaan nyata, rutinitas paling bernilai adalah mengecek git status, /permissions, .claude/settings.local.json, dan script audit sebelum meminta Claude Code mengedit file. Menaruh link Gumroad dan deploy di ask sedikit memperlambat sesi, tetapi mempercepat review karena setiap perubahan yang menyentuh revenue punya alasan persetujuan yang terlihat.

#claude-code #permissions #security #setup #workflow #claude-md
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.