Bulut Altyapı

Cosmos DB Güvenliği: Yeni Projede İlk Gün Kararları

Bir Cosmos DB hesabı açtınız. Portal size iki tane key ve bir connection string verdi. Uygulama da çalıştı. Sonra ne oldu? Büyük ihtimalle o connection string’i bir appsettings.Development.json dosyasına yapıştırdınız, “production’da düzeltirim” dediniz, iş bitti.

Tanıdık geldi mi? Bana da geldi. Hatta bir keresinde, finans tarafında orta ölçekli bir fintech müşterimde tam bu senaryoyu yaşadık; üç yıl önce yazılmış bir mikroservis hâlâ primary key ile Cosmos’a bağlanıyordu, key rotation işe hiç yapılmamıştı,. Hangi servisin o key’i kullandığını kimse net bilmiyordu.

İşte bu yazı bunun için. Yeni bir Cosmos DB projesine başlıyorsanız, ilk gün almanız gereken güvenlik kararlarını konuşalım. Enterprise karmaşasına dalmadan ama “sonra düzeltirim” tuzağına da düşmeden.

Önce dürüst bir tehdit modeli yapalım

Açık konuşayım: gerçek hayatta Cosmos DB hesaplarına yapılan saldırılar film sahnesi gibi olmuyor. Hani sıfırıncı gün açıkları, devlet destekli APT grupları falan… öyle şeyler nadir. Olan şu:

  • Bir geliştirici .env dosyasını yanlışlıkla public repo’ya pushluyor. Connection string orada duruyor. Bot 12 dakika içinde buluyor.
  • Uygulamaya gereğinden fazla yetki veriliyor. Read-only olması gereken analytics servisi, yanlışlıkla DELETE de yapabiliyor.
  • Cosmos DB endpoint’i tüm internete açık bırakılıyor. Bir credential sızarsa, saldırgan ile veriniz arasında pek bir şey kalmıyor.
  • Client’tan gelen JSON körü körüne kabul ediliyor. 5 MB’lık dokümanlar, sınırsız query’ler… sonra performans niye düştü diye bakılıyor.
  • Diagnostic log kapalı oluyor. Olay yaşanınca “kim, ne zaman, neyi okudu?” sorusuna cevap yok. Tahmin yürütüyorsunuz.

Yani işin aslı şu: pahalı bir güvenlik aracı almadan da çok şey yapılır. Basit hataları yapmamak çoğu zaman yeterli oluyor — ama bunun için ilk günden doğru karar vermek gerekiyor.

“Production’da düzeltirim” diye başlayan her config, çoğu zaman production’a aynen gidiyor. Bunu kariyerimde defalarca gördüm — maalesef ben de yaptım.

Anahtarlar mı, Entra ID mi? İşte can alıcı nokta burada

Cosmos DB hesabı oluşturduğunuzda size dört key veriyor: primary, secondary, read-only primary ve read-only secondary. Bunlar hemen çalışıyor, her tutorial’da var, o yüzden insanlar doğal olarak bunlara sarılıyor. Sorun da tam burada başlıyor.

Key’lerin asıl sıkıntısı: Kim kullandı?

Key’ler aslında birer bearer token. Kim eline geçirirse yetki onun oluyor. Diagnostic logging açıksa IP adresi ya da user agent gibi şeyleri görebilirsiniz ama “Ahmet mi yaptı, Mehmet mi?” sorusunun cevabı çıkmıyor; çünkü key paylaşılıyor ve beş servis aynı key’i kullanıyorsa hangisinin yaptığı belli olmuyor.

Bir de key sızınca ne oluyor? Tek çare regenerate etmek. Sonra o key’i kullanan her sistemi tek tek güncelleyeceksiniz. Geçen sene bir telekom projesinde bunu yaşadık; toplam 23 servis bağımlıydı ve 4 tanesini unutmuşuz, prod’da yarım gün kesinti yedik (evet, doğru duydunuz). Hiç hoş değildi.

Peki Entra ID neden daha mantıklı?

Entra ID (eski adıyla Azure AD) ile uygulamanız bir kimlik kazanıyor — managed identity veya service principal gibi düşünün. O kimliğe sadece gereken yetkileri veriyorsunuz. Sızıntı olursa? Kimliği devre dışı bırakıyorsunuz; başka hiçbir sistemi update etmeniz gerekmiyor ve audit log’da kim ne yaptı net görünüyor.

Tavsiyem: Daha development ortamında bile Entra ID ile başlayın. Setup sandığınız kadar zor değil; üstüne bir sürü dertten kurtarıyor sızı.

//.NET ile Entra ID kullanımı — bu kadar basit
using Azure.Identity;
using Microsoft.Azure.Cosmos;
var credential = new DefaultAzureCredential();
var cosmosClient = new CosmosClient(
accountEndpoint: "https://your-account.documents.azure.com:443/",
tokenCredential: credential
);
// Connection string yok. Key yok. Sızıntı riski azalıyor.

Local development’ta DefaultAzureCredential, Azure CLI ya da Visual Studio login’ınızı kullanıyor; production’da işe managed identity devreye giriyor. Tek satır kod gibi duruyor ama arkada işi bayağı toparlıyor.

Yetkilendirme: Uygulamanız tam olarak ne yapabilmeli?

Cosmos DB’de iki farklı erişim katmanı var ve bunları karıştırmak çok yaygın bir hata:

Katman Neyi kontrol ediyor? Nasıl yönetiliyor?
Control plane Hesap/database/container oluşturma, silme ve ayar değiştirme Azure RBAC (IAM üzerinden)
Data plane Doküman okuma, yazma ve query çalıştırma Cosmos DB veri rolleri

Sizin uygulamanızın data plane’e ihtiyacı var. Control plane’e değil. Ama insanlar genelde “Cosmos DB Contributor” rolü verip geçiyor — bu ciddi risk yaratabiliyor çünkü o rol container silebilir, throughput’u sıfırlayabilir, başka şeyler de yapabilir. Uygulama niye bunları yapsın ki?

Builtin data rolü var; çoğu zaman biri yeterli oluyor

  • Cosmos DB Built-in Data Reader: Sadece okuma yapar. Analytics ve reporting servisleri için uygun.
  • Cosmos DB Built-in Data Contributor: Okuma + yazma yapar. Asıl uygulama servisi için kullanılır.

Biri e-ticaret projesinde şöyle ayırmıştık: sipariş alma servisi Data Contributor kullanıyordu, raporlama dashboard’u Data Reader ile çalışıyordu, admin paneli işe Control Plane Contributor almıştı ama sadece spesifik admin kullanıcıları için. Üç ayrı identity, üç ayrı yetki… Saldırgan reporting servisine sızsa bile veriyi değiştiremiyordu; işte blast radius dediğimiz şey biraz bu.

Ve işler burada ilginçleşiyor.

Ağ erişimi: Internet’e açık bırakmayın, lütfen

Kosmos DB endpoint’ınız varsayılan olarak tüm internete açık geliyor mu? Evet geliyor gibi düşünebilirsiniz; endpoint URL’sını bilen herkes deneme yapabiliyor (inanın bana). Key ya da token olmadan zaten çok ileri gidemez ama credential leak olursa tek savunma hattınız o key kalıyor — bu da pek rahatlatıcı değil.

Peki hangi seçenek size uyuyor?

1. IP firewall: En basit yöntem bu. Belirli IP aralıklarından erişim açarsınız; küçük ekipseniz veya Azure dışında host edilen bir backend’ınız varsa mantıklı başlangıç ölür. Bu konuyla ilgili AKS Fleet Manager Cross-Cluster Networking: Saha Notları yazımıza da göz atmanızı tavsiye ederim.

Açıkçası, 2. VNet service endpoint: Azure içinde VNet’ınız varsa Cosmos DB’ye sadece o VNet’ten erişim açarsınız. Trafik Microsoft backbone üzerinden akar; internet tarafına çıkmazsınız (ben de ilk duyduğumda şaşırmıştım) Bu konuyla ilgili Kubernetes CVE Kayıtları Düzeltiliyor: Sahadan Notlar yazımıza da göz atmanızı tavsiye ederim.

3. Private endpoint: En sıkı çözüm bu diyebilirim. Cosmos DB hesabınız VNet’inizin içinde özel IP alır ve public endpoint’i tamamen kapatabilirsiniz; enterprise projelerde biz bunu standart sayıyoruz artık.

💡 Bilgi: Türkiye’deki kurumsal müşterilerde gördüğüm kadarıyla finans ve sağlık sektöründe private endpoint artık opsiyon gibi durmuyor — regülasyon yüzünden neredeyse şart oluyor. KVKK uyumluluğunda “veri Azure’da ama internete açık” yaklaşımı denetimde sorun çıkarabiliyor. Startup tarafında işe IP firewall + Entra ID ile gayet idare edebilirsiniz ilk aşamada.

Peki loglama? Olay olmadan açmazsanız geç kalırsınız

Açıkçası, Burası kritik ama çoğu ekip atlıyor işte burayı. Diagnostic logging açık değilse güvenlik olayı yaşandığında elinizde kanıt kalmıyor; “sanırım şu olmuş”, “muhtemelen bu olmuş” diye konuşuyorsunuz adeta adlı analiz yerine tahmin oyunu oynanıyor. Entra External ID Native Auth: Apple Watch RT Transferi GA yazımızda bu konuya da değinmiştik.

Açmanız gereken Cosmos DB log kategorileri şunlar: Bu konuyla ilgili Visual Studio Mayıs Güncellemesi: Plan, İncele, İyileştir yazımıza da göz atmanızı tavsiye ederim. GitHub Copilot’u.NET’te Verimli Kullanma Rehberi yazımızda bu konuya da değinmiştik.

  1. User request logs / DataPlaneRequests: Her okuma-yazma operasyonu burada görünür; hangi IP’den gelmiş, hangi identity kullanılmış, ne zaman olmuş hepsi çıkar.
  2. QueryRuntimeStatistics:: Çalıştırılan query’leri gösterir; performans tarafında da işe yarar hani.
  3. :ControlPlaneRequests:: Ayar değişikliklerini yakalar; biri throughput’u 100K RU’ya çektiyse burada görünür.

Oops!

Sıkça Sorulan Sorular

Cosmos DB key authentication’ı tamamen kapatabiliyor muyum?

Doğrusu, Evet, “disableLocalAuth” özelliğiyle key authentication’ı tamamen devre dışı bırakabiliyorsun. Bu durumda yalnızca Entra ID üzerinden bağlantı kabul ediliyor. Açıkçası production hesapları için neredeyse kesinlikle öneriyorum. Ama önce mevcut bağlantılarının Entra ID’ye geçtiğinden emin ol — yoksa servislerinin çökeceğini söylemek zorundayım (evet, doğru duydunuz)

Managed identity ile bağlantı local development’ta da çalışıyor mu?

Çalışıyor. DefaultAzureCredential, hani Azure CLI’dan (az login), Visual Studio ya da VS Code’dan login bilgilerini otomatik alıyor (buna dikkat edin). Yani local’de kendi kullanıcınla, prod’da managed identity ile bağlanıyorsun — kod aynı kalıyor, bu kısmı gerçekten şık. Tek koşul şu: kendi kullanıcına da geliştirme ortamı için ilgili Cosmos rolünü vermen gerekiyor.

Private endpoint kullanırsam maliyet ne kadar artıyor?

Aslında, Private endpoint’in kendisi saatlik ücretlendiriliyor. Ay sonunda aşağı yukarı 7-8 USD civarında bir ek fatura görüyorsun, endpoint başına. Bir de veri transfer ücreti var, ama VNet içi trafik ücretsiz. Bence küçük ölçekli bir uygulamada görmezden gelinebilecek bir maliyet — karşılığında aldığın güvenlik kazancı düşünülünce aslında oldukça makul.

Birden fazla servisim aynı Cosmos hesabına erişiyor, hepsine ayrı identity mi vereyim?

Şöyle ki, Evet, kesinlikle ayrı ver. Her servis kendi managed identity’sine sahip olmalı. Tecrübeme göre bunun üç somut faydası var: bir servis ele geçirildiğinde diğerleri etkilenmiyor, log’larda hangi servisin ne yaptığı net görünüyor. Yetkileri servis bazında ince ayar yapabiliyorsun. Tek bir “shared identity” kullanmak, yani mesela herkese aynı kimliği vermek, klasik bir anti-pattern.

Diagnostic log’ları ne kadar süre saklamalıyım?

Sektörüne ve regülasyonlarına bağlı değişiyor. KVKK kapsamında kişisel veri işleyen sistemler için en az 2 yıl tavsiye ediliyor. Finans tarafında, yani BDDK için, bu süre 10 yıla kadar çıkabiliyor. Log Analytics’te 30 günlük retention ücretsiz, sonrası ek ücretli. Eski log’ları daha ucuz storage’a, mesela Archive tier’a, taşıyabilirsin — açıkçası bu yolu kullanmalarını öneririm.

Evet, doğru duydunuz.

Kaynaklar ve İleri Okuma

Araya gireyim: Azure Cosmos DB için RBAC Kurulumu — Microsoft Learn

Cosmos DB Private Endpoint Konfigürasyonu

Ne yalan söyleyeyim, Orijinal Yazı: Cosmos DB Security for New Apps — DevBlogs

Cosmos DB Güvenlik Genel Bakış

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

← Onceki Yazi
.NET MAUI Android'de Material 3: Tek Satırda Yenilenme
Sonraki Yazi →
A2A v1 Geldi: Agent'lar Artık Aynı Dili Konuşuyor

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İçindekiler
    ← .NET MAUI Android’de Mat...
    A2A v1 Geldi: Agent’lar ... →