Bir Kodlama Ajanına Prompt'a Yazmadan Gizli Bilgi Nasıl Verilir
Bir ajanın komutunu çalıştırmak için bir Stripe anahtarına ya da veritabanı parolasına ihtiyacı var. Onu sohbete yapıştırdığın anda diskindeki transkripte, model sağlayıcısına ve bazen bir commit'e düşer. Kendi üç hatamızdan sonra vardığımız kural: bir gizli bilgi bir ajana yalnızca ortam değişkeniyle ulaşır, başka hiçbir yolla değil.
Durum hep aynı. Ajan bir görevin ortasında, test Stripe API'ne gitmesi, staging veritabanında bir migrasyon çalıştırması ya da özel bir kayıt defterine push etmesi gerekiyor. Anahtarı istiyor. Anahtar parola yöneticinde duruyor, ajan bekliyor ve dünyadaki en hızlı şey onu sohbete yapıştırmak.
İşte o yapıştırma, anahtarın kontrolünden çıktığı andır. Model kötü niyetli olduğu için değil, bir prompt saklanan ve iletilen bir nesne olduğu için: diskinde bir transkript dosyasına gider, model sağlayıcısına gider ve konuşmayı devralan her yeniden deneme ile her alt ajan tarafından kopyalanır.
Biz kodlama ajanlarını çalıştıran bir masaüstü uygulaması olan AgentsRoom uygulamasını geliştiriyoruz, dolayısıyla bunu önce kendimiz için çözmek zorunda kaldık. Eylül 2026'da üç kez yanıldık. Sonunda vardığımız kural, onu doğuran üç hata ve uygulamamızı kullansan da kullanmasan da bunu nasıl uygulayacağın aşağıda.
Kısa cevap
- Bir gizli bilgi bir ajana yalnızca ortam değişkeniyle ulaşır, başka hiçbir yolla değil. Mesajla değil, ticket'la değil, beceriyle değil, komut satırı bayrağıyla değil.
- Ajan
$NAMEyazar, değeri asla. Komut çalışırken kabuk onu açar. - Değeri bir kez, deponun dışında sakla, işletim sistemi anahtar zincirinle şifrele, başka her yerde ona adıyla referans ver.
- Bir konuşmadan geçmiş gizli bilgi yanmıştır. Önce değiştir, sonra temizle.
- Maskeleme bir emniyet ağıdır, bir plan değil. Anahtara benzeyen şeyi yakalar, kelimeye benzeyen bir veritabanı parolasını değil.
O yapıştırma göründüğünden neden daha kötü
Aynı anda üç şey olur ve yalnızca ilki göze çarpar.
Model sağlayıcısına gider. Herkesin gördüğü kısım bu. Anahtarın artık başkasının altyapısında bir istek gövdesinde, hem de düzenleyemeyeceğin bir konuşmanın içinde.
Diskine düz metin olarak gider. Claude Code, Codex, Antigravity CLI ve diğerleri, konuşmayı sonradan sürdürebilmen için onun bir transkriptini tutar. O dosya ana klasöründe, şifresiz biçimde, CLI geçmişini tuttuğu sürece durur. Bir kere transkriptlerinde sk- dizesini ara ve neler çıktığına bak.
Yana doğru yayılır. Konuşma ajanın hafızasıdır, dolayısıyla konuşmayı kopyalayan her şey anahtarı da kopyalar: sürdürülen bir oturum, forklanmış bir ajan, ebeveynin bağlamıyla başlatılan bir alt ajan, bir proje dosyasına yazılan bir özet. Bir anahtarın sohbet mesajından ticket açıklamasına, oradan ikinci bir ajanın ilk mesajına yolculuk ettiğini, hem de kimse yanlış bir şey yapmadan, gördük.
Üstelik her zamanki emniyet ağı tutmuyor. Çıktı maskelemesi desenle çalışır: sk-…, glpat-…, bir JWT biçimi. thursday-harbour-71 değerinin staging veritabanı parolan olduğunu bilemez. Kendi uygulamamızda eşleşen değerleri terminal çıktısından maskeliyoruz ve bunu yine de trapezin kendisi değil, trapezin altındaki ağ olarak görüyoruz.
Tek kapı kuralı
Kural tek satırda şu: bir kimlik bilgisi bir ajana, ajanın içinde çalıştığı sürecin bir ortam değişkeniyle ulaşır, başka hiçbir kanalla değil.
Geri kalan her şey düz metindir. Yazdığın bir mesaj, bir ticket açıklaması, bir beceri dosyası, bir sistem prompt'u, bir komut satırı bayrağı: bunların hepsini bir insan ya da bir model okur, dolayısıyla oraya yazılmış bir gizli bilgi yayımlanmış bir gizli bilgidir.
Komut satırı kendi cümlesini hak ediyor, çünkü bir sohbet mesajından daha güvenli hissettirir ve değildir. --api-key=… içindeki bir değer, ps üzerinden makinedeki her sürece görünür, kabuk geçmişine düşer, başlatılan komutu kaydeden her şey tarafından günlüklenir ve süreç satırını sana geri yazan tanılama araçlarında belirir. Tek bir sürecin ortam değişkenini ise o süreç ve root okuyabilir. Daha küçük yüzey, aynı kolaylık.
Ajanın ise değere hiç ihtiyacı yok. İhtiyacı olan şey şunu yazmak:
curl -H "Authorization: Bearer $STRIPE_SECRET_KEY" https://api.stripe.com/v1/charges
Kabuk $STRIPE_SECRET_KEY değişkenini çalıştırma anında açar. Ajan on yedi karakter ve bir dolar işareti yazdı. Transkriptinde on yedi karakter ve bir dolar işareti duruyor.
Bizim uygulamamızda nasıl çalışıyor
Mekanizma biçimden daha az önemli, ama bir uygulamasını görünce biçimi kopyalamak kolaylaşıyor.
Tek kasa, tek dosya. AgentsRoom gizli bilgileri ana klasöründeki tek bir dosyada tutar, 0600 kipinde, işletim sistemi anahtar zinciriyle şifrelenmiş ve her yazmada yeniden doğrulanmış olarak. Hiçbir şey bir sunucuya senkronize edilmez ve hiçbir şey başka bir bilgisayara geçmez: bir gizli bilgi, onu tutan makineye aittir. Anahtar zinciri kullanılamıyorsa kaydetme düz metne düşmek yerine başarısız olur.
Bir değeri bir kez kaydedersin. Komutlar ve bağlantılar > Gizli bilgiler, herhangi bir projede. Bir ad (harfler, rakamlar, nokta, tire, alt çizgi, 64 karakter, yani ortam değişkeni adı olarak kullanılabilir) ve bir parola alanına yazılan bir değer. Beliren satır adı ve referansını, {{secret:STRIPE_SECRET_KEY}}, bir de referansı kopyalayan bir düğme gösterir. Göster düğmesi ve değeri kopyala düğmesi yoktur, çünkü arayüze bir değer döndüren hiçbir kod yolu yoktur.
Ortamın kurulduğu yerde ona referans verirsin. Ajanı düzenle > Gelişmiş > Ortam değişkenleri, ya da proje ayarları, ya da sağlayıcı ayarları, ya da bir dev komut satırı:
STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}
Başlatma anında ana süreç, değeri yaratmak üzere olduğu terminalin ortamına yerleştirir. Arayüz onu hiç görmez, ajan hiç görmez, telefon hiç görmez. Gizli Bilgi Yöneticisi sayfası ekranları tek tek anlatıyor.
Ajan adları keşfeder, değerleri değil. MCP araçlarımıza bağlı bir ajan secrets_list çağırabilir ve o makinedeki adların listesini alabilir. İşe yaraması için bu yeterli: «kayıtlı bir STRIPE_SECRET_KEY var, bu ajanın ortamına STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}} ekle, ben de $STRIPE_SECRET_KEY kullanayım» diyebilir. Değeri okuyamaz, onu kullanan bir komutu çalıştırırken bile.
Yayına verdiğimiz üç hata
Yukarıdaki kural yazılı haliyle apaçık görünüyor. Oysa hepsi Eylül 2026'da olan, hepsi kullanıcılar tarafından bildirilen üç hatanın bıraktığı yara izi.
Bir ticket'ta alıntılanan referans çözülmüş olarak çıkıyordu
19 Eylül. Robert, ticket'ı kim alırsa neyi ayarlaması gerektiğini bilsin diye bir ticket açıklamasına bir eşleme yazmıştı, gayet makul olan STRIPE_SECRET_KEY={{secret:STRIPE_SECRET_KEY}}. Ticket API üzerinden okunduğunda referans olduğu gibi dönüyordu. Ama o ticket'tan başlatılan ajan ilk mesajında değeri alıyordu.
Sebep, gerçek bir sonucu olan bir tesisat ayrıntısıydı. Bir ticket özeti ajanın ilk prompt'u olur ve bu prompt, başlatma komutunun bir ortam değişkeninin içinde yolculuk ediyordu. Çözümleyicimiz her ortam değerini yerine koyuyordu, dolayısıyla prompt'u da yerine koydu. Anahtar diske ve model sağlayıcısına gitti. Anahtarı değiştirmek şart, kaçışı yok.
Düzeltme, ajanın başlatma komutunu düz metin saymaktı: ortam bir ajan kimliği taşıdığında, ilk prompt'u tutan değişkene dokunulmaz. Aynı değişkeni kullanan bir dev komutunun ajan kimliği yoktur ve eskisi gibi çözülür. Bir yan etkiyi bilerek kabul ettik: bir ajanın CLI seçeneklerine yazılan bir referans da artık çözülmüyor, ki bu doğru, çünkü bir komut satırı zaten ps içine ve günlüklere düşüyor.
Ders: kapı bilerek dar olmalı. «İşe yarayabileceği her yerde yerine koyalım», bir gizli bilginin asla bulunmaması gereken yere düşme biçimidir.
Bir mesaja yapıştırılan ve hiç çözülmeyen referans
22 Eylül. Cs040618 tam tersi sorunu bildirdi: «referansı konuşmaya yapıştırıyorum ve ajan bu anahtarın ne olduğunu anlayamıyor».
Hata değil. Bir mesaj tasarım gereği düz metindir, yani üç gün önceki düzeltmenin ta kendisi. Ama o hareketi yaptığın anda uygulamada bunu söyleyen hiçbir şey yoktu ve mesajda {{secret:…}} alan ajanın ne cevaplayacağına dair hiçbir fikri yoktu.
Üç düzeltme, hepsi insanlara kapının nerede olduğunu söylemeye dair: yazma alanına bir referans yapıştırdığında tetiklenip ortam değişkenlerini gösteren bir ipucu, gizli bilgi listesinin üstünde bir referansın yerine konduğu üç alanı adıyla sayan ve «asla bir mesajda değil» diyen bir yardım metni, bir de ajanın kendi talimatlarında bir mesaja referans geldiğinde ne cevaplayacağını söyleyen bir satır.
«Ayarlar > Gizli bilgiler» diye bir yer yoktu
28 Eylül. Mohammad'ın ajanı bir rapor açtı: kullanıcı OTPIQ_API_KEY değerini Ayarlar > Gizli bilgiler içine eklediğini, otuz dakika boyunca birkaç kez kaydettiğini, ama secrets_list çağrısının hâlâ aynı üç eski gizli bilgiyi döndürdüğünü söylüyordu.
Kaydetme yolunda sorun yoktu. Gizli bilgi kasaya hiç ulaşmamıştı, çünkü ayarlarda Gizli bilgiler diye bir sayfa yok. Masaüstü uygulamasındaki altı yardım metni, bu sitedeki bir sayfa ve ajanın kendi talimatları insanları var olmayan bir ekrana yolluyordu. Ayarlarda gerçekten var olan şey ortam değişkenleri bloğu, o yüzden token'ı oraya yazdı, süslü parantez içinde, ki bu bir referans değil: asla yerine konmaz, ajana olduğu gibi gider ve projeyle senkronize edilir, böylece token makineden çıkmış oldu.
Metinleri gerçek yolu söyleyecek şekilde düzelttik, ajanlara dönük araçlara bir gizli bilginin nereye eklendiğini söylettik ve ortam bloğuna, ham görünen bir kimlik bilgisini, referans olmayan süslü parantezli bir adı ve bu makinede bulunmayan bir gizli bilgiye verilen referansı işaretleyen bir denetim ekledik.
Buradaki ders gizli bilgilerle ilgili bile değil: bir yardım metnindeki yanlış yol bir güvenlik hatasıdır. Kullanıcıyı doğru görünen en yakın alana taşır.
AgentsRoom kullanmıyorsan
Kural taşınır. Bunlardan kurulumuna uyanı seç; hepsi aynı yerde, ajanın içinde çalıştığı sürecin bir ortam değişkeninde biter.
- Bir parola yöneticisi CLI'si. 1Password ile
op run -- claude, ya da Bitwarden ve Doppler'daki karşılığı: araç bir şablondan referansları okur, gerçek değerleri alt sürecin ortamına enjekte eder ve diske hiçbir şey yazılmaz. - gitignore'a alınmış bir
.envrciledirenv. Basit, yerel, klasör başına..envrcve.env*dosyalarını.gitignoreiçine ilk değerden önce ekle, sonra değil. - Ajanın hiç okumadığı bir
.envdosyası. Onu deponun dışında tut ve ajanı başlatan kabukta yükle. Dosya deponun içindeyse ajan er geç onu açar, bir mesajda alıntılar ve seni başladığın yere geri koyar. - Bulut kimlik bilgileri: kısa ömürlü olanları kullan. CI'da uzun ömürlü AWS anahtarları yerine GitHub OIDC, servis hesabı anahtar dosyası yerine bir iş yükü kimliği.
Hangisini seçersen seç, kuralı ajanın talimatlarına da ekle ki sormayı bıraksın. CLAUDE.md ya da AGENTS.md içindeki tek paragraf yeter: asla bir kimlik bilgisinin değerini isteme, asla bir dosyaya yazma, $NAME kullan ve kullanıcıya hangi değişkeni ayarlaması gerektiğini söyle. Tam olarak bunu söyleyen küçük bir beceri yayımlıyoruz, beş satır uzunluğunda.
Bir anahtar bir konuşmadan çoktan geçtiyse
Sırayla, ve ilk adım isteğe bağlı değil.
-
Değiştir. Gönderilmiş bir prompt geri alınmaz. Değeri ele geçmiş say ve yenisini çıkar.
-
Transkriptleri bul. CLI'ler konuşma dosyalarını ana klasöründe tutar. İçlerinde eski değeri ara, eşleşenleri sil ya da kırp.
-
Metin kopyalayan yerleri kontrol et. Pano yöneticisi geçmişi, ajanın brifingini aldığı ticket ya da issue, ajanın depoya yazdığı herhangi bir özet, ve anahtarı elinde tutarken commit attıysa
git log -p. -
Kapıyı ancak bundan sonra kur. Yeni değer bir ortam değişkeninin arkasında, adıyla referans, ve bir sonraki ajanın sormaması için güncellenmiş talimatlar.
-
adım en sonda, çünkü sızmış bir anahtarın etrafındaki temiz bir mekanizma yalnızca daha derli toplu bir sızıntıdır.
İnsanların gerçekten sorduğu sorular
Bir API anahtarı neden asla bir yapay zeka ajanına verilen prompt'a yazılmamalı?
Çünkü bir prompt saklanır ve iletilir. Claude Code, Codex ve diğer CLI'ler konuşmayı diskindeki bir transkript dosyasına yazar, mesajın kendisi de model sağlayıcısına gider. Oradan sonra anahtar panonun geçmişinde, mesajı tekrarlayan her günlükte ve konuşmayı kopyalayan yeniden denemelerle alt ajanlarda da bulunur. Desene dayalı maskeleme sk- ya da glpat- biçimindeki şeyleri yakalar, sıradan bir kelimeye benzeyen bir veritabanı parolasını değil.
Bir kodlama ajanı okuyamadığı bir gizli bilgiyi nasıl kullanır?
Bir ortam değişkeniyle. Değeri, ajanın içinde çalıştığı sürecin bir ortam değişkenine koyarsın, ajan da komuta değerin yerine $STRIPE_SECRET_KEY yazar. Komut çalışırken kabuk onu açar. Ajan karakterleri hiç görmez, dolayısıyla karakterler ne konuşmasına ne de transkriptine girer.
Gizli bilgiyi bunun yerine komut satırı argümanı olarak geçebilir miyim?
Geçebilirsin ama geçmemelisin. Bir komut satırı ps üzerinden makinedeki her sürece görünür, kabuk geçmişine, süreç günlüklerine ve başlatılan komutu okuyan her tanılama aracına düşer. Tek bir sürecin ortam değişkenini ise o süreç ve root okuyabilir, bu çok daha küçük bir yüzeydir.
AgentsRoom, ajanların kullandığı gizli bilgileri nerede saklıyor?
Ana klasöründeki tek bir dosyada, 0600 kipinde, işletim sistemi anahtar zincirinle şifrelenmiş olarak ve yalnızca o makinede. Hiçbir şey bir sunucuya senkronize edilmez ve bir değeri yeniden gösteren bir düğme yoktur. Uygulama adları gösterir, ajan adları görür, değer ise yalnızca ana süreçte, bir terminal ya da bir komut başladığı anda çözülür.
Ajana gönderdiğim bir mesaja gizli bilgi referansı yapıştırırsam ne olur?
Hiçbir şey yerine konmaz, bu bilerek böyle. Bir mesaj, bir ticket açıklaması, bir beceri ve bir sistem prompt'u düz metindir, oraya yazılan bir referans ajana metin olarak ulaşır. Yalnızca bir ortam değişkeninin değeri yerine konur. Bunu zor yoldan öğrendik: bir ticket açıklamasında alıntılanan bir referans, o ticket'tan başlatılan ajanın ilk mesajında çözülmüş olarak çıkıyordu.
Bir anahtar bir konuşmadan geçti bile. Ne yapmalıyım?
Her şeyden önce onu değiştir, çünkü gönderileni geri alamazsın: anahtar hem sağlayıcı tarafında hem de diskindeki transkript dosyasında. Sonra onu içeren transkriptleri sil ya da kırp, pano yöneticini kontrol et ve ajan bir dosyaya yazmış olabilir diye depoda ara. Yeni değeri ancak bundan sonra bir ortam değişkeninin arkasına koy.
Kısa hali
Bir ajanın anahtarını okumaya ihtiyacı yok. İhtiyacı olan şey, ortamında anahtarın hazır durduğu bir süreç.
Değeri bir kez, deponun dışında, işletim sistemi tarafından şifrelenmiş olarak sakla. Ortamın kurulduğu yerde ona adıyla referans ver. Ajan $NAME yazsın. Diğer bütün kanalları düz metin olarak tut, yerine koymanın işine yarayacağı kanallar dahil, çünkü işe yarayan kanallar tam olarak saklanan ve iletilen kanallardır.
Ve yanıldığında, ki yanılacaksın, önce anahtarı değiştir, toparlamayı sonraya bırak.
AgentsRoom'u İndir
Tüm yapay zeka ajanlarını, tüm projelerinde, tek bir pencereden çalıştır.
Yardımcı uygulama: hareket halindeyken ajanlarını izle
Claude, Codex, Antigravity CLI veya başka bir AI sağlayıcı kullan.
Hataları ve istekleri doğrudan genel backloguna gönder.
Okumaya devam et
Kodu artık ajanlar yazıyor. Geliştiricinin işi neye dönüştü?
Kod yazmak altı halkalı bir zincirin tek halkasıydı ve ajanların aldığı halka o oldu. Diğer beşi ağırlaştı. Geriye kalan işin dökümü: talebi duymak, karar vermek, brief yazmak, yürütmeyi yönetmek, incelemek, yayına çıkarmak.
Makaleyi okuAgentsRoom artık Ollama'yı destekliyor: yerel modelleri bulutun yanında çalıştırın
Ollama artık AgentsRoom'da bir sağlayıcı. Llama, Qwen, Gemma ve DeepSeek gibi yerel açık kaynak modelleri bulut ajanlarının yanında çalıştırın ve her ajana, konuşmanın ortasında değiştirilebilen bir yerel-veya-bulut kadranı ayarlayın.
Makaleyi okuTek Claude Hesabı İki Bilgisayarda ya da İki Kişiyle: Hangisi Çalışır
Tek bir Claude hesabıyla sahip olduğun her cihazda giriş yapabilirsin ve hepsi aynı 5 saatlik ve haftalık limitleri kullanır, Claude ve Claude Code birlikte. Tek hesabı iki kişi kullanmak Anthropic'in şartlarına aykırı ve bir aile planı yok. 25 Ekim 2026'da neyi kontrol ettiğimiz ve hangi bilgisayarın ne harcadığını nasıl göreceğin.
Makaleyi oku