Permission Budget Claude Code: cek izin, biaya, dan log dalam 5 menit
Loop praktis Claude Code untuk allow/deny rules, batas biaya, log eksekusi, dan handoff tim.
Mengapa perlu dicek lima menit setiap pagi
Pertanyaan operasional saat memakai Claude Code bukan hanya “apakah agent bisa menulis kode?” Pertanyaan yang lebih penting adalah “apa yang boleh ia lakukan tanpa berhenti meminta izin?” Menyetujui setiap command Bash terasa aman pada awalnya, lalu approval fatigue muncul. Mengizinkan semuanya jauh lebih berbahaya: pembacaan .env, install package, git push, deploy produksi, migrasi database, dan perubahan billing bisa masuk ke jalur yang sama.
Permission budget adalah tabel operasi pendek. Isinya: aksi yang boleh dijalankan Claude Code tanpa approval, aksi yang harus bertanya ke manusia, dan aksi yang dilarang di repository tersebut. Loop adalah kebiasaan mengecek tabel itu setiap pagi terhadap log eksekusi dan usage hari sebelumnya. Secara sederhana, ini adalah rutinitas menghitung kunci dan dompet yang sudah diberikan ke agent.
Berdasarkan dokumentasi resmi yang dicek pada 3 Juni 2026, Claude Code memakai rule allow, ask, dan deny; deny punya prioritas di atas ask dan allow. /permissions menampilkan rule aktif dan file settings asalnya. Untuk biaya, /usage berguna sebagai tampilan lokal atau session, sedangkan Claude Console adalah referensi untuk billing dan workspace limits. Simpan link resmi ini: Configure permissions, Claude Code settings, Manage costs effectively, dan CLI reference.
Untuk bacaan internal, hubungkan loop ini dengan Claude Code permissions guide, permission audit checklist, dan permission receipt pattern.
Dasarnya tanpa jargon keamanan
Permission Claude Code ditegakkan oleh CLI, bukan oleh niat baik model. Menulis “jangan baca secrets” di CLAUDE.md tetap berguna sebagai arahan, tetapi itu bukan batas teknis. Rule deny seperti Read(./.env) atau Read(./secrets/**) adalah batas yang bisa ditegakkan Claude Code.
Mode permission juga perlu dipisahkan. default adalah flow approval normal. plan cocok untuk membaca dan investigasi. acceptEdits membuat edit file lebih lancar. dontAsk menolak tool yang tidak pre-approved atau tidak masuk rule ask. bypassPermissions, yang juga tersedia lewat --dangerously-skip-permissions, melewati prompt dan sebaiknya hanya dipakai di container atau VM yang terisolasi.
Biaya juga mengikuti pola yang sama. /usage membantu menemukan session lokal yang tiba-tiba mahal, tetapi billing API harus dikonfirmasi di Claude Console. Untuk run scripted dengan claude -p, --max-budget-usd dan --max-turns berguna sebagai guardrail; keduanya bukan pengganti budget tim.
Daily permission budget loop
Rutinitas ini harus kecil agar dilakukan terus. Tujuannya bukan audit sempurna, melainkan memastikan hari tidak dimulai dengan permission berbahaya yang masih terbuka.
| Langkah | Cek | Syarat lolos |
|---|---|---|
| 1 | /permissions | Tidak ada Bash(*) atau rule terlalu luas seperti Bash(npm *) |
| 2 | .claude/settings.json | secrets, deploy, database, dan billing masuk ask atau deny |
| 3 | /usage dan Console | Spend kemarin punya penjelasan |
| 4 | git diff dan log | Work yang disetujui cocok dengan diff |
| 5 | catatan handoff | Open allowances, blocked actions, dan reviewer berikutnya tertulis |
Prompt awal yang pendek:
Before starting today's Claude Code work, classify the task into:
1. safe to run without approval
2. requires human approval
3. should not run in this session
Then list up to five checks for /permissions, /usage, and git diff.
Starter settings.json bersama
Contoh .claude/settings.json ini bisa menjadi titik awal. defaultMode: "dontAsk" cukup ketat: tool yang tidak diizinkan atau tidak ditandai ask-first tidak akan berjalan. Coba dulu secara lokal sebelum dijadikan default project.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "dontAsk",
"allow": [
"Bash(npm run lint)",
"Bash(npm run test)",
"Bash(npm run test *)",
"Bash(npm run build)",
"Bash(git status)",
"Bash(git diff)",
"Bash(git diff *)",
"WebFetch(domain:code.claude.com)"
],
"ask": [
"Bash(npm install *)",
"Bash(pnpm add *)",
"Bash(git push *)",
"Bash(wrangler deploy *)",
"Bash(vercel deploy *)",
"Bash(terraform apply *)",
"Bash(kubectl apply *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(rm -rf *)"
]
}
}
Yang penting bukan daftar command persisnya, tetapi menjaga safe lane tetap sempit. Bash(npm *) bisa bergeser dari test ke install atau publish. Bash(git *) bisa bergeser dari diff ke push. Read, lint, test, dan build boleh di-allow secara sempit; install, push, deploy, dan apply tetap minta approval manusia.
Simpan budget dan log dalam JSON
Permission hanya separuh loop. Separuh lainnya adalah biaya. Investigasi panjang, test gagal yang diulang, background session, dan log besar bisa menaikkan biaya tanpa terlihat. Simpan budget kecil dan log harian agar review terlihat di pull request.
{
"date": "2026-06-03",
"dailyLimitUsd": 6,
"warnAtUsd": 4,
"usageSource": "/usage plus Claude Console",
"safeAllow": [
"Bash(npm run lint)",
"Bash(npm run test)",
"Bash(git diff *)"
],
"askFirst": [
"Bash(npm install *)",
"Bash(git push *)",
"Bash(wrangler deploy *)"
],
"mustDeny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
],
"handoffRequired": true
}
{
"date": "2026-06-03",
"spentUsd": 1.85,
"usageChecked": true,
"settingsChecked": true,
"permissionsReviewed": [
"/permissions",
".claude/settings.json"
],
"openAllowances": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"handoff": [
"No deploy allowance left open",
"Claude stopped before production data work"
]
}
Simpan sebagai .claude/permission-budget.json dan .claude/daily-claude-log.json. Spreadsheet boleh untuk laporan manajemen, tetapi JSON lebih enak untuk PR review dan automation.
Script audit Node yang bisa langsung dipakai
Simpan file ini sebagai scripts/audit-claude-loop.mjs, lalu jalankan node scripts/audit-claude-loop.mjs. Tidak perlu package eksternal. Script ini mengecek Bash yang terlalu luas, deploy di lane allow, deny .env yang hilang, budget overrun, dan handoff yang kosong.
#!/usr/bin/env node
import fs from "node:fs";
const readJson = (file) => JSON.parse(fs.readFileSync(file, "utf8"));
const budget = readJson(".claude/permission-budget.json");
const log = readJson(".claude/daily-claude-log.json");
const settings = readJson(".claude/settings.json");
const problems = [];
const permissions = settings.permissions ?? {};
const allow = new Set(permissions.allow ?? []);
const ask = new Set(permissions.ask ?? []);
const deny = new Set(permissions.deny ?? []);
const hasPattern = (items, pattern) => [...items].some((item) => pattern.test(item));
if (typeof budget.dailyLimitUsd !== "number" || budget.dailyLimitUsd <= 0) {
problems.push("dailyLimitUsd must be a positive number");
}
if (typeof budget.warnAtUsd !== "number" || budget.warnAtUsd >= budget.dailyLimitUsd) {
problems.push("warnAtUsd must be lower than dailyLimitUsd");
}
if (log.spentUsd > budget.dailyLimitUsd) {
problems.push(`spentUsd ${log.spentUsd} exceeds daily limit ${budget.dailyLimitUsd}`);
}
if (log.spentUsd >= budget.warnAtUsd) {
console.warn(`WARN: spentUsd ${log.spentUsd} has reached warnAtUsd ${budget.warnAtUsd}`);
}
if (!log.usageChecked) problems.push("Run /usage and mark usageChecked true");
if (!log.settingsChecked) problems.push("Review /permissions and mark settingsChecked true");
if (allow.has("Bash") || allow.has("Bash(*)") || hasPattern(allow, /^Bash\(\*.*\)$/)) {
problems.push("Do not allow every Bash command");
}
if (hasPattern(allow, /(deploy|terraform apply|kubectl apply|git push)/)) {
problems.push("Deploy, infrastructure, and push commands must be ask-first, not allow");
}
for (const rule of budget.askFirst ?? []) {
if (!ask.has(rule)) problems.push(`Missing ask rule: ${rule}`);
}
for (const rule of budget.mustDeny ?? []) {
if (!deny.has(rule)) problems.push(`Missing deny rule: ${rule}`);
}
if (!hasPattern(deny, /Read\(.*\.env/)) {
problems.push("Deny rules should block .env reads");
}
if (!Array.isArray(log.handoff) || log.handoff.length === 0) {
problems.push("Add at least one handoff note");
}
if (problems.length) {
console.error(problems.map((problem) => `- ${problem}`).join("\n"));
process.exit(1);
}
console.log("Claude Code daily permission budget check passed.");
Untuk CI, mulai dari mode warning atau manual. Policy yang terlalu keras pada hari pertama sering membuat orang mencari jalan pintas.
Empat use case konkret
Pertama, artikel dan dokumentasi. Markdown, MDX, internal link, CTA, typo fix, dan path gambar biasanya tidak menyentuh secrets atau production. Allow secara sempit file read, git diff, lint, test, dan local build agar Claude Code bisa membuat diff kecil tanpa berhenti terus.
Kedua, perubahan dependency. npm install dan pnpm add memengaruhi lockfile, postinstall, license, vulnerability, dan bundle size. Masukkan ke ask. Saat approval diminta, minta alasan dependency baru, alternatif yang dipertimbangkan, dan rencana removal.
Ketiga, deploy dan migration. wrangler deploy, vercel deploy, terraform apply, kubectl apply, dan database migration mengubah state eksternal. Claude Code boleh menulis command, blast radius, rollback, verification URL, dan monitoring checklist, tetapi eksekusi tetap menunggu manusia.
Keempat, handoff tim. Jika orang lain melanjutkan pekerjaan, tulis open allowances, proof commands, blocked actions, dan remaining budget. Tanpa catatan ini, orang berikutnya akan mengulang investigasi, memakai token lagi, dan membuka permission berisiko yang sama.
Kegagalan yang perlu dihindari
Kegagalan paling umum adalah Bash yang terlalu luas. Bash(npm *) dan Bash(git *) terlihat praktis, tetapi mencampur command read-only dengan command yang mengubah state. Gunakan command spesifik untuk jalur harian.
Kegagalan berikutnya adalah deploy allowance yang lupa ditutup. Saat incident, wrangler deploy * mungkin dipindah dari ask ke allow. Jika masih terbuka besok, pekerjaan fitur biasa punya akses produksi.
Kegagalan ketiga adalah mengabaikan pertumbuhan token dan biaya. Investigasi panjang terasa produktif, tetapi bisa membakar budget. Cek /usage, bandingkan dengan Console ketika billing penting, dan stop session yang tidak lagi berguna.
Terakhir, jangan samakan prompt dengan enforcement. “Jangan baca secrets” adalah arahan. Read(./.env) di deny adalah enforcement. Harness, yaitu kerangka kerja agent, membutuhkan prompt, settings, log, dan review sekaligus.
Produk, training, dan rollout
Untuk latihan sendiri, copy JSON dan script ke repository kecil. Untuk checklist reusable, template CLAUDE.md, dan prompt review, gunakan /products/. Untuk rollout tim yang butuh permissions, cost control, CI policy, reviewer training, dan aturan khusus repository, gunakan /training/.
Catatan praktik (実際に試した結果): peningkatan terbesar bukan datang dari memblokir semua command berisiko. Peningkatan datang dari lima menit mengecek /permissions, /usage, git diff, dan handoff note setiap pagi. Rule allow yang sempit tetap membantu, sementara deploy, billing, dan secrets selalu kembali ke ask atau deny.
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.
Tentang penulis
Masa
Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.
Artikel terkait
Permission safety ladder Claude Code: perluas akses tanpa kehilangan kontrol
Naik dari read-only ke edit terbatas, command bukti, dan cek deploy dengan kontrol yang jelas.
Claude Code Small PR Proof Pack: perubahan kecil yang mudah direview
Paket bukti untuk PR Claude Code: diff, check, URL publik, jalur CTA, dan rollback.
Review gate Claude Code sebelum commit: diff, test, URL publik, dan CTA
Cara memakai Claude Code sebelum commit: diff scope, build, URL publik, link Gumroad, CTA konsultasi, missing test, dan file tidak terkait.