"Don't Ask Again" di Claude Code Bocorkan API Key ke GitHub: Cara Cek dan Perbaikinya

Menyetujui perintah dengan "Don't Ask Again" akan menyimpannya apa adanya, termasuk kata sandi. Berikut cara memeriksanya dengan satu perintah untuk repositori Anda, urutan pembersihannya, dan cara menjaga agar kunci tidak ikut tersimpan dalam persetujuan agent.

Ahmed Waheed

Ahmed Waheed

12 November 2026

"Don't Ask Again" di Claude Code Bocorkan API Key ke GitHub: Cara Cek dan Perbaikinya

Apidog untuk Perusahaan

Penerapan On-Premises

SSO & RBAC

Sesuai SOC 2

Jelajahi Apidog Enterprise

Tombol “Don’t Ask Again” (Jangan Tanyakan Lagi) di Claude Code menyimpan perintah persis yang Anda setujui sebagai aturan allow di .claude/settings.local.json. Jika perintah itu mengandung password atau API key, rahasia tersebut kini tersimpan dalam bentuk teks biasa di folder proyek Anda, dan jika file tersebut di-commit, rahasia itu jadi publik. Perusahaan keamanan Apiiro menemukan 1.122 file semacam itu di GitHub publik yang berisi 1.379 secret asli. Berikut cara memeriksa repositori Anda sendiri dengan satu perintah, membersihkannya, dan mencegahnya terjadi lagi.

Apa yang terjadi: temuan Apiiro dalam angka

Apiiro menelusuri GitHub publik mencari salinan .claude/settings.local.json, yaitu file per-proyek tempat Claude Code menyimpan persetujuan izin pribadi Anda. Mereka menemukan 104.185 salinan di 103.617 repositori. Pada 1.122 di antaranya terdapat setidaknya satu secret asli, totalnya 1.379 secret berbeda, menurut tulisan iTnews tentang riset tersebut.

Jenis secret Jumlah
Password database 379
Service-role key Supabase 122
Login SSH untuk server publik 43
Token GitHub, GitLab, dan npm 42
Key AWS 23

Ketika Apiiro memperluas pencarian ke versi git file yang lebih lama, file bersama .claude/settings.json, serta transkrip agen yang tersimpan, jumlahnya naik menjadi 2.539 secret di 1.994 repositori. Apiiro tidak menguji apakah kredensial tersebut masih berfungsi, tetapi satu organisasi yang mereka beri tahu mengonfirmasi bahwa sebuah key masih aktif.

Angka dari scanner adalah bagian yang seharusnya paling mengkhawatirkan Anda. Dari 1.122 file yang berisi secret asli, TruffleHog menandai 643 dan gitleaks menandai 564. 215 file lolos dari keduanya. Jadi, “kami menjalankan secret scanner” bukanlah bukti bahwa Anda bersih.

Kisah ini menduduki puncak Hacker News dengan 582 poin. Boris Cherny, yang memimpin Claude Code di Anthropic, menjawab di utas tersebut bahwa Claude Code secara historis tidak membersihkan secret dan bahwa tim sedang menyelidikinya. Baca riset asli Apiiro.

Bagaimana “Don’t Ask Again” menaruh secret ke dalam file

Ketika Claude Code ingin menjalankan perintah Bash, ia bertanya lebih dulu. Pilih “Yes, and don’t ask again” dan Claude Code menulis persetujuan permanen ke .claude/settings.local.json sebagai aturan allow, seperti yang dijelaskan dalam dokumentasi pengaturan Anthropic. Aturan itu merekam teks perintahnya. Jika perintahnya seperti ini:

psql "postgresql://admin:Sup3rS3cret@db.example.com:5432/prod" -c "select count(*) from users"

maka file pengaturan Anda kini berisi sesuatu seperti ini:

{
  "permissions": {
    "allow": [
      "Bash(psql \"postgresql://admin:Sup3rS3cret@db.example.com:5432/prod\" -c \"select count(*) from users\")"
    ]
  }
}

Password ada di dalam aturan karena ada di dalam perintah. Claude Code menyimpan apa yang Anda setujui, kata per kata.

Diagram alur persetujuan Claude Code dengan password inline yang masuk ke settings.local.json lalu ke repositori GitHub publik

Mengapa file itu berakhir di GitHub

Claude Code berupaya menjaga file ini agar tidak masuk ke git. Saat pertama kali menulis .claude/settings.local.json di repositori yang belum mengabaikannya, ia menambahkan **/.claude/settings.local.json ke file global git excludes Anda. Proteksi itu memiliki celah:

Periksa repositori Anda dengan satu perintah

Mulailah dari repositori tempat Anda berada. Perintah ini memberi tahu Anda apakah file tersebut sedang di-track dan apakah pernah di-commit:

git ls-files | grep -E '(^|/)\.claude/settings(\.local)?\.json$'
git log --all --name-only --format= | grep -E '\.claude/settings(\.local)?\.json$' | sort -u

Jika baris pertama menampilkan apa pun, file itu ada di tree Anda saat ini. Jika baris kedua menampilkan apa pun, file itu ada di history Anda, meskipun Anda sudah menghapusnya.

Untuk memindai semua repositori di bawah satu folder sekaligus:

find ~/code -path '*/.claude/settings.local.json' -exec sh -c \
  'cd "$(dirname "$1")/.." && git ls-files --error-unmatch .claude/settings.local.json >/dev/null 2>&1 && echo "TRACKED: $PWD"' _ {} \;

Untuk sebuah organisasi GitHub, GitHub CLI dapat mencari kode berdasarkan nama file:

gh search code permissions --owner your-org --filename settings.local.json

Lalu periksa isi setiap file yang Anda temukan. Karena scanner melewatkan 19% file yang bocor, baca aturannya sendiri alih-alih percaya pada hasil pemindaian yang “hijau”:

grep -nE 'Bash\(' .claude/settings.local.json | grep -iE 'pass|token|key|secret|://[^/]*:[^@]*@'

Connection string dengan format user:password@, header Authorization: Bearer, -p diikuti password literal, atau apa pun yang diawali sk-, ghp_, AKIA, atau eyJ adalah kredensial. Jalankan gitleaks pada repositori sebagai pemeriksaan kedua, bukan satu-satunya pemeriksaan.

Cara memperbaiki file settings yang bocor

Urutannya penting. Rotasi kredensial harus didahulukan, karena menghapus file tidak berpengaruh apa pun terhadap salinan yang sudah ada di fork, clone, dan cache.

  1. Rotasi setiap kredensial yang pernah ada di file itu. Periksa seluruh history file dengan git log -p --all -- .claude/settings.local.json, buat daftar setiap secret di dalamnya, dan cabut masing-masing di penyedianya. Panduan Apiiro menempatkan langkah ini di urutan pertama.
  2. Berhenti melacak file dan abaikan di repositorinya sendiri:
git rm --cached .claude/settings.local.json
echo '.claude/settings.local.json' >> .gitignore
git add .gitignore && git commit -m "Stop tracking Claude Code local settings"
git check-ignore -v .claude/settings.local.json

Perintah terakhir seharusnya menampilkan baris .gitignore yang cocok. Aturan di dalam repositori melindungi setiap clone.

  1. Bersihkan history jika repositori publik atau dibagikan secara luas. git-filter-repo menghapus file tersebut dari setiap commit:
git filter-repo --invert-paths --path .claude/settings.local.json
git push --force --all

Ini menulis ulang history untuk semua orang, jadi beri tahu tim Anda lebih dulu. Ini juga tidak menjangkau fork, jadi ini adalah pembersihan, bukan pengganti langkah 1.

  1. Bersihkan juga file lokalnya. Buka .claude/settings.local.json, hapus aturan apa pun yang berisi secret literal, dan ganti dengan pola (bagian berikutnya).
  2. Aktifkan push protection. GitHub secret scanning push protection memblokir push yang berisi format secret yang dikenali. Ini tidak menangkap semuanya, seperti yang ditunjukkan oleh 215 file yang terlewat, tetapi menghentikan format token yang umum.

Cegah terulangnya kejadian ini

Solusinya mudah diucapkan: jangan pernah menaruh secret literal dalam perintah yang dijalankan agen Anda, dan setujui pola alih-alih perintah persis.

Perbandingan berdampingan antara aturan allow Claude Code yang berisiko berisi password literal dan aturan aman yang mereferensikan variabel environment

Referensikan secret, jangan diketik. Shell memperluas variabel saat runtime, tetapi aturan allow menyimpan teksnya sebagaimana ditulis. Jadi psql "$DATABASE_URL" menyimpan $DATABASE_URL di aturan, bukan passwordnya:

{
  "permissions": {
    "allow": ["Bash(psql \"$DATABASE_URL\" *)", "Bash(npm run test *)"],
    "deny": ["Read(./.env)", "Read(./.env.*)"]
  }
}

Aturan deny diambil langsung dari dokumentasi pengaturan Anthropic; aturan itu menghentikan Claude Code membaca file .env Anda, sehingga key juga tidak bisa ditempel dari sana ke dalam sebuah perintah.

Jaga aturan tetap sempit. Komentator HN yang mengutip riset tersebut mengatakan 5% dari file mengizinkan perintah shell apa pun dan 43% memuat aturan interpreter seperti Bash(python:*). Aturan seperti itu memungkinkan agen menjalankan apa pun melalui Python, jadi itu adalah aturan izinkan-semua dengan langkah tambahan.

Pertimbangkan auto mode dan sandbox. Cherny merekomendasikan auto mode alih-alih aturan izin yang ditulis manual, dan mengatakan bahwa Anthropic membangun sandbox open-source. Beberapa komentator menunjukkan bahwa auto mode adalah classifier, bukan batas keamanan, jadi padukan dengan kebiasaan di atas.

Jauhkan agen dari secret produksi. Key yang paling aman adalah key yang tidak pernah dilihat agen. Kami membahas pola tersebut di cara membuat agen AI menggunakan API key tanpa melihatnya, dan apa yang dilakukan penyerang dengan AI key yang bocor di AI API key yang dicuri dan LLMjacking.

Buat agen coding Anda memanggil API tanpa mengetik key, menggunakan Apidog CLI

Salah satu cara umum key berakhir di perintah yang disetujui adalah panggilan API singkat: curl -H "Authorization: Bearer sk-..." untuk memeriksa sebuah endpoint. Anda bisa menyerahkan tugas itu ke Apidog CLI. Key tersimpan di variabel environment Apidog, skenario pengujian Anda mereferensikannya sebagai {{API_KEY}}, dan perintah yang dijalankan agen Anda hanya berisi ID proyek, skenario, dan environment. Tidak ada rahasia di dalamnya untuk disimpan.

Atur sekali saja, di terminal Anda sendiri alih-alih melalui agen, sehingga access token Anda tidak pernah melewati proses persetujuan:

npm install -g apidog-cli@latest
apidog auth login
npx -y skills add https://apidog.com   # pick Claude Code when prompted

Lalu beri Claude Code satu prompt:

List the environments in Apidog project 123456, then run test scenario 7890
against the staging environment and summarise any failed assertions.
The API key is stored in that environment as {{API_KEY}}. Never pass a key,
token or password on the command line, and never use --env-var for secrets.

Agen menjalankan perintah seperti ini, yang aman untuk disetujui dengan “Don’t Ask Again”:

apidog environment list --project 123456
apidog run -t 7890 --project 123456 -e <envId> -r cli,json

Dua catatan jujur. Pertama, apidog run menggunakan nilai bersama dari variabel, yang disinkronkan ke Apidog dan terlihat oleh anggota proyek, jadi simpan test key dengan scope terbatas di sana, bukan root key produksi. Jika Anda lebih suka menyimpan nilai di disk, apidog run juga menerima --variables <path>; arahkan ke file di luar repositori. Kedua, flag --env-var "key=value" memang ada untuk meneruskan variabel di baris perintah, dan itulah persis pola yang menyebabkan kebocoran, jadi beri tahu agen Anda untuk tidak menggunakannya untuk secret.

Tim dengan paket Enterprise juga dapat menarik secret dari HashiCorp Vault, Azure Key Vault, atau AWS Secrets Manager dengan Apidog Vault Secrets, dan Enterprise SaaS Secret Scanner menandai key yang disimpan di request, script, dan variabel Apidog. Ini tidak memindai repositori GitHub, jadi tetap lakukan pemeriksaan di atas. Untuk panduan penyiapan lengkapnya, lihat cara menggunakan Apidog CLI di Claude Code dan mengelola environment dan variabel secret di Apidog. Paket Gratis Apidog mencakup hingga 4 pengguna.

button

FAQ

Apakah settings.local.json milik Claude Code di-gitignore secara default?

Sebagian. Ketika Claude Code membuat file ini di repositori git, ia menambahkan **/.claude/settings.local.json ke global git excludes Anda. Itu hanya melindungi mesin Anda, dan tidak berlaku jika Anda membuat file itu secara manual atau memaksanya masuk ke git. Tambahkan juga baris tersebut ke .gitignore milik repositorinya sendiri.

Apakah menghapus file menghilangkan key yang bocor?

Tidak. Key tetap ada di history git, di fork, dan di setiap clone yang dibuat selama masih publik. Rotasi key lebih dulu, lalu berhenti melacak file dan bersihkan history dengan git-filter-repo.

Apakah gitleaks atau TruffleHog menangkap kebocoran ini?

Tidak selalu. Dalam sampel Apiiro, 215 dari 1.122 file dengan secret asli terlewat oleh kedua alat tersebut. Jalankan scanner, lalu baca sendiri aturan Bash(...) di dalam file.

Apakah ini masalah model atau masalah Claude Code?

Apiiro mereproduksinya dengan Opus 5.5 dan Fable 5.1 dan menyebutnya sebagai sifat Claude Code, bukan modelnya. Persetujuan menyimpan teks perintahnya, model apa pun yang menulis perintah itu.

Bagaimana menyetujui perintah dengan aman di Claude Code?

Setujui pola seperti Bash(npm run test *) dan referensikan secret sebagai variabel environment seperti $DATABASE_URL. Tambahkan aturan deny untuk Read(./.env) dan Read(./.env.*).

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.