Skip to content

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

OrtamDoğru yerYanlış 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/CDBoru hattının sır deposu (GitHub Actions secrets, Azure DevOps variable group). Loglarda maskelenirBoru hattı dosyasında düz metin; echo $SIR ile hata ayıklama
ÜretimKasa (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 yoluNasıl
Süreç ortamı okunabilirLinux'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 verisidocker 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 mirasUygulamanı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şiprintenv, 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 kid hangi 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 bir kid gö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 -p ile 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-repo benzeri 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/superuser ile 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)

  1. Sırrı projeden çıkar. .NET tarafında bağlantı dizesini appsettings.json'dan alıp dotnet user-secrets set ile taşı; kodun hiç değişmediğini doğrula. Node tarafında aynı değeri .env'e taşı, .env.example oluştur (yalnız anahtar adları) ve .gitignore'a ekle. Sonra git add -f .env deneyip .gitignore'un neden yeterli bir savunma olmadığını gör.
  2. 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ıyorsan docker inspect <kap> çıktısında sırrı düz metin bul. Son olarak uygulamadan bir alt süreç başlatıp (child_process ya da Process.Start) o sürecin de aynı ortamı gördüğünü kanıtla.
  3. Dosyaya geçir. 4. bölümdeki _FILE desenini 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.
  4. Anahtar döndürmeyi simüle et. 5. dersteki JWT örneğine dön: iki imzalama anahtarı tanımla (kid: "a" ve kid: "b"). Doğrulayıcıyı ikisini de kabul edecek şekilde yaz, üreticiyi a'dan b'ye geçir ve a ile imzalanmış eski jetonların hâlâ çalıştığını gör. Ardından a'yı kaldır ve eski jetonların reddedildiğini doğrula. Dört adımı kendi cümlelerinle yaz.
  5. Geçmiş gerçeğini gör. Deneme deposunda bir dosyaya sahte bir anahtar yaz ve commit et. Sonraki commit'te sil. git log -p ile 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.
  6. 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 TABLE denemesinin 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."