Cosmos DB Dynamic Data Masking: Veri Güvenliğinde Yeni Dönem
Geçen ay bir finans kuruluşunun Cosmos DB altyapısını denetlerken ekip liderine sordum: “Destek mühendisleri production veritabanını sorgularken müşteri TC kimlik numaralarını görebiliyor mu?” Cevap, tahmin ettiğim gibiydi; evet, herkes her şeyi görüyordu. Klasik hikâye. Hani şu “herkesin admin olduğu” ortamlardan bahsediyorum… İşte tam da bu tip senaryolar için Microsoft’un uzun süredir beklenen özelliği nihayet GA öldü: Azure Cosmos DB için Dynamic Data Masking.
Açık konuşayım, bu özellik SQL Database tarafında yıllardır vardı. Cosmos DB’ye gelmesi biraz geç kaldı bence. Ama geldi işte; şimdi bakalım ne sunuyor, nerede işe yarıyor ve nerede biraz idare eder kalıyor.
Dynamic Data Masking Tam Olarak Ne Yapıyor?
DDM dediğimiz şey, aslında göz boyamadan ibaret değil. Hassas alanları yetkisiz kullanıcıdan saklıyor, ama verinin kendisine dokunmuyor; sorgu çalıştığı anda, yanı query execution sırasında, sonuç tarafında maske basıyor.
Kısa hali şu. Asıl veri yerinde dürüyor. Sadece dışarı çıkan görüntü değişiyor.
Kendi deneyimimden konuşuyorum, Bunu bir kredi kartı numarası gibi düşünün. Yetkiniz varsa tam değeri görüyorsunuz, yoksa “4532-XXXX-XXXX-1234” gibi bir çıktı geliyor; garip. Işe yarıyor, çünkü amaç zaten veri tabanını karıştırmadan görüneni kısmak.
Ama Neden Sunucu Tarafında Olması Önemli?
Açık konuşayım, Bakın şimdi, 2021’de bir e-ticaret işinde uygulama katmanında maskeleme yapıyorduk. Her mikroservis kendi kafasına göre davranıyordu, biri başka yazılmıştı, öteki biraz aceleye gelmişti; sonra bir servis güncellendi ve maskeleme kodu aradan kaynadı, destek ekibi de müşteri kredi kartı bilgilerini üç gün boyunca açık açık gördü.
Dürüst olmak gerekirse, Kötü tarafı neydi biliyor musunuz? Kimse ilk anda anlamadı. Güvenlik denetimi gelene kadar olayın üstüne gidilmedi; işte o yüzden sunucu tarafı maskeleme bence bayağı iş görüyor, çünkü uygulama kodu değişse de, yeni SDK gelse de, farklı client bağlansa da kural orada kalıyor.
Cosmos DB bunu kendi içinde hallediyor. Nokta.
Tabi her şey pürüzsüz değil. Performans tarafında ne oluyor, hangi maskeleme tipleri destekleniyor, RBAC ile nasıl konuşuyor — bunlara birazdan gireceğim; hatta bazen beklediğinizden farklı davranabiliyor, o yüzden göz ucuyla geçmemek lazım.
Kurulum: Portal Üzerinden Adım Adım
Kurulum, açık konuşayım, baya kolay. Hatta beklediğimden de rahat ilerliyor. Azure Portal’da Cosmos DB hesabınıza giriyorsunuz, Settings altındaki Features sekmesine geçiyorsunuz. Dynamic Data Masking’i enable ediyorsunuz. Sonra da maskeleme kurallarını tek tek tanımlıyorsunuz.
İşin özü şu: bir kuralın içinde birkaç parça bilgi oluyor, ama gözünüzü korkutmasın, aslında düzen basit kalıyor. Database adı, container adı, maskelenecek JSON path. Hangi maskeleme fonksiyonunun kullanılacağı yeterli oluyor; geri kalan kısmı biraz sizin senaryoya göre şekilleniyor.
| Parametre | Açıklama | Örnek |
|---|---|---|
| Database | Hedef veritabanı adı | CustomerDB |
| Container | Hedef container adı | Users |
| Property Path | Maskelenecek JSON path | /personalInfo/tcNo |
| Masking Function | Maskeleme türü | Default, Number, Text, Custom String |
Dört farklı maskeleme fonksiyonu var. Default olan string alanlarda “XXXX” gibi bir değer dönduruyor, Number sayısal değeri sıfıra çekiyor, Text ile prefix-suffix tanımlayabiliyorsunuz, Custom String tarafında işe iş biraz daha esniyor. Kendi kuralınızı yazabiliyorsunuz. Bu arada hepsi aynı anda lazım olmayabilir, yanı senaryoya göre biri gayet yeterli geliyor.
Peki neden? Çünkü her alanı aynı şekilde gizlemek mantıklı değil. Mesela TC numarasıyla yaş bilgisini aynı kefeye koyarsanız işler karışıyor; biri bayağı kapanmalı, diğeri sadece anlamını koruyacak kadar değişmeli. Neyse, çok dağıtmayayım.
RBAC Entegrasyonu: İşin Can Alıcı Noktası
Bakın, Maskeleme kuralını tanımladınız diyelim. Güzel. Ama asıl soru şu oluyor: kim gerçek veriyi görecek, kim maskelenmiş hâliyle yetinecek? Cosmos DB burada role-based access control kullanıyor; kullanıcının rolünde “unmask” yetkisi varsa gerçek veri geliyor, yoksa maskelenmiş sürüm ekrana düşüyor.
Bunu Azure CLI ile şöyle yapabilirsiniz:
# Önce custom role tanımlayın — unmask yetkisi olan
az cosmosdb sql role definition create \
--account-name myCosmosAccount \
--resource-group myResourceGroup \
--body '{
"RoleName": "SensitiveDataReader",
"Type": "CustomRole",
"AssignableScopes": ["/"],
"Permissions": [{
"DataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/unmaskPolicy/read"
]
}]
}'
# Unmask yetkisi OLMAYAN rol
az cosmosdb sql role definition create \
--account-name myCosmosAccount \
--resource-group myResourceGroup \
--body '{
"RoleName": "MaskedDataReader",
"Type": "CustomRole",
"AssignableScopes": ["/"],
"Permissions": [{
"DataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read"
]
}]
}'
Gördüğünüz gibi can alıcı fark o unmaskPolicy/read permission’ında dürüyor (buna dikkat edin). Bu yetki varsa maskeleme devre dışı kalıyor; yoksa veri maskeli dönüyor. Basit gibi dürüyor ama bir düşüneyim… yönetim tarafında baya iş görüyor. Hani bazen küçük bir izin satırı tüm akışı değiştirir ya, işte tam öyle — dürüst olayım, biraz hayal kırıklığı — Node.js Addon’larını.NET Native AOT ile Yazmak yazımızda bu konuya da değinmiştik.
Evet. Daha fazla bilgi için Codex Kurumsal Ölçekte: Ne Vaat Ediyor, Ne Eksik? yazımıza bakabilirsiniz.
Türkiye’deki Kurumsal Yapılarda Bu Ne İfade Ediyor?
Daha açık söyleyeyim, dürüst olmak gerekirse, Şimdi asıl meseleye gelelim. Türkiye’de KVKK var ya, işte onun gölgesi zaten her yerde hissediliyor; veri maskeleme de artık “olsa iyi olur” seviyesinden çıkıp baya zorunlu bir şeye dönüştü. Ama sahada ne görüyorum? Çoğu ekip bunu uygulama tarafında, biraz yamalı bohça gibi çözmeye çalışıyor.
Açık konuşayım, Logosoft’ta çalıştığım bir bankacılık projesinde — tam 2023 sonlarıydı — KVKK denetimi kapıya dayanmıştı. Bir anda acil veri maskeleme ihtiyacı çıktı. Cosmos DB kullanıyorlardı, fakat DDM henüz preview aşamasındaydı. Ne yaptık peki? Uygulama katmanında middleware yazdık, her response’u tek tek süzdük; çalıştı mı, evet çalıştı, ama bakım yükü resmen can sıktı çünkü her yeni endpoint için kuralları yeniden tanımlamak gerekiyordu.
Şimdi DDM GA olduğuna göre, aynı projeye dönüp o middleware’leri sökebiliriz. Direkt Cosmos DB seviyesinde maskeleme yapmak (söylemesi ayıp) daha temiz dürüyor, hem kod sadeleşiyor hem de açık riski azalıyor. Bir taşla iki kuş diyeyim; hatta üç kuş da olur, çünkü denetim raporlaması da daha rahat hâle geliyor.
Eğer KVKK denetimlerine hazırlanıyorsanız, Dynamic Data Masking’i sadece bir güvenlik özelliği olarak değil, aynı zamanda bir compliance aracı olarak değerlendirin. Denetçilere “maskeleme veritabanı katmanında, merkezî olarak yönetiliyor” demek, “her serviste ayrı ayrı implement ettik” demekten çok daha güçlü bir pozisyon.
Enterprise vs Startup: Kime Ne Kadar Lazım?
Bu soruyu sık duyuyorum. Küçük bir startup için DDM lazım mı? Açık konuşayım, cevap biraz “duruma göre” (en azından benim deneyimim böyle). Işin özü çoğu zaman şu: önce ihtiyacı doğru okuyun, sonra özellik kovalamaya başlayın. SQL MCP Server: Veritabanını Ajanlara Açmanın Yolu yazımızda bu konuya da değinmiştik.
Şimdi gelelim işin can alıcı noktasına.
Araya gireyim: Küçük ekipseniz (5-10 kişi): Büyük ihtimalle herkes zaten birbirinin alanına giriyor. DDM kurmak fena değil, ama ilk gün şart da değil. Önce RBAC tarafını düzgün toparlayın, sonra DDM’e bakarsınız; bütçe sıkışıksa Cosmos DB’nın built-in RBAC yapısı bile başlangıç için gayet iş görüyor.
Şey, küçük ekiplerde başka bir gerçek daha var: çoğu zaman tek bir connection string dolaşıyor. Herkes aynı hesabı kullanıyor. DDM’in anlamlı çalışması için RBAC’ın sağlam kurulmuş olması gerekiyor, yanı önce kimlik ve erişim tarafını rayına oturtmanız lazım. Sız ne dersiniz? Evet, temel konu bu.
Enterprise seviyede (50+ geliştirici, destek ekipleri, analiz ekipleri): Burada tablo değişiyor. Bir telekom şirketini düşünün; yüzlerce geliştirici var, destek ekibi production veritabanına bakıyor, analiz ekibi rapor çekiyor (ve her biri farklı veri görüyor), işte o noktada DDM baya işe yarıyor. Onsuz yönetmek… nasıl desem, idare eder bir senaryo değil.
Performans ve Sınırlamalar: Gerçekçi Olalım
Her güvenlik katmanının bir faturası var, DDM de bundan kaçmıyor. Sunucu tarafında her sorgu sonucu işlenirken araya küçük bir adım giriyor, ama işin ilginci şu: Microsoft’un kendi testlerine göre etki “minimal” kalıyor. Ben bunu henüz büyük ölçekli bir production ortamında birebir sınamadım, o yüzden %100 emin değilim. Yine de preview döneminde kurduğum bir test ortamında bakınca, açık konuşayım, göze batan bir gecikme görmedim.
Şimdi sınırlamalar kısmına gelelim. Birkaç tane var, ve bunları baştan bilmek iyi oluyor: Bu konuyla ilgili AI Maliyet Optimizasyonu: ROI’yi Gerçekten Artırmanın Yolu yazımıza da göz atmanızı tavsiye ederim.
- Maskeleme sadece NoSQL API’de çalışıyor — yukarıda söylediğim gibi
- Nested JSON property’lerde path tanımlaması bazen kafa karıştırıcı olabiliyor
- Array içindeki alanlarda maskeleme kuralı tanımlamak biraz tricky
- Change feed üzerinden akan veri maskelenmemiş hâlde geliyor — bu çok kritik bir detay! — bunu es geçmeyin
- Cross-partition sorgularda maskeleme davranışı bazen beklenmedik sonuçlar verebiliyor (bunu kendi test ortamımda yaşadım)
Ha, bunu atlamayayım: Change feed konusu gerçekten önemli. Eğer change feed’i kullanıp başka bir sisteme veri aktarıyorsanız — mesela bir analitik pipeline’a — o tarafta veri maskelenmemiş şekilde gider. Yanı DDM’i tek başına güvenlik çözümü diye görmek biraz fazla iyimser olur. Katmanlı yaklaşım lazım. İşin aslı bu. Güvenlik mimarisini bütünüyle düşünmek gerekiyor; daha önce Azure DevOps Güvenlik Taraması: Tek Tıkla Başlıyor yazımda da güvenlik tarama araçlarından bahsetmiştim (buna dikkat edin)
Maliyet Analizi: Ek Fiyat Var mı?
Tuhaf ama, Güzel haber şu: DDM için ayrıca bir lisans parası ödemiyorsunuz. Cosmos DB hesabınız varsa, bu özelliği açıp kullanabiliyorsunuz, işte olay bu kadar basit. Microsoft ek RU tüketimi için “ihmal edilebilir düzeyde” diyor; ben de kendi testlerimde gözle görülür bir fark yakalamadım ama yoğun workload’larda birkaç yüzdelik oynama olabilir, önü da kenara not etmek lazım. Bu konuyla ilgili Kubernetes’te AI Agent Sandbox: Pratik Rehber yazımıza da göz atmanızı tavsiye ederim.
Ve işler burada ilginçleşiyor.
TL tarafında bakınca tablo biraz daha netleşiyor. Zaten Cosmos DB’nın RU maliyeti başlı başına önemli bir kalem, o yüzden DDM’in eklediği marjinal maliyet pek konuşulacak gibi durmuyor; asıl farkı uygulama katmanında maskeleme middleware’i yazarken, sonra önü test ederken. Yıllarca bakımını çekerken hissediyorsunuz. Bir geliştirici buna haftalar harcayabiliyor, DDM işe işi 15 dakikada toparlıyor; açık konuşayım, bu yüzden maliyet optimize etmeu kafasını biraz daha kurcalamak isterseniz Bulut Maliyet Optimizasyonu: Hâlâ Geçerli Prensipler yazıma da bakabilirsiniz.
Pratik İpuçları: İlk Adımlarınız
Denemek istiyorsanız, bence şöyle başlayın:
- Önce RBAC tarafına bir bakın. DDM, RBAC olmadan pek anlamlı durmuyor. Hâlâ master key ile bağlanıyorsanız, lafı gevelemeden AAD tabanlı kimlik doğrulamaya geçin; yoksa güvenlik var sanıp aslında eski alışkanlığı sürdürmüş oluyorsunuz. (bence en önemlisi)
- Hassas alanları tek tek çıkarın. Hangi container’da hangi property’ler hassas veri taşıyor? Bunu Excel’e yazan da olur, deftere karalayan da olur — önemli olan envanteri net görmek, çünkü sonra “bu alan nerede kalmıştı?” diye dönüp durmak insanı yoruyor. — bunu es geçmeyin
- Pilot için tek bir container seçin. Production’a yüklenmeden önce test edin, bakın akış nasıl gidiyor (özellikle change feed tarafında maskelenmemiş veri sızıyor mu diye). İlk başta küçük başlamak daha az can sıkıyor, açık konuşayım.
- Maskeleme kurallarını tanımlayın. Default masking çoğu senaryoda iş görüyor, ama kredi kartı ya da TC kimlik gibi alanlarda Custom String masking daha iyi oturabiliyor; yanı her alanı aynı kalıba sokmaya çalışmayın.
- Unmask yetkisini sadece gerçekten ihtiyacı olan rollere verin. “Herkes görsün” diye başlamak kolay geliyor ama sonra işler karışıyor; least privilege burada da geçerli, hem de bayağı geçerli.
Bir de şunu ekleyeyim: DDM’i ilk denediğimde ARM template üzerinden kural tanımlarken JSON path’lerde epey uğraştım. Cosmos DB’deki property path’ler “/” ile başlıyor — kendi adıma konuşayım — (mesela “/email”), buna dikkat etmek gerekiyor; ben ilk seferde path’i yanlış yazınca maskeleme çalışmadı ama ortada düzgün bir hata da yoktu, sessizce geçti. Debug etmek biraz sınır bozucuydu, hani insan bekliyor ki en azından bir uyarı çıksın, ama yok.
Son Söz: İyi Bir Adım Ama Yeterli Değil
Bence DDM’in GA’ya gelmesi, doğru tarafa atılmış bir adım. Ama yetiyor mu? Pek sayılmaz. Şifreleme var, ağ izolasyonu var, audit logging var, RBAC var. Işin aslı bunların hepsi birlikte anlam kazanıyor (tek başına duran şey pek işe yaramıyor), DDM de bu yapının içinde yer alıyor. Güzel dürüyor, ama sadece bir parça.
Bunu biraz açayım.
Aslında burada ufak bir kırılma var — dur bir saniye — benim esas beklentim DDM’in MongoDB API tarafında da çalışmasıydı. Türkiye’de Cosmos DB kullanan şirketlerin hatırı sayılır kısmı MongoDB API’yi seçiyor, çünkü ekipler o tarafa daha alışık oluyor, bazı uygulamalar da orada daha rahat akıyor; ama tam da bu yüzden, o tarafta eksik kalınca boşluk bariz hissediliyor — dürüst olayım, biraz hayal kırıklığı —. Umarım Microsoft bunu da yakında getirir.
Bakın, Neyse, uzun lafın kısası: Cosmos DB’de hassas veri tutuyorsanız ve DDM’i henüz açmadıysanız, bugün açın. 15 dakikanızı alır, abartmıyorum, güvenlik duruşunuzu da fena olmayan bir seviyede yukarı çeker. Hem KVKK denetiminde eliniz biraz daha rahatlar.
Sıkça Sorulan Sorular
Dynamic Data Masking veritabanındaki asıl veriyi değiştiriyor mu?
Hayır, kesinlikle hayır. DDM aslında tamamen sorgu sonucu üzerinde çalışıyor — yanı veritabanındaki orijinal veri olduğu gibi dürüyor. Sadece yetkisiz kullanıcılara dönen sonuçlarda maskeleme devreye giriyor. Bence bu, özellikle veri bütünlüğü konusunda endişesi olanları rahatlatacak bir detay (en azından benim deneyimim böyle)
DDM’i etkinleştirmek için uygulama kodumda bir şey değiştirmem gerekiyor mu?
Hiç gerek yok. Maskeleme tamamen sunucu tarafında, Cosmos DB engine seviyesinde hallediliyor. Hangi SDK ya da client kullanırsanız kullanın, maskeleme kuralları otomatik olarak işliyor. Açıkçası bu kısım bence DDM’in en güzel yanlarından biri — mevcut uygulamanıza hiç dokunmadan güvenlik katıyorsunuz.
Cosmos DB DDM hangi API’lerde çalışıyor?
Şu an yalnızca Azure Cosmos DB for NoSQL API’sinde destekleniyor. MongoDB, Cassandra, Gremlin ve Table API’lerde henüz yok. Microsoft’un bu API’lere de genişletme planı olduğu söyleniyor ama tecrübeme göre bu tür “yakında geliyor” açıklamalarında resmî bir tarih pek verilmiyor — bu sefer de öyle.
Change feed’den akan veriler de maskeleniyor mu?
Hayır, ve bu gerçekten çok önemli bir nokta. Change feed üzerinden akan veriler maskelenmemiş hâlde geliyor. Yanı eğer change feed aracılığıyla başka sistemlere veri aktarıyorsanız, o tarafta ayrıca güvenlik önlemleri almanız şart. Bunu atlayan çok kişi görüyorum, dikkat!
Bir dakika — bununla bitmedi.
DDM’in ayrı bir maliyeti var mı?
Yok. Mevcut Cosmos DB hesabınızda ücretsiz olarak açabiliyorsunuz — hani ayrı bir lisans falan gerekmiyor. RU tüketiminde çok ufak bir artış olabilir, ama pratikte fark edilebilir bir maliyet artışı yaratmıyor.
Kaynaklar ve İleri Okuma
Azure Cosmos DB Dynamic Data Masking — Microsoft Resmî Dokümantasyonu
Garip gelecek ama, General Availability: Dynamic Data Masking for Azure Cosmos DB — Microsoft DevBlog
Azure Cosmos DB Role-Based Access Control (RBAC) — Microsoft Learn
İçeriği paylaş:
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.







0 comments