Sebelum menyerahkan kunci ke AI. 5 langkah keamanan "anti-celaka" yang wajib dipegang pemula
Pengantar super dasar sebelum menyerahkan kunci ke AI: setelan minimal cegah kebocoran API key, command berbahaya, dan hapus produksi.
“Tolong rapikan sekilas proyek ini ya.”
Saya mengetik itu dengan santai, lalu pergi menyeduh kopi. Begitu kembali, terminal berhenti satu langkah sebelum menjalankan rm -rf. Jari saya nyaris terulur ke tombol persetujuan secara tak sadar.
Kalau waktu itu saya menekan “ya”, .env dan file konfigurasi akan terhapus sekaligus.
Claude Code itu pintar. Tapi pintar dan aman itu dua hal yang sama sekali berbeda. Malah, justru karena pintar dan gesit, ia berlari sekencang-kencangnya ke arah yang salah. Sama seperti pisau yang makin tajam makin gampang melukai sebelum kamu menguasai cara memegangnya.
Artikel ini saya batasi cuma ke langkah keamanan yang pertama wajib dipegang pemula. Hal rumit nanti dulu. Lima yang wajib dijaga, saya tulis santai bareng kegagalan saya.
Memangnya, apa sih yang begitu berbahaya?
Editor teks biasa cuma menampilkan huruf. Tapi Claude Code beda. Ia alat yang “bisa melakukan” hal-hal berikut di dalam komputermu.
- Membaca, menulis, menghapus file
- Menjalankan command terminal (
rmpun bisa) - Mengakses internet, lalu mem-posting ke layanan luar
Lebih dari itu, semua ini jalan begitu kamu menyetujui dengan “ya”. Masalahnya, setelah menekan tombol persetujuan puluhan kali, kamu berhenti melihat isinya. Begitu terbawa irama “ya, ya, OK”, operasi berbahaya menyelinap lolos.
Karena itu, keamanan bukan soal “berhati-hati”. Ini soal membuat lebih dulu mekanisme yang tidak celaka meski kamu tidak berhati-hati. Mari kita lihat satu per satu.
Situasi yang bikin jantung berhenti (3 contoh)
Tiga “situasi berbahaya” yang sering dilakukan pemula. Tidak ada yang istimewa.
Situasi 1: Ingin error dibetulkan, lalu tempel seluruh log
Saat meminta “betulkan error ini”, kamu copas semua huruf yang muncul di terminal, kan? Tapi di dalam log itu kadang terselip baris macam DATABASE_URL=postgresql://user:password_asli@.... Niatnya menyerahkan ke AI, ternyata di riwayat percakapan maupun di log, password mentah ikut tertinggal.
Situasi 2: Membiarkannya dalam mode “serahkan semua”
Karena malas menyetujui, kamu setel ke mode yang bisa menjalankan apa saja tanpa konfirmasi, lalu meninggalkan meja. AI dengan niat baik mengetik git push --force, dan pekerjaan seseorang di tim lenyap tertiup. Niat jahatnya nol. Tapi hasilnya paling buruk.
Situasi 3: Salah ambil DB yang namanya mirip
myapp_dev dan myapp_prod. Beda satu huruf. Kalau cuma minta “hapus data lama di DB” dan AI tidak memastikan ia tersambung ke yang mana—yang terhapus bisa jadi data pelanggan di produksi.
Persamaan ketiganya adalah begitu manusia “lengah” sesaat, AI menjalankannya dengan sekuat tenaga. Kalau begitu, buat saja supaya lengah pun tetap aman. Itulah langkah pencegahannya.
Tiga kesalahan yang pernah saya bikin
Saya menulis dengan sok tahu, padahal saya pun di awal penuh kecelakaan. Jujur, saya akui tiga.
Pertama. Saat membuat auto-posting ke Qiita, saya tempel token langsung ke prompt. “Pakai QIITA_TOKEN=xxxx untuk posting”, begitu. Karena jalan, saya puas, tapi belakangan baru sadar. String itu tertinggal di log percakapan, juga di riwayat AI kecil yang jalan di belakang (subagent). Buru-buru saya buat ulang token-nya. Mengingatnya sekarang bikin keringat dingin.
Kedua. Demi investigasi, saya minta “cek isi .env”. AI dengan patuh membacakannya semua. API key maupun password DB, semuanya ke layar dan ke log. Begitu disuruh membacanya, saat itu juga itu sama dengan “sudah bocor”. .env itu, bahkan saya manusianya pun biasanya tidak membukanya.
Ketiga. Setelan longgar proyek hobi, saya salin ke repository kerja. Akibatnya, “larangan menulis ke produksi” yang seharusnya ada di sisi kerja, tertimpa oleh kelonggaran versi hobi. Saya sadar sebelum kecelakaan, tapi menggunakan ulang setelan itu benar-benar berbahaya.
Semuanya, lebih karena tidak menghentikan lewat mekanisme ketimbang kurang pengetahuan. Mulai sini intinya.
Yang dijaga cuma 5 ini. Kerjakan berurutan saja
Langkah 1: Taruh API key “di luar kode”
Ini yang paling penting. API key dan token, jangan pernah ditulis langsung ke kode atau prompt. Isolasi ke file khusus bernama .env, lalu keluarkan ia dari pengelolaan Git. Cuma dengan ini, sebagian besar kebocoran tercegah.
Pertama, dari contoh yang tidak boleh dilakukan.
// SALAH: ditulis langsung di kode sumber (begitu di-commit, langsung tamat)
const client = new Anthropic({ apiKey: "tempel API key asli langsung" });
// SALAH: dicampur ke prompt
// "Pakai QIITA_TOKEN=token_asli untuk posting" ← ini yang saya lakukan
Yang benar, kumpulkan kunci ke file bernama .env.
# .env (file ini jangan diunggah ke Git. taruh cuma di komputermu sendiri)
ANTHROPIC_API_KEY=isi nilai asli di sini
QIITA_TOKEN=isi nilai asli di sini
DATABASE_URL=postgresql://...
Lalu, deklarasikan agar .env itu “tidak pernah dipungut Git”. Ini tali pengamannya.
# Wajib ditulis di .gitignore (asuransi agar tak sengaja meng-commit kunci)
.env
.env.*
!.env.example # contoh saja boleh dibagikan
*.pem
*.key
*-service-account.json # kunci service account cloud jangan lupa juga
Saat cuma ingin memberi tahu tim “kunci apa saja yang diperlukan”, taruh contoh dengan nilai dikosongkan.
# .env.example (ini boleh diunggah ke Git. isinya kosong)
ANTHROPIC_API_KEY=
QIITA_TOKEN=
DATABASE_URL=
Dari kode, jangan tulis nilai filenya langsung, tapi baca sebagai “variabel lingkungan”. Wujud asli kunci tidak muncul di mana pun dalam kode.
// BENAR: baca dari variabel lingkungan. nilai tidak ditulis sama sekali di kode
import { config } from "dotenv";
config();
const token = process.env.QIITA_TOKEN;
if (!token) {
// Kalau kunci tidak ada, sampaikan bukan nilainya, tapi cuma "kamu lupa menyetelnya"
throw new Error("QIITA_TOKEN belum disetel. Cek file .env.");
}
Poinnya cuma satu. Wujud asli kunci hanya boleh disentuh di dalam .env. Buat kode, prompt, maupun log cuma tahu “nama” kuncinya saja. Inilah dasar dari segala dasar.
Langkah 2: Jangan biarkan command berbahaya “disetujui otomatis”
Berikutnya, command yang tidak bisa diralat macam rm -rf (hapus borongan) atau git push --force (menimpa pekerjaan tim). Ini disetel ke “wajib tanya manusia sebelum dijalankan” atau “memang tidak bisa dijalankan”.
Claude Code punya mekanisme untuk menentukan “OK / perlu konfirmasi / dilarang” per command. Tulis begini di .claude/settings.json.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"defaultMode": "default",
"allow": [
"Read(**)",
"Glob(**)",
"Grep(**)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(curl * | bash)"
],
"ask": [
"Write(**)",
"Edit(**)",
"Bash(git commit*)",
"Bash(git push*)"
]
}
}
Cara membacanya sederhana. Cukup pilah ke 3 kotak.
| Kotak | Arti | Yang dimasukkan |
|---|---|---|
allow | Jalankan tanpa konfirmasi | Operasi aman yang cuma membaca |
ask | Selalu tanya baik-baik | Menulis, commit, push |
deny | Sama sekali tidak diizinkan | Hapus, force push, DB produksi |
Kalau bingung, ingat begini. Cuma membaca allow, kalau menulis ask, kalau menghapus deny. Di awal sempitkan ketat-ketat, lalu hanya operasi yang sudah kamu pahami “ah, ini aman” yang nanti dinaikkan ke ask atau allow. Arah sebaliknya (awalnya longgar, lalu diperketat) baru terjadi setelah kecelakaan, jadi wajib mulai dari arah memperketat.
Langkah 3: Persempit “jangkauan” baca-tulis
Lihat baik-baik deny di langkah 2. Di bagian atasnya ada baris seperti ini.
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
Ini setelan “.env dan folder secrets bahkan membacanya pun dilarang”. Kecelakaan “menyuruh membaca .env” yang saya lakukan, tidak akan terjadi kalau ada satu baris ini. Sebab meski diminta “cek isinya”, ia ditolak di depan pintu.
Mempersempit jangkauan artinya menarik garis lebih dulu: tempat mana yang boleh ditunjukkan, dan tempat mana yang haram ditunjukkan. Folder berisi kunci, setelan produksi, data pelanggan. Kalau dibuat “memang tidak bisa disentuh”, maka tak sengaja meminta pun tetap aman.
Tambahan, file yang sama sekali tidak ingin diedit, kalau ditulis juga dalam Bahasa Indonesia di aturan proyek (CLAUDE.md), jadi lebih tenang.
## File terlarang diedit (tulis di CLAUDE.md)
Berikut sama sekali jangan diedit. Kalau perlu, wajib konfirmasi ke saya (manusia).
- .env (berisi kunci dan password)
- wrangler.toml (setelan publikasi produksi)
- .github/workflows/*.yml (setelan auto-deploy)
Blokir secara mekanis lewat file setelan, sampaikan maksud ke AI lewat kalimat aturan. Disusun dua lapis seperti ini, kebocoran berkurang.
Langkah 4: Jangan keluarkan informasi rahasia ke log
Ini lebih ke kebiasaan menulis ketimbang setelan. Saat menulis pesan error, jangan keluarkan “nilai” kunci sekaligus.
// SALAH: API key muncul apa adanya di log error
throw new Error(`Autentikasi gagal: token=${process.env.TOKEN}`);
// BENAR: jangan keluarkan nilainya, cuma sampaikan di mana harus dilihat
throw new Error("Autentikasi gagal: cek variabel lingkungan TOKEN");
Cuma beda satu baris, tapi yang atas membocorkan kunci begitu log ditunjukkan ke seseorang.
Satu lagi. Saat menyerahkan log ke AI, jangan tempel mentah-mentah. Baris kunci atau password, ganti nilainya jadi sensor dulu baru diserahkan.
# Ubah dulu seperti ini baru diserahkan. AI cukup paham strukturnya "ada info koneksi DB"
DATABASE_URL=***sudah disensor***
QIITA_TOKEN=***sudah disensor***
“Yang boleh diserahkan” dan “yang tidak boleh”, saya kasar-kasarkan ke tabel. Tempel ini ke CLAUDE.md, maka tiap kali meminta, kamu teringat patokan penilaiannya.
| Boleh diserahkan | Tidak boleh diserahkan |
|---|---|
| Jenis error, langkah reproduksi, nama file | API key, password, cookie sesi |
.env.example, “nama” item setelan | URL DB produksi, data pelanggan |
| Log yang sudah diganti sensor | Token asli, file .json service account |
Langkah 5: Perlakukan barang produksi secara “terpisah”
Terakhir. Pisahkan dengan jelas yang untuk latihan (pengembangan) dan yang produksi. Untuk mencegah tertukarnya myapp_dev dan myapp_prod, ampuh untuk memberi satu langkah repot pada penulisan ke produksi.
// scripts/db-query.mjs
const env = process.env.NODE_ENV ?? "development";
// Kalau mencoba menulis ke produksi, hentikan kecuali ada flag khusus
if (env === "production" && process.argv.includes("--write")) {
console.error("Menulis ke produksi butuh flag --force-production.");
process.exit(1);
}
“Tak sengaja kena produksi” diblokir secara fisik lewat satu langkah repot bernama flag. Kerepotan inilah tali pengamannya. Data produksi, kalau dihapus, tidak kembali.
Kalau mau mulai, mulailah dari sini (langkahnya)
Tidak perlu mengerjakan kelimanya hari ini. Kalau berurutan, selesai dalam 30 menit.
- Buat
.envdi proyek, pindahkan semua kunci ke sana - Tambahkan
.envke.gitignore(Langkah 1) - Buat
.claude/settings.json, masukkanrm -rfdan pembacaan.envkedeny(Langkah 2 & 3) - Masukkan jenis menulis dan commit ke
ask(Langkah 2) - Tempel tabel “boleh/tidak diserahkan” dan file terlarang diedit ke
CLAUDE.md(Langkah 4)
Cukup 3 langkah pertama saja, kecelakaan rm -rf dan kebocoran .env di awal tadi sudah terhenti. Jangan kejar kesempurnaan, satu dulu. Itu sudah cukup jadi kemajuan.
Kalau sudah ingin menggarap setelan izin lebih detail, baca Panduan setelan izin Claude Code. Kalau ingin tahu cerita gamblang kecelakaan yang benar-benar terjadi, baca Kasus kegagalan keamanan Claude Code. Untuk spesifikasi akurat setelan, dokumentasi resmi selalu yang terbaik.
Hasil setelah saya coba sendiri
Sejak momen jantung berhenti rm -rf di awal, saya berhenti galau soal “percaya atau tidak ke AI”. Yang saya lihat sekarang adalah di penjaga pintu mana ia berhenti.
Setelah menambah pembacaan .env ke deny, meski diminta “cek variabel lingkungan”, AI dengan patuh mundur. “Bacakan semuanya” yang bikin canggung itu, tidak pernah terjadi lagi.
Jujur, di hari saya menulis setelannya, saya pikir “kayaknya berlebihan nih”. Tapi ternyata kebalikannya. Justru karena ada penjaga, saya bisa santai bermalas-malasan. Saya bisa menekan tombol persetujuan dengan ringan, karena tahu operasi berbahaya sudah lebih dulu dihentikan oleh deny. Daripada berjuang menguasai AI yang pintar, lebih baik lebih dulu menggelar lantai yang tidak melukai saat terjatuh. Inilah yang paling santai dan cepat—begitu kesimpulan saya sekarang.
Penutup
Yang pertama wajib dipegang pemula, cukup 5 ini saja.
| Yang dijaga | Caranya |
|---|---|
| Jangan bocorkan API key | Isolasi ke .env + .gitignore |
| Jangan biarkan command berbahaya mengamuk | rm -rf / force push ke deny |
| Persempit jangkauan baca-tulis | .env/secrets ke deny, file produksi terlarang diedit |
| Jangan keluarkan rahasia ke log | Jangan keluarkan nilai, serahkan dengan sensor |
| Perlakukan produksi secara terpisah | Blokir penulisan produksi lewat flag |
Begitu dengar keamanan kamu jadi tegang, padahal yang dikerjakan cuma “membuat lebih dulu mekanisme yang tidak celaka”. Sekali dipasang, sisanya ia menjaga sendiri meski dibiarkan. Hari ini 30 menit. Dengan itu, satu kecelakaan besar di masa depan bisa kamu hapus.
Kalau galau “di tim kami, sampai mana harus diikat?”, saya juga menyediakan materi dan dukungan. Intip dulu daftar materi.
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
Cara Menulis Instruksi agar Claude Code Hanya Mengubah Satu File
Dari kegagalan 'bikin lebih bagus' yang mengubah 40 baris: template brief Claude Code yang menyatukan scope, verifikasi, dan rollback.
Pulih dari permission denial Claude Code tanpa melemahkan guardrail
Ubah command Claude Code yang ditolak menjadi recovery prompt dengan alasan, alternatif aman, proof command, dan kriteria retry.
Claude Code Harness Smoke Test: loop bukti 15 menit sebelum mempercayai agen
Pemeriksaan Claude Code untuk scope, area terlarang, command bukti, URL publik, dan CTA pendapatan.