Cara Memberi Rahasia ke AI Coding Agent Tanpa Menaruhnya di Prompt
Sebuah agen butuh kunci Stripe atau kata sandi database untuk menjalankan perintahnya. Anda tempelkan di chat, dan nilai itu mendarat di file transkrip pada disk Anda, di penyedia model, dan kadang di sebuah commit. Aturan yang akhirnya kami pakai setelah tiga kesalahan kami sendiri: sebuah rahasia sampai ke agen lewat variabel lingkungan, dan tidak lewat yang lain.
Situasinya selalu sama. Sebuah agen sedang setengah jalan mengerjakan tugas, lalu ia perlu memanggil Stripe test API Anda, menjalankan migrasi ke database staging, atau push ke registry privat. Ia minta kuncinya. Kuncinya ada di pengelola kata sandi Anda, agennya sedang menunggu, dan hal tercepat di dunia adalah menempelkannya ke chat.
Tempelan itulah saat kunci Anda lepas dari kendali Anda. Bukan karena modelnya jahat, tapi karena sebuah prompt adalah objek yang disimpan dan diteruskan: ia masuk ke file transkrip di disk Anda, ia dikirim ke penyedia model, dan ia disalin oleh setiap percobaan ulang serta setiap subagent yang mewarisi percakapan itu.
Kami membuat AgentsRoom, aplikasi desktop yang menjalankan agen coding, jadi kami harus menyelesaikan masalah ini untuk diri kami sendiri. Kami salah tiga kali pada September 2026. Inilah aturan yang akhirnya kami pakai, tiga kesalahan yang melahirkannya, dan cara menerapkannya entah Anda memakai aplikasi kami atau tidak.
Jawaban singkatnya
- Sebuah rahasia sampai ke agen lewat variabel lingkungan, dan tidak lewat yang lain. Bukan lewat pesan, bukan tiket, bukan skill, bukan opsi baris perintah.
- Agen memakai
$NAME, tidak pernah nilainya. Shell yang mengembangkannya saat perintah dijalankan. - Simpan nilainya sekali saja, di luar repositori, dienkripsi oleh keychain sistem operasi Anda, lalu rujuk lewat namanya di semua tempat lain.
- Rahasia yang sudah lewat sebuah percakapan itu hangus. Rotasi dulu, baru bersih-bersih.
- Penyensoran adalah jaring pengaman, bukan rencana. Ia menangkap yang bentuknya mirip kunci, bukan kata sandi database yang terbaca seperti kata biasa.
Kenapa tempelan itu lebih buruk dari kelihatannya
Tiga hal terjadi sekaligus, dan hanya yang pertama yang terlihat jelas.
Ia dikirim ke penyedia model. Itu bagian yang semua orang lihat. Kunci Anda sekarang ada di dalam body sebuah request di infrastruktur orang lain, di dalam percakapan yang tidak bisa Anda sunting.
Ia mendarat di disk Anda, dalam bentuk teks biasa. Claude Code, Codex, Antigravity CLI, dan yang lainnya menyimpan transkrip percakapan supaya Anda bisa melanjutkannya. File itu duduk di folder home Anda, tanpa enkripsi, selama CLI-nya masih menyimpan riwayat. Coba sekali saja cari string sk- di transkrip Anda dan lihat apa yang muncul.
Ia menyebar ke samping. Percakapan adalah memori agen, jadi apa pun yang menyalin percakapan ikut menyalin kuncinya: sesi yang dilanjutkan, agen yang di-fork, subagent yang dijalankan dengan konteks induknya, ringkasan yang ditulis ke sebuah file proyek. Kami pernah melihat satu kunci berjalan dari pesan chat ke deskripsi tiket lalu ke pesan pertama agen kedua, tanpa ada seorang pun yang berbuat salah.
Dan jaring pengaman yang biasa tidak menahannya. Penyensoran keluaran bekerja dengan pola: sk-…, glpat-…, bentuk sebuah JWT. Ia tidak bisa tahu bahwa thursday-harbour-71 adalah kata sandi database staging Anda. Di aplikasi kami sendiri kami menyensor nilai yang cocok dari keluaran terminal, dan kami tetap memperlakukannya sebagai jaring di bawah trapeze, bukan sebagai trapeze-nya.
Aturan satu pintu
Ini aturannya, dalam satu baris: sebuah kredensial sampai ke agen lewat variabel lingkungan dari proses tempat agen itu berjalan, dan tidak lewat kanal lain mana pun.
Selebihnya adalah teks apa adanya. Pesan yang Anda ketik, deskripsi tiket, file skill, system prompt, opsi baris perintah: semuanya dibaca oleh manusia atau oleh model, jadi rahasia yang ditulis di sana adalah rahasia yang sudah dipublikasikan.
Baris perintah pantas dapat kalimatnya sendiri, karena ia terasa lebih aman daripada pesan chat padahal tidak. Nilai di dalam --api-key=… terlihat oleh setiap proses di mesin lewat ps, ia mendarat di riwayat shell Anda, ia dicatat oleh apa pun yang merekam perintah yang dijalankan, dan ia muncul lagi di alat diagnostik yang mencetak baris proses itu kembali ke hadapan Anda. Variabel lingkungan dari satu proses hanya terbaca oleh proses itu dan oleh root. Permukaan lebih kecil, kenyamanan sama saja.
Sementara itu agennya sendiri tidak pernah butuh nilainya. Ia cuma perlu menulis ini:
curl -H "Authorization: Bearer $STRIPE_SECRET_KEY" https://api.stripe.com/v1/charges
Shell mengembangkan $STRIPE_SECRET_KEY saat eksekusi. Agen menulis tujuh belas karakter dan satu tanda dolar. Transkripnya memuat tujuh belas karakter dan satu tanda dolar.
Cara kerjanya di aplikasi kami
Mekanismenya tidak sepenting bentuknya, tapi bentuknya lebih mudah ditiru kalau Anda bisa melihat satu implementasi nyata.
Satu brankas, satu file. AgentsRoom menyimpan rahasia dalam satu file di folder home Anda, mode 0600, dienkripsi lewat keychain sistem operasi, dan ditegaskan ulang pada setiap penulisan. Tidak ada yang disinkronkan ke server, dan tidak ada yang menyeberang ke komputer lain: sebuah rahasia milik mesin yang memegangnya. Kalau keychain tidak tersedia, penyimpanan gagal, bukan mundur ke teks biasa.
Anda menyimpan sebuah nilai satu kali. Perintah & koneksi > Rahasia, di proyek mana pun. Satu nama (huruf, angka, titik, strip, garis bawah, 64 karakter, supaya langsung bisa dipakai sebagai nama variabel lingkungan) dan satu nilai, diketik di kolom bertipe kata sandi. Baris yang muncul menampilkan namanya dan referensinya, {{secret:STRIPE_SECRET_KEY}}, plus tombol yang menyalin referensi itu. Tidak ada tombol untuk menampilkan nilai dan tidak ada tombol untuk menyalin nilai, karena memang tidak ada jalur kode yang mengembalikan sebuah nilai ke antarmuka.
Anda merujuknya di tempat lingkungan itu dibangun. Edit agen > Lanjutan > Variabel lingkungan, atau pengaturan proyek, atau pengaturan provider, atau sebuah baris perintah dev:
STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}
Saat peluncuran, proses utama memasukkan nilai aslinya ke lingkungan terminal yang akan ia buat. Antarmuka tidak pernah melihatnya, agen tidak pernah melihatnya, ponsel juga tidak pernah melihatnya. Halaman Pengelola Rahasia menunjukkan layar demi layar.
Agen menemukan nama, bukan nilai. Agen yang terhubung ke tool MCP kami bisa memanggil secrets_list dan menerima daftar nama yang ada di mesin itu. Itu sudah cukup untuk membuatnya berguna: ia bisa bilang "Anda punya STRIPE_SECRET_KEY yang tersimpan, tambahkan STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} ke lingkungan agen ini dan saya akan memakai $STRIPE_SECRET_KEY". Ia tidak bisa membaca nilainya, bahkan ketika sedang menjalankan perintah yang memakainya.
Tiga kesalahan yang kami rilis
Aturan di atas kedengaran jelas sekali begitu ditulis. Ia adalah jaringan parut dari tiga bug, semuanya pada September 2026, semuanya dilaporkan pengguna.
Referensi yang ditulis di tiket keluar sudah terisi nilai asli
19 September. Robert mendokumentasikan sebuah pemetaan di deskripsi tiket, yaitu STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} yang sama sekali masuk akal, supaya siapa pun yang mengambil tiket itu tahu apa yang harus disetel. Dibaca lewat API, tiketnya mengembalikan referensi itu utuh. Tapi agen yang diluncurkan dari tiket tersebut menerima nilai aslinya di pesan pertamanya.
Penyebabnya adalah detail perpipaan dengan konsekuensi nyata. Brief sebuah tiket menjadi prompt pertama agen, dan prompt itu berjalan di dalam sebuah variabel lingkungan dari perintah peluncuran. Resolver kami mengganti semua nilai lingkungan, jadi ia mengganti isi prompt itu juga. Kuncinya masuk ke disk dan ke penyedia model. Harus dirotasi, tidak ada jalan lain.
Perbaikannya adalah membuat perintah peluncuran agen menjadi apa adanya: ketika lingkungan membawa sebuah id agen, variabel yang memuat prompt pertama dibiarkan tidak tersentuh. Perintah dev yang memakai variabel yang sama tidak punya id agen, jadi tetap diganti seperti sebelumnya. Kami menerima satu efek samping dengan sengaja: referensi yang diketik di opsi CLI sebuah agen juga tidak lagi diganti, dan itu memang benar, karena baris perintah toh berakhir di ps dan di log.
Pelajarannya: pintunya harus sempit dengan sengaja. "Ganti di mana pun itu mungkin berguna" adalah persis cara sebuah rahasia berakhir di tempat yang seharusnya tidak pernah ia datangi.
Referensi yang ditempel ke pesan, yang tidak pernah diganti
22 September. Cs040618 melaporkan masalah yang sebaliknya: "saya tempel referensinya ke percakapan dan agennya tidak bisa paham kunci ini apa".
Bukan bug. Pesan memang teks apa adanya secara desain, dan itu persis perbaikan dari tiga hari sebelumnya. Tapi tidak ada satu pun bagian aplikasi yang mengatakannya tepat saat pengguna melakukan gerakan itu, dan agen yang menerima {{secret:…}} di sebuah pesan sama sekali tidak tahu harus menjawab apa.
Tiga perbaikan, semuanya soal memberi tahu di mana pintunya: petunjuk yang muncul ketika Anda menempelkan sebuah referensi ke kolom pesan dan mengarahkan ke variabel lingkungan, teks bantuan di atas daftar rahasia yang menyebut tiga kolom tempat sebuah referensi diganti dan berkata "tidak pernah di dalam pesan", serta satu baris di instruksi agen itu sendiri yang memberitahunya harus menjawab apa ketika sebuah referensi datang lewat pesan.
"Pengaturan > Rahasia" tidak pernah ada
28 September. Agen milik Mohammad mengirim laporan: penggunanya bilang ia menambahkan OTPIQ_API_KEY di Pengaturan > Rahasia, menyimpannya berkali-kali selama tiga puluh menit, dan secrets_list tetap mengembalikan tiga rahasia lama yang sama.
Jalur penyimpanannya baik-baik saja. Rahasianya memang tidak pernah sampai ke brankas, karena tidak ada halaman Rahasia di pengaturan. Enam string bantuan di aplikasi desktop, satu halaman di situs ini, dan instruksi agen semuanya mengarahkan orang ke layar yang tidak ada. Yang memang ada di pengaturan adalah blok variabel lingkungan, jadi di situlah ia mengetik tokennya, di dalam kurung kurawal, yang bukan sebuah referensi: tidak pernah diganti, dikirim ke agen apa adanya, dan disinkronkan bersama proyek, sehingga tokennya keluar dari mesin.
Kami memperbaiki string-string itu supaya menyebut jalur yang sebenarnya, membuat tool yang menghadap agen menyebutkan di mana sebuah rahasia ditambahkan, dan menambahkan pemeriksaan pada blok lingkungan yang menandai kredensial yang terlihat mentah, nama dalam kurung kurawal yang bukan referensi, dan referensi ke rahasia yang tidak ada di mesin ini.
Pelajaran di sini sama sekali bukan soal rahasia: jalur yang salah di teks bantuan adalah bug keamanan. Ia memindahkan pengguna ke kolom terdekat yang kelihatannya benar.
Kalau Anda tidak memakai AgentsRoom
Aturannya bisa dibawa ke mana saja. Pilih mana dari cara berikut yang cocok dengan setup Anda; semuanya berakhir di tempat yang sama, sebuah variabel lingkungan di proses tempat agen berjalan.
- CLI pengelola kata sandi.
op run -- claudedengan 1Password, atau padanannya di Bitwarden dan Doppler: alatnya membaca referensi dari sebuah template, menyuntikkan nilai asli ke lingkungan proses anak, dan tidak ada yang ditulis ke disk. direnvdengan.envrcyang sudah di-gitignore. Sederhana, lokal, per direktori. Tambahkan.envrcdan.env*ke.gitignoresebelum nilai pertama masuk, bukan sesudahnya.- File
.envyang tidak pernah dibaca agen. Simpan di luar repositori dan muat di shell yang meluncurkan agen. Kalau filenya ada di dalam repositori, cepat atau lambat agen akan membukanya, mengutipnya di sebuah pesan, dan mengembalikan Anda ke titik awal. - Kredensial cloud: pakai yang berumur pendek. GitHub OIDC di CI daripada kunci AWS berumur panjang, dan workload identity daripada file kunci service account.
Apa pun yang Anda pilih, tambahkan aturan itu ke instruksi agen supaya ia berhenti bertanya. Satu paragraf di CLAUDE.md atau AGENTS.md sudah cukup: jangan pernah meminta nilai sebuah kredensial, jangan pernah menuliskannya ke sebuah file, pakai $NAME dan beri tahu pengguna variabel mana yang harus disetel. Kami menerbitkan satu skill kecil yang bunyinya persis seperti itu, dan panjangnya lima baris.
Kalau sebuah kunci sudah terlanjur lewat percakapan
Berurutan, dan langkah pertama tidak opsional.
- Rotasi kuncinya. Prompt tidak bisa ditarik kembali. Anggap nilainya sudah bocor dan terbitkan yang baru.
- Cari transkripnya. CLI menyimpan file percakapan di folder home Anda. Cari nilai lamanya di sana lalu hapus atau potong yang cocok.
- Periksa tempat-tempat yang menyalin teks. Riwayat pengelola clipboard, tiket atau issue tempat agen di-brief, setiap ringkasan yang ditulis agen ke dalam repositori, dan
git log -pkalau agen sempat commit saat memegangnya. - Baru setelah itu bangun pintunya. Nilai baru di balik variabel lingkungan, dirujuk lewat nama, dan instruksi agen diperbarui supaya yang berikutnya tidak bertanya lagi.
Langkah 4 paling akhir, karena mekanisme yang bersih di sekeliling kunci yang sudah bocor hanyalah kebocoran yang lebih rapi.
Pertanyaan yang benar-benar ditanyakan orang
Kenapa kunci API tidak boleh masuk ke prompt untuk agen AI?
Karena sebuah prompt disimpan dan diteruskan. Claude Code, Codex, dan CLI lainnya menulis percakapan ke file transkrip di disk Anda, dan pesannya sendiri dikirim ke penyedia model. Dari sana kuncinya juga ada di riwayat clipboard Anda, di setiap log yang mengulang pesan itu, dan di setiap percobaan ulang serta subagent yang menyalin percakapannya. Penyensoran berbasis pola menangkap sesuatu yang berbentuk sk- atau glpat-, bukan kata sandi database yang terbaca seperti kata biasa.
Bagaimana agen coding memakai rahasia yang tidak bisa ia baca?
Lewat variabel lingkungan. Anda menaruh nilainya di variabel lingkungan dari proses tempat agen berjalan, dan agen menulis $STRIPE_SECRET_KEY di perintahnya, bukan nilainya. Shell yang mengembangkannya saat perintah dijalankan. Agen tidak pernah melihat karakternya, jadi karakter itu tidak pernah masuk ke percakapan maupun transkripnya.
Boleh tidak saya oper rahasianya sebagai argumen baris perintah saja?
Boleh, dan sebaiknya jangan. Baris perintah terlihat oleh setiap proses di mesin lewat ps, masuk ke riwayat shell, ke log proses, dan ke alat diagnostik apa pun yang membaca perintah yang dijalankan. Variabel lingkungan dari satu proses hanya terbaca oleh proses itu dan oleh root, permukaan yang jauh lebih kecil.
Di mana AgentsRoom menyimpan rahasia yang dipakai agen?
Di satu file di folder home Anda, mode 0600, dienkripsi lewat keychain sistem operasi Anda, dan hanya di mesin itu. Tidak ada yang disinkronkan ke server, dan tidak ada tombol untuk menampilkan nilainya lagi. Aplikasi menampilkan nama, agen melihat nama, dan nilainya baru didekripsi di proses utama tepat saat sebuah terminal atau perintah dijalankan.
Apa yang terjadi kalau saya menempelkan referensi rahasia ke pesan untuk agen?
Tidak ada yang diganti, dan itu memang disengaja. Pesan, deskripsi tiket, skill, dan system prompt adalah teks apa adanya, jadi referensi yang ditulis di sana sampai ke agen sebagai teks. Hanya nilai variabel lingkungan yang diganti. Kami belajar ini dengan cara yang pahit: referensi yang ditulis di deskripsi tiket dulu keluar sudah terisi nilai asli di pesan pertama agen yang diluncurkan dari tiket itu.
Sebuah kunci sudah terlanjur lewat percakapan. Apa yang harus saya lakukan?
Rotasi dulu, sebelum hal lain apa pun, karena prompt tidak bisa ditarik kembali: nilainya sudah ada di sisi penyedia dan di file transkrip pada disk Anda. Lalu hapus atau potong transkrip yang memuatnya, periksa pengelola clipboard Anda, dan grep repositori kalau-kalau agen menuliskannya ke sebuah file. Baru setelah itu taruh nilai barunya di balik variabel lingkungan.
Versi singkatnya
Sebuah agen tidak perlu membaca kunci Anda. Ia perlu sebuah proses yang lingkungannya sudah memegang kunci itu.
Simpan nilainya sekali saja, di luar repositori, dienkripsi oleh sistem operasi. Rujuk lewat namanya di tempat lingkungan itu dibangun. Biarkan agen menulis $NAME. Jaga semua kanal lain tetap apa adanya, termasuk kanal yang penggantian nilainya tadinya akan terasa praktis, karena justru kanal yang praktis itulah yang disimpan dan diteruskan.
Dan ketika Anda salah, dan itu pasti terjadi, rotasi dulu dan rapikan kemudian.
Unduh AgentsRoom
Jalankan semua agen AI Anda, di semua proyek Anda, dari satu jendela.
Aplikasi pendamping: pantau agen Anda saat bepergian
Gunakan Claude, Codex, Antigravity CLI, atau penyedia AI lainnya.
Kirim bug dan permintaan langsung ke backlog publik Anda.
Lanjutkan membaca
Tujuh Agen AI Bekerja untuk Kami Setiap Malam: Agen Terjadwal di Luar Coding, Lengkap dengan Prompt-nya
Seorang pengguna bertanya bagaimana kami memakai agen AI untuk hal lain selain menulis kode. Sejak 28 Agustus, tujuh agen terjadwal mulai bekerja setiap malam di sebuah Mac mini: seorang CEO piket, tim SEO, product manager, agen perbaikan bug, tim media sosial, penjaga dokumentasi, dan pelapor yang mengirim ringkasan 25 baris lewat email. 33 malam, 31 email pagi, 51 bug diperbaiki lengkap dengan tautan commit, 7 artikel blog dalam 20 bahasa. Apa yang dikerjakan masing-masing, bagaimana mereka saling menyerahkan pekerjaan tanpa berbicara, model mana yang mengerjakan tugas mana, empat aturan yang harus dipelajari prompt mereka, dan prompt-nya sendiri, siap disalin.
Baca artikelCara Berkomunikasi dengan AI Coding Agent: Claude, Codex, Antigravity, Grok Build
Kode bukan lagi hambatannya, komunikasi yang jadi masalah. Begini cara berbicara dengan AI agent seperti Claude, Codex, Antigravity, dan Grok Build agar lebih cepat, presisi, dan hemat token.
Baca artikelSatu Akun Claude di Dua Komputer, atau untuk Dua Orang: Apa yang Bisa
Satu akun Claude bisa login di semua perangkat milik Anda, dan semuanya memakai batas 5 jam dan batas mingguan yang sama, Claude dan Claude Code bersama-sama. Dua orang di satu akun melanggar ketentuan Anthropic, dan tidak ada paket keluarga. Apa yang kami periksa pada 25 Oktober 2026, dan cara melihat komputer mana yang memakai berapa.
Baca artikel