Jam 23.14, aku push satu commit kecil buat benerin integrasi pengirim email di proyek sampingan. Sepuluh menit kemudian, kotak masuk penuh notifikasi dari penyedia layanan emailnya: penggunaan API naik 40x dari rata-rata harian. Bukan aku yang ngirim. Aku baru sadar file test-send.js yang tadi kupakai buat debug cepat—dengan API key ditulis langsung, bukan lewat .env—ikut ter-commit dan nangkring di repo publik selama 19 menit sebelum aku sadar dan revoke.
Sembilan belas menit itu ternyata cukup. Ada bot yang scan commit publik GitHub nyari pola kunci API, dan begitu ketemu langsung dites otomatis buat lihat batas kuotanya.
Momen linknya nyangkut
Ceritanya biasa banget, dan justru itu yang bikin bahaya. Aku lagi ngejar bug di webhook penerima email—payload-nya nggak konsisten di kondisi tertentu—dan pengin cepat verifikasi tanpa muter-muter setup .env di skrip debug terpisah. Jadi aku tempel API key langsung ke variabel di test-send.js, jalanin beberapa kali sampai bug ketemu, terus lupa hapus sebelum git add . dan push. Tidak ada review, tidak ada CI yang jalan buat side project ini—commit langsung ke main karena "cuma proyek kecil".
Yang bikin runtutan ini realistis: aku sudah punya .gitignore buat .env, jadi kepalaku bilang "aman", padahal proteksi itu nggak nyentuh file baru yang secara eksplisit ditambahkan. .gitignore melindungi dari lupa, bukan dari sengaja nulis di tempat yang salah.
Balapan sama bot pemindai
Yang paling bikin sadar skala masalahnya: aku nggak nemuin ini dari GitHub secret scanning (repo publik memang dapat pemindaian otomatis dari beberapa provider yang ikut partner program-nya, tapi providerku waktu itu belum terdaftar di program itu). Aku tahu duluan dari email peringatan anomali pemakaian dari sisi provider API-nya sendiri—yang berarti ada pihak lain yang sudah lebih dulu menemukan dan mencoba pakai kuncinya sebelum aku bahkan sadar filenya kepush.
Urutan yang kutempuh begitu sadar:
- Revoke key dari dashboard provider—prioritas nomor satu, sebelum bersih-bersih apa pun.
- Generate key baru dan update di environment produksi (bukan di file, langsung lewat secret manager platform hosting).
- Cek log pemakaian: sebagian besar hit-nya cuma percobaan cek kuota (permintaan ringan, bukan kirim massal), jadi kerugiannya kecil—tapi kalau itu key dengan scope lebih luas (misalnya akses billing atau database), ceritanya bisa jauh lebih mahal.
- Baru setelah itu bersihin histori git.
Poin empat ini penting dipisah dari poin satu: banyak yang refleksnya langsung git filter-branch atau git push --force buat "menghapus" commit yang bocor. Itu salah urutan. Kunci yang sudah pernah publik harus dianggap terbakar permanen—dihapus dari histori git tidak membatalkan bahwa sudah ada mesin di luar sana yang sempat membacanya dan mungkin sudah menyimpannya di tempat lain. Revoke dulu, baru bersih-bersih histori belakangan buat kerapian, bukan buat keamanan.
Yang berubah di workflow-ku sekarang
Setelah insiden ini aku nggak nambahin proses berat—niatnya tetap proyek sampingan yang harus tetap enak dikerjain sendirian—tapi tiga kebiasaan ini nempel:
- Pre-commit hook sederhana yang nge-grep pola umum API key (panjang string tertentu, prefix seperti
sk-,AIza, dll) sebelum commit diterima. Bukan solusi sempurna, tapi nangkep kasus paling umum: hardcode buat debug cepat yang lupa dicabut. - Semua skrip debug lewat
.env.localyang di-.gitignore, tanpa kecuali "cuma buat sekali doang". Godaan "cuma sekali ini aja" itu justru sumber insidennya. - Key produksi dan key development dipisah scope-nya, jadi kalau salah satu bocor, blast radius-nya kebatasin. Kunci yang bocor kemarin scope-nya kebetulan sempit; kalau nggak, ceritanya beda.
Aku juga akhirnya daftarin repo-repo publik ke secret scanning provider yang tersedia gratis di GitHub buat repo publik—bukan buat gantiin kewaspadaan sendiri, tapi buat jaring kedua kalau kelalaian yang sama kejadian lagi.
Takeaway
.gitignore itu jaring buat lupa, bukan buat kecerobohan yang disengaja—dan garis antara keduanya kadang cuma satu baris kode debug yang kepencet enter. Yang paling nempel dari 19 menit itu bukan soal git, tapi soal urutan respons: revoke dulu baru rapiin histori, karena begitu sesuatu pernah publik, anggap saja sudah dibaca. Kalau proyekmu masih solo dan belum ada CI yang nge-review tiap commit, pre-commit hook kecil buat pola secret itu ongkosnya jauh lebih murah daripada satu insiden pemakaian ilegal yang lolos beberapa jam sebelum kamu sadar.
---
Sumber gambar: Adi Goldstein di Unsplash Sumber gambar: Markus Spiske di Unsplash Sumber gambar: Philipp Katzenberger di Unsplash
The conversation 0
No comments yet. Start the conversation.