Bölüm 10 / 11
Sır yönetimi
Ortam değişkeni, kasa (vault), .NET user secrets.
15 dakikalık okuma
12-04'te ".env deponun dışında kalır" kuralını
koyduk; 12-11'de ortam değişkeninin de zayıflıkları olduğunu söyleyip ayrıntısını bu
derse bıraktık. Şimdi tamamı burada: bağlantı dizesi, imza anahtarı, API anahtarı,
sertifika özel anahtarı — bunların geliştirici makinesinden üretime kadar
nerede durduğu, ortam değişkeninin tam olarak nereden sızdığı, kasa (vault)
kullanmanın "sır almak için sır" paradoksunu nasıl çözdüğü ve — en çok atlanan
kısım — sır döndürmenin kesintisiz nasıl yapıldığı. Sonunda bir de acı bir
gerçek var: sızmış bir sır, git geçmişinden silinerek kurtarılmaz.
01Ne öğreneceksin
- Sır ile yapılandırma farkı ve sırların sınıflandırılması
- Katman katman doğru yer: geliştirici makinesi (.NET user secrets), boru hattı, üretim
- Ortam değişkeni tam olarak nereden sızar:
/proc,docker inspect, alt süreç mirası, hata bağlamı, çekirdek dökümü, log - Dosya olarak bağlama (mount) neden tercih edilir
- Kasa (vault) ve "sır almak için sır" paradoksunun çözümü: yönetilen kimlik
- Sır döndürme: iki anahtar dönemi, uygulamanın yeniden okuması, JWT imza anahtarı ve sertifika örnekleri
- Sır taraması ve git geçmişi gerçeği: asıl işlem silmek değil, iptal etmektir
02Sır nedir, yapılandırmadan farkı ne?
Yapılandırma, uygulamanın davranışını belirleyen değerdir: sayfa boyutu, zaman aşımı süresi, özellik bayrağı, veritabanı sunucusunun adı. Sır ise bir kimlik bilgisidir: onu bilen, o yetkiyi kullanabilir.
Ayrımın pratik değeri şudur: yapılandırma depoda durabilir, sürüm kontrolüne girer, gözden geçirilir. Sır duramaz — çünkü depoya giren bir değer klonlayan herkeste, tüm CI çalışmalarında, yedeklerde ve geçmişin tamamında vardır. Tipik sırlar:
- Veritabanı bağlantı dizesindeki parola
- JWT imza anahtarı / HMAC sırrı (5. ders), sertifikaların özel anahtarları (2. ders)
- OAuth2 istemci sırrı (6. ders — yalnız gizli istemcilerde)
- Üçüncü taraf API anahtarları (posta, SMS, ödeme, harita)
- Şifreleme anahtarları, çerez koruma anahtarları, biber (3. ders)
- Bulut erişim anahtarları ve servis hesabı kimlik bilgileri
Sırları sınıflandırmak da işin parçasıdır: hangisi sızarsa ne olur, ne kadar sürede döndürülebilir, kaç sistemi etkiler? "Test ortamının SMS anahtarı" ile "üretim veritabanı parolası" aynı özenle korunmaz — 1. dersteki risk = olasılık × etki denklemi burada da bütçeyi dağıtır.
03Katman katman: geliştirici, boru hattı, üretim
| Ortam | Doğru yer | Yanlış yer |
|---|---|---|
| Geliştirici makinesi | .NET: dotnet user-secrets (kullanıcı profilinde, proje dışında). Node: .env + .gitignore; ekipte .env.example paylaşılır (değerler değil, anahtar adları) | appsettings.json, koda gömme, ekip sohbetinde paylaşma |
| CI/CD | Boru hattının sır deposu (GitHub Actions secrets, Azure DevOps variable group). Loglarda maskelenir | Boru hattı dosyasında düz metin; echo $SIR ile hata ayıklama |
| Üretim | Kasa (Key Vault / Vault) + yönetilen kimlik; ya da orkestratörün sır nesnesi dosya olarak bağlanmış | İmajın içine gömme; docker run -e ile açıkta geçirme; sunucuda düz dosya |
.NET user secrets özel olarak anlaşılmaya değer, çünkü ne olduğu sık yanlış bilinir. Sırları şifrelemez; yaptığı şey onları proje klasörünün dışına, kullanıcı profilindeki bir JSON dosyasına taşımaktır. Böylece yanlışlıkla commit edilmeleri yapısal olarak imkânsız hâle gelir. Yalnızca geliştirme içindir, üretimde kullanılmaz:
dotnet user-secrets init
dotnet user-secrets set "ConnectionStrings:Ana" "Host=localhost;...;Password=..."
dotnet user-secrets list
// Kod tarafında hiçbir şey değişmez — yapılandırma sağlayıcısı zincire eklenir:
var baglanti = builder.Configuration.GetConnectionString("Ana");
Buradaki asıl fikir yapılandırma sağlayıcı zinciridir: aynı anahtar
(ConnectionStrings:Ana) geliştirmede user secrets'tan, üretimde ortam
değişkeninden ya da kasadan gelir. Kod değişmez, kaynak değişir. Node'da
aynı disiplin, 12-09'daki "yapılandırmayı açılışta doğrula, hızlı çök" deseniyle
kurulur: uygulama açılışta eksik sırrı fark edip hemen çöker — üretimde
ilk isteği alana kadar beklemez.
Bir de en temel kural: .gitignore'a güvenmek yeterli değildir.
Dosya bir kez izlenmeye başlandıysa .gitignore onu durdurmaz;
git add -f ile de aşılabilir. Asıl savunma 7. bölümdeki commit öncesi
taramadır.
04Ortam değişkeni tam olarak nereden sızar?
Ortam değişkeni, sırrı depodan çıkardığı için büyük bir kazançtır ve on iki faktör yaklaşımının önerisidir. Ama gizli bir kasa değildir; 12-11'de "zayıflıkları var" dediğimiz yerin tam listesi şudur:
| Sızma yolu | Nasıl |
|---|---|
| Süreç ortamı okunabilir | Linux'ta /proc/<pid>/environ — aynı kullanıcı (ya da root) tüm ortamı okur. Konteynerdeki bir kabuk erişimi tüm sırları verir |
| Konteyner meta verisi | docker inspect ve orkestratör nesne tanımları ortam değişkenlerini düz metin gösterir; kayıtlara ve yedeklere de öyle girer |
| Alt süreçlere miras | Uygulamanın başlattığı her alt süreç ortamın tamamını devralır — bir yardımcı araç, sırlarını da yanında taşır |
| Hata bağlamı | Birçok hata izleme aracı ve çerçeve, çökmede ortam değişkenlerini rapora ekler ve dış bir servise gönderir |
| Çekirdek dökümü / bellek dökümü | Süreç belleğinin dökümü ortamı ve sırları içerir |
| Log ve komut geçmişi | printenv, hata ayıklama amaçlı yazdırmalar, docker run -e SIR=... komutunun kabuk geçmişi ve süreç listesi |
Bu yüzden üretimde tercih edilen yol sırrı dosya olarak bağlamaktır: orkestratör sırrı bir dosyaya (tercihen bellekte tutulan bir dosya sisteminde) yazar, uygulama onu okur. Üç avantajı vardır: süreç ortamında görünmez, alt süreçlere miras kalmaz, ve döndürüldüğünde dosya içeriği değişir — süreç yeniden başlatılmadan yeni değer okunabilir (6. bölüm).
# Dosya tabanlı sır okuma deseni: önce _FILE değişkenine bak, sonra düz değişkene
const sirOku = (ad) => {
const yol = process.env[`${ad}_FILE`];
return yol ? fs.readFileSync(yol, "utf8").trim() : process.env[ad];
};
const dbParola = sirOku("DB_PAROLA"); // DB_PAROLA_FILE=/run/secrets/db_parola
Hangi yolu seçersen seç, 12-11'in kuralı geçerlidir: sırlar loglanmaz.
Yapılandırılmış log kütüphanesinin redaksiyon listesine password,
authorization, token, secret,
connectionstring anahtarları eklenir; ve hata yanıtlarının içine
yapılandırma nesnesi konmaz.
05Kasa ve "sır almak için sır" paradoksu
Kasa (Azure Key Vault, HashiCorp Vault, AWS Secrets Manager), sırları merkezî olarak saklayan, erişimi yetkilendiren ve her erişimi kaydeden bir servistir. Ortam değişkenine göre kazancı üç başlıktadır: erişim politikası (kim hangi sırrı okuyabilir), denetim izi (1. dersteki STRIDE'ın R harfi) ve döndürme desteği.
Ama hemen bir soru doğar ve mülakatta ayırt edicidir: kasaya bağlanmak için de bir kimlik bilgisi gerekmez mi? O kimlik bilgisini nerede saklayacaksın? Sorunu bir adım öteye taşımış olmaz mısın?
Cevap: evet, o yüzden o adımda sır kullanılmaz. Modern çözüm yönetilen kimliktir (managed identity / workload identity): uygulamanın çalıştığı altyapı bileşenine — sanal makineye, konteynere, Kubernetes servis hesabına — platform tarafından bir kimlik atanır. Uygulama kasaya bağlanırken bir parola sunmaz; platformun verdiği kısa ömürlü bir jetonu kullanır ve o jeton uygulamanın hiçbir yerinde saklanmaz.
Klasik (paradoks): [uygulama] --(kasa parolası: NEREDE?)--> [kasa] --> sırlar
Yönetilen kimlik : [platform] --(kısa ömürlü jeton, otomatik)--> [uygulama] --> [kasa] --> sırlar
↑ kimlik altyapıya bağlıdır; kopyalanabilir bir dosya değildir
Yönetilen kimlik yoksa (kurum içi sunucu, eski altyapı) paradoks tamamen çözülmez ama küçültülür: tek bir önyükleme sırrı (bootstrap) kalır, o da makineye özel, dar yetkili ve kısa ömürlü olur; geri kalan onlarca sır kasadadır. Kritik nokta şudur: bir sırrı çok sayıda sırla değiştirmek yerine tek bir dar kapıya indirmek — 1. dersteki saldırı yüzeyini küçültme ilkesi.
Kasa kullanımının iki üretim ayrıntısı: sırlar önbelleklenir (her istekte kasaya gitmek hem gecikme hem oran sınırı sorunudur) ama süresiz değil — döndürme etkisiz kalmasın diye TTL konur; ve kasa erişimi en az yetkiyle verilir: uygulama yalnız kendi sırlarını okur, listeleyemez ve yazamaz.
06Sır döndürme — en çok atlanan kısım
Sırlar süresiz yaşamaz. Döndürme (rotation) üç sebeple yapılır: bir sızıntı şüphesi, personel değişikliği ve rutin hijyen (sızıntının fark edilmediği durumlarda pencereyi daraltmak). Kurumsal politikalarda genelde bir süre tanımlıdır.
Zor olan kısım kesintisiz döndürmedir. Naif yaklaşım — "eski sırrı sil, yenisini koy" — çalışan uygulamaları anında düşürür. Doğru desen iki anahtar dönemidir:
1) Yeni anahtar ÜRETİLİR; sistem artık ikisini de KABUL eder (doğrulama tarafı)
2) Üreticiler yeni anahtara geçirilir (imzalama/bağlanma tarafı)
3) Eski anahtarla üretilmiş her şeyin ömrü dolana kadar BEKLENİR
4) Eski anahtar KALDIRILIR ve iptal edilir
Bu deseni bu hattın üç yerinde zaten gördün:
- JWT imza anahtarı (5. ders): başlıktaki
kidhangi anahtarın kullanıldığını söyler; doğrulayıcı bir süre iki anahtarı birden geçerli tutar. 6-7. dersteki JWKS ucu birden çok anahtar yayınlayarak bunu mümkün kılar — istemcinin bilmediği birkidgördüğünde JWKS'i tazelemesi kuralı tam da bu geçiş içindir. - TLS sertifikası (2. ders): ACME ile otomatik yenilenir; unutulan yarısı, sürecin yeni dosyayı yeniden okumasıdır.
- Veritabanı parolası: iki kimlik bilgisi dönüşümlü kullanılır (uygulama A parolasıyla çalışırken B döndürülür, sonra geçilir). Tek kullanıcıyla çalışan sistemlerde döndürme kaçınılmaz olarak kısa bir kesinti üretir — bu yüzden döndürülebilirlik bir tasarım kararıdır, sonradan eklenmez.
Uygulama tarafındaki kural: sır açılışta bir kez okunup sonsuza kadar bellekte tutulmamalıdır. Dosyadan okuyan bir tasarım (4. bölüm) ya da TTL'li kasa önbelleği, döndürmeyi yeniden başlatma gerektirmeden mümkün kılar. Aksi hâlde her döndürme bir dağıtım demektir — ve bu, döndürmenin hiç yapılmamasının en yaygın sebebidir.
07Sır taraması ve git geçmişi gerçeği
Sırların depoya sızmasının önlenmesi iki katmanlıdır. Önleyici: commit öncesi çalışan bir kanca (hook) ve düzenli ifade/entropi tabanlı bir tarayıcı, şüpheli değerleri commit edilmeden yakalar. Tespit edici: boru hattında (18. hat) her değişiklikte ve periyodik olarak tüm geçmiş taranır; birçok kod barındırma platformu bilinen anahtar biçimlerini kendiliğinden tarar ve sağlayıcıya haber verir.
Şimdi acı gerçek. Bir sır depoya girdiyse, onu silmek yeterli değildir — hatta ikincil bir iştir. Sebebi git'in çalışma biçimidir:
- Sır geçmişte durur; sonraki bir commit'te silmek onu kaldırmaz,
git log -pile hâlâ okunur. - Depo klonlanmıştır: her geliştiricinin makinesinde, her CI önbelleğinde, her yedekte, çatallanmış kopyalarda bir nüshası vardır.
- Geçmişi yeniden yazmak (
filter-repobenzeri araçlarla) tüm commit kimliklerini değiştirir; herkesin deposunu yeniden klonlaması gerekir, açık dallar ve incelemeler bozulur — ve uzak platformdaki önbellekler bir süre erişilebilir kalabilir.
Bu yüzden doğru sıra şudur ve tersi yapıldığında zaman kaybedilir:
1) SIRRI DERHAL İPTAL ET / DÖNDÜR ← tek gerçek çözüm budur
2) Kötüye kullanım var mı diye erişim kayıtlarını incele
3) Yeni sırrı kasaya koy, uygulamaları geçir
4) (Gerekiyorsa) geçmişi temizle — ama bunu 1. adımın YERİNE değil, ARDINDAN yap
5) Nasıl girdiğini bul: tarama neden yakalamadı, hangi adım eksikti
Zihinsel model tek cümledir: sızmış bir sır, artık bir sır değildir — yapılacak şey onu saklamaya çalışmak değil, geçersiz kılmaktır.
08Kimlik bilgilerinde en az yetki
Sır yönetiminin görünmeyen yarısı, sırrın ne kadar yetki taşıdığıdır. Mükemmel saklanan bir sır, aşırı yetkiliyse yine felaket üretir. 1. dersteki en az yetki ilkesinin somut karşılıkları:
- Veritabanı: uygulama
db_owner/superuserile bağlanmaz; kendi şemasında yalnız gereken işlemleri yapan bir kullanıcı kullanılır. Göç (migration) işlemleri ayrı ve daha yetkili bir kimlikle, yalnız dağıtım sırasında çalışır (7. hat). - Ortam ayrımı: geliştirme, test ve üretim ayrı kimlik bilgileri kullanır. Aynı anahtarın her ortamda kullanılması, en zayıf ortamın güvenliğini üretime taşır.
- Üçüncü taraf anahtarları: sağlayıcı kapsam desteği veriyorsa (yalnız gönderme, yalnız okuma) dar kapsam seçilir; IP kısıtı varsa uygulanır.
- Paylaşılan hesap yoktur. Her servis ve her kişi kendi kimliğiyle erişir; aksi hâlde denetim izi anlamını yitirir ve personel değişiminde döndürme imkânsızlaşır.
Son olarak bağlantı dizesi özel bir dikkat ister: içinde hem yapılandırma (sunucu, veritabanı adı) hem sır (parola) vardır. İkisini ayırmak — sunucu adını yapılandırmadan, parolayı sırdan almak — hem sızıntı yüzeyini küçültür hem döndürmeyi kolaylaştırır. Mümkünse parola hiç kullanılmaz: bulut veritabanlarında yönetilen kimlikle bağlanmak, sırrı tamamen ortadan kaldırır ve döndürülecek bir şey bırakmaz — en iyi sır, var olmayan sırdır.
09Mini alıştırma — sırrı taşı, sızdır, döndür
Yaklaşık 20 dakika · .NET veya Node projen + Docker (varsa)
- Sırrı projeden çıkar. .NET tarafında bağlantı dizesini
appsettings.json'dan alıpdotnet user-secrets setile taşı; kodun hiç değişmediğini doğrula. Node tarafında aynı değeri.env'e taşı,.env.exampleoluştur (yalnız anahtar adları) ve.gitignore'a ekle. Sonragit add -f .envdeneyip.gitignore'un neden yeterli bir savunma olmadığını gör. - Ortam değişkenini sızdır. Uygulamayı bir sırla başlat ve kendi
süreç kimliğiyle
cat /proc/<pid>/environ | tr '\0' '\n' | grep -i parolaçalıştır. Docker kullanıyorsandocker inspect <kap>çıktısında sırrı düz metin bul. Son olarak uygulamadan bir alt süreç başlatıp (child_processya daProcess.Start) o sürecin de aynı ortamı gördüğünü kanıtla. - Dosyaya geçir. 4. bölümdeki
_FILEdesenini uygula: sırrı bir dosyaya koy, uygulamaya yolu ver. Süreç ortamında artık görünmediğini doğrula. Sonra dosyanın içeriğini uygulama çalışırken değiştir ve yeni değeri yeniden başlatmadan okuyabilecek şekilde kodu düzenle — bu, 6. bölümdeki döndürmenin ön koşuludur. - Anahtar döndürmeyi simüle et. 5. dersteki JWT örneğine dön: iki
imzalama anahtarı tanımla (
kid: "a"vekid: "b"). Doğrulayıcıyı ikisini de kabul edecek şekilde yaz, üreticiyia'danb'ye geçir veaile imzalanmış eski jetonların hâlâ çalıştığını gör. Ardındana'yı kaldır ve eski jetonların reddedildiğini doğrula. Dört adımı kendi cümlelerinle yaz. - Geçmiş gerçeğini gör. Deneme deposunda bir dosyaya sahte bir anahtar
yaz ve commit et. Sonraki commit'te sil.
git log -pile anahtarın hâlâ okunabildiğini göster. "Ne yapmalıydım?" sorusunun cevabını sırayla yaz — ilk maddenin "geçmişi temizle" olmadığını vurgula. - Yetkiyi daralt. Veritabanı bağlantında kullandığın kullanıcının
yetkilerini listele. Uygulamanın gerçekten ihtiyaç duyduğu asgari yetkileri
çıkar ve yeni bir kullanıcı oluştur; göç işlemleri için ayrı bir kimlik tanımla.
Uygulamanın bu dar kullanıcıyla çalıştığını doğrula ve
DROP TABLEdenemesinin reddedildiğini gör.
10Kendini sına
Sır ile yapılandırma farkı nedir? .NET user secrets tam olarak ne yapar, ne yapmaz? .gitignore neden yeterli bir savunma değildir?
Yapılandırma davranışı belirleyen değerdir (zaman aşımı,
sayfa boyutu, sunucu adı) ve depoda durabilir, gözden geçirilir. Sır bir
kimlik bilgisidir: onu bilen o yetkiyi kullanabilir, dolayısıyla depoda
duramaz — depoya giren değer klonlayan herkeste, tüm CI çalışmalarında, yedeklerde ve
geçmişin tamamında vardır. user secrets sırları şifrelemez;
yaptığı şey onları proje klasörünün dışına, kullanıcı profilindeki bir JSON
dosyasına taşımaktır — böylece yanlışlıkla commit edilmeleri yapısal olarak imkânsız
olur. Yalnız geliştirme içindir. Asıl fikir yapılandırma sağlayıcı zinciridir:
aynı anahtar geliştirmede user secrets'tan, üretimde ortam değişkeninden ya da kasadan
gelir — kod değişmez, kaynak değişir; ve eksik sır açılışta fark edilip hızlı
çökülür. .gitignore yetmez çünkü dosya bir kez izlenmeye
başlandıysa onu durdurmaz ve git add -f ile aşılabilir; asıl savunma
commit öncesi tarama ve boru hattındaki sır taramasıdır.
Ortam değişkeni sırrı nereden sızdırır (en az dört yol)? Dosya olarak bağlamanın üç avantajı nedir?
Sızma yolları: (1) süreç ortamı okunabilir —
/proc/<pid>/environ; aynı kullanıcı ya da root tüm ortamı görür,
konteynerde bir kabuk erişimi tüm sırları verir; (2) konteyner meta verisi —
docker inspect ve orkestratör nesne tanımları ortamı düz metin
gösterir, kayıtlara ve yedeklere de öyle girer; (3) alt süreçlere miras —
uygulamanın başlattığı her süreç ortamın tamamını devralır; (4) hata bağlamı —
birçok hata izleme aracı çökmede ortam değişkenlerini rapora ekleyip dış bir
servise gönderir; (5) çekirdek/bellek dökümü; (6) log ve komut
geçmişi — printenv, hata ayıklama yazdırmaları,
docker run -e SIR=... komutunun kabuk geçmişi ve süreç listesi.
Dosya olarak bağlamanın avantajları: süreç ortamında görünmez; alt süreçlere
miras kalmaz; ve döndürüldüğünde dosya içeriği değişir, böylece süreç yeniden
başlatılmadan yeni değer okunabilir. Hangi yol seçilirse seçilsin sırlar loglanmaz:
password, authorization, token,
secret, connectionstring redaksiyon listesine girer ve
hata yanıtlarına yapılandırma nesnesi konmaz.
Kasa ortam değişkenine göre ne kazandırır? "Kasaya bağlanmak için de sır gerekmez mi" paradoksu nasıl çözülür?
Kasa üç şey kazandırır: erişim politikası (kim hangi sırrı okuyabilir), denetim izi (her erişim kaydedilir — STRIDE'ın R harfi) ve döndürme desteği. Paradoks gerçektir: kasaya bağlanmak için bir kimlik bilgisi gerekir ve onu saklamak sorunu bir adım öteye taşır. Çözüm, o adımda sır kullanmamaktır: yönetilen kimlik (managed/workload identity) ile uygulamanın çalıştığı altyapı bileşenine — sanal makine, konteyner, Kubernetes servis hesabı — platform tarafından bir kimlik atanır; uygulama kasaya parola değil, platformun verdiği kısa ömürlü bir jetonu sunar ve o jeton hiçbir yerde saklanmaz. Yönetilen kimlik yoksa paradoks tamamen çözülmez ama küçülür: tek bir dar yetkili, makineye özel önyükleme sırrı kalır, geri kalan onlarca sır kasadadır — yani bir sırrı çok sayıda sırla değiştirmek yerine tek bir dar kapıya indirmiş olursun. Üretim ayrıntıları: sırlar önbelleklenir ama TTL ile (yoksa döndürme etkisiz kalır) ve kasa erişimi en az yetkiyle verilir — uygulama yalnız kendi sırlarını okur, listeleyemez ve yazamaz.
Sır döndürmenin dört adımı nedir ve bu deseni bu hatta nerede gördün? Sır depoya sızdıysa ilk yapılacak şey nedir, neden?
İki anahtar dönemi: (1) yeni anahtar üretilir ve sistem
ikisini birden kabul eder; (2) üreticiler yeni anahtara geçirilir; (3) eskiyle
üretilmiş her şeyin ömrü dolana kadar beklenir; (4) eski anahtar kaldırılır ve iptal
edilir. Bu hatta üç yerde göründü: JWT imza anahtarı — kid ile
hangi anahtarın kullanıldığı belirtilir, JWKS birden çok anahtar yayınlar ve
doğrulayıcı bilinmeyen kid'de JWKS'i tazeler; TLS sertifikası —
ACME ile otomatik yenilenir, unutulan yarısı sürecin dosyayı yeniden
okumasıdır; veritabanı parolası — iki kimlik bilgisi dönüşümlü kullanılır.
Uygulama kuralı: sır açılışta bir kez okunup sonsuza kadar bellekte tutulmaz, yoksa
her döndürme bir dağıtım demektir — döndürmenin hiç yapılmamasının en yaygın sebebi
budur. Sızıntıda ilk iş: sırrı derhal iptal et / döndür. Silmek yetmez çünkü
sır geçmişte durur (git log -p ile okunur), depo herkeste
klonlanmıştır (CI önbellekleri, yedekler, çatallar) ve geçmişi yeniden yazmak tüm
commit kimliklerini değiştirip herkesi yeniden klonlamaya zorlar — üstelik uzak
platform önbellekleri bir süre erişilebilir kalabilir. Sıra: iptal → erişim
kayıtlarını incele → yeni sırrı kasaya koy → gerekiyorsa geçmişi temizle → nasıl
girdiğini bul. Tek cümle: sızmış bir sır artık sır değildir; saklanmaz, geçersiz
kılınır.
11Sınav köşesi
Yazılıda nasıl sorulur
(1) Sır (secret) ile yapılandırma arasındaki fark nedir? (2) Sırlar neden kod
deposunda tutulmaz? (3) .NET user secrets nedir, üretimde kullanılır mı?
(4) Configuration provider zinciri nasıl çalışır? (5) Ortam değişkeninin güvenlik
zayıflıkları nelerdir? (6) Sırları dosya olarak bağlamanın avantajı nedir?
(7) Key Vault / Vault ne işe yarar? (8) Managed identity nedir, hangi problemi
çözer? (9) Secret rotation nasıl kesintisiz yapılır? (10) JWT imza anahtarı
rotasyonunda kid ve JWKS'in rolü nedir? (11) Bir sır repoya
commit'lendiyse ne yapılmalıdır? (12) Uygulamanın veritabanı kullanıcısı hangi
yetkilere sahip olmalıdır? (13) Bağlantı dizesi nasıl yönetilmelidir?
Sözlüde nasıl anlatılır — 2 dakikalık taslak
Düzen: (1) Ayrım — "Yapılandırma depoda durabilir, sır duramaz: sır bir kimlik
bilgisidir ve depoya girdiği anda tüm klonlarda, CI önbelleklerinde, yedeklerde ve
geçmişin tamamında vardır." (2) Katmanlar — "Geliştirmede .NET user
secrets ya da .gitignore'lu .env + değer içermeyen bir
.env.example; CI'da boru hattının sır deposu; üretimde kasa. Kod
değişmez, yalnız yapılandırma kaynağı değişir; eksik sırda açılışta hızlı çökerim."
(3) Ortam değişkeni — "Sırrı depodan çıkarır ama kasa değildir:
/proc/<pid>/environ, docker inspect, alt süreç
mirası, hata izleme araçlarının çökme raporuna ortamı eklemesi ve bellek dökümleri.
Bu yüzden üretimde sırrı dosya olarak bağlamayı tercih ederim — ortamda
görünmez, miras kalmaz ve döndürüldüğünde yeniden başlatmadan okunabilir."
(4) Kasa — "Kasa erişim politikası, denetim izi ve döndürme verir. 'Kasaya
bağlanmak için de sır gerekmez mi' sorusunu yönetilen kimlikle çözerim:
kimlik altyapıya bağlıdır, kopyalanabilir bir dosya değildir; yoksa da tek bir dar
önyükleme sırrına indiririm." (5) Kıdem vuruşu — "İki şeyi vurgularım. Birincisi
döndürme bir tasarım kararıdır: iki anahtar dönemi kurulmazsa döndürme
kesinti demektir ve hiç yapılmaz; JWT'de bunu kid + JWKS ile,
sertifikada ACME + reload ile, veritabanında iki kimlik bilgisiyle yaparım.
İkincisi sızmış sır artık sır değildir: ilk iş geçmişi temizlemek değil,
sırrı iptal etmektir — geçmiş temizliği ancak ondan sonra gelir. Ve en iyi
sır var olmayan sırdır: bulut veritabanına yönetilen kimlikle bağlanırsam
döndürülecek bir şey de kalmaz."
