Cosmos DB Rolleri: Uygulamam İçin Hangisi Doğru Seçim?
Geçen hafta bir ekiple oturdum, ellerinde düzgün sayılabilecek bir.NET API vardı, Azure’a deploy etmişlerdi, lokalde de gayet sakın çalışıyordu. Tek dertleri şuydu: Cosmos DB’ye bağlanırken hâlâ connection string’i App Settings’e gömüyorlardı. “Aşkın hocam, yıllardır böyle yapıyoruz, ne olacak ki?” dediler.
Olan şu: Bir gün biri repo’ya o connection string’i yanlışlıkla commit’liyor. Ya da bir junior dev local.settings.json’ı paylaşıyor. Sonrası malum. Kısa versiyon bu.
İşin aslı şu ki, Cosmos DB tarafında key tabanlı kimlik doğrulama dönemi çoktan geride kalmış olmalıydı. Microsoft yıllardır managed identity ve RBAC tarafını toparlıyor, iyice de olgunlaştırıyor. Ama sahada hâlâ %70 civarı key kullanıldığını görüyorum; şaşırdım açıkçası. Bu yazıda — lafı dolandırmadan — uygulamanızın Cosmos DB’ye nasıl, hangi rolle, hangi kimlikle bağlanması gerektiğini anlatacağım.
Önce Kafa Karıştıran O Ayrımı Netleştirelim
Ne yalan söyleyeyim, Cosmos DB’nın iki ayrı izin sistemi var, işte mesele burada başlıyor. Bunu anlamadan yola çıkarsanız rol atarken neden çalışmadığını saatlerce kurcalarsınız; ben ilk başladığımda bu tuzağa düşmüştüm, sonra aynı kafa karışıklığını çok ekipte daha gördüm. Neyse uzatmayalım.
Çok konuştum, örnekle göstereyim.
Bakın şöyle:
| Özellik | Control Plane | Data Plane |
|---|---|---|
| Ne yönetir? | Hesap yönetimi: DB/container oluşturma, throughput değiştirme, anahtar okuma, network ayarları | Asıl veri: doküman okuma/yazma, sorgular, stored procedure çalıştırma |
| Roller nerede? | Azure RBAC (standart Microsoft.Authorization rolleri) | Cosmos DB’nın kendi data plane RBAC sistemi |
| Örnek rol | Cosmos DB Account Reader, Contributor | Cosmos DB Built-in Data Reader, Data Contributor |
Şimdi en sık gördüğüm hata şu: Birisi geliyor, “Ben uygulamama Contributor rolü verdim ama doküman okuyamıyor” diyor. Çünkü Contributor dediğiniz şey control plane rolü; hesap üzerinde işlem yaptırıyor ama veriye dokundurmuyor. Tam tersi de geçerli: Data (belki yanılıyorum ama) Contributor verirseniz bu kez kullanıcı throughput değiştiremez. Garip gibi dürüyor ama öyle.
İki sistem birbirinden bağımsız. Portal’dan Cosmos DB’nın “Access Control (IAM)” sekmesinde rol verirken control plane rolleri görürsünüz. Data plane rolleri işe sadece CLI veya ARM/Bicep ile atanabilir. Bu da Microsoft’un bilinçli tasarımı; yetkisiz birinin yanlışlıkla veri yetkisi vermesini istemiyorlar.
Üç Soru Sorun Kendinize
Erişim mimarisi kurarken kafamda hep üç soru olur:
- Kim erişim istiyor? (uygulamanızın kimliği)
- Ne yapabilecek? (rol)
- Nerede geçerli? (kapsam — account, database ya da container seviyesi)
Bak şimdi, Bunlar oturunca gerisi baya mekanik ilerliyor. Şimdi tek tek gidelim; çünkü işin tadı orada çıkıyor.
1. Kim: Managed Identity (gerçekten başka yere bakmayın)
Uygulamanızın Azure’ın tanıdığı bir kimliği olmalı. Pratikte iki seçenek var:
Managed Identity: Azure sizin için credential işini yönetiyor. Secret yok, rotasyon yok, config dosyasında saklanacak bir şey yok; kulağa fazla temiz geliyor ama işe yarıyor işte. Mantıklı değil mi? App Service, Functions, Container Apps, AKS veya VM üzerinde çalışıyorsanız bunu kullanın.
Service Principal: Manuel kaydedilen bir app identity; client secret ya da sertifika ile yürür. Bunu sadece managed identity’nın mümkün olmadığı yerlerde kullanın (Azure dışı kodlar, on-prem entegrasyonu falan). Yanı mecbursanız.
App Service için system-assigned managed identity açmak şu kadar basit:
az webapp identity assign \
--name my-app \
--resource-group my-rg
Aslında, Komutun döndürdüğü principalId değerini bir kenara not edin. Rol atamasındaki “kim” tam olarak bu oluyor.
2. Ne: Built-in Veri Rolleri
Tekerleği yeniden icat etmeyin derim. Cosmos DB iki tane hazır data plane rolü sunuyor. Uygulamaların belki %95’i bunlarla rahatça çıkıyor; fazlasına çoğu zaman gerek bile kalmıyor:
| Rol | ID | Yetkiler |
|---|---|---|
| Cosmos DB Built-in Data Reader | Doküman okuma, sorgu çalıştırma, change feed okuma | |
|
<PRIVATE_ROLE> |
<PRIVATE_ID> |
</PRIVATE_ROLE>> + create, replace, upsert, delete |
Düzeltme gerekiyor mu? Evet;. Içeriğin anlamı aynı kalacak şekilde söyleyeyim: Veri yazan uygulamalar Data Contributor ister. Sadece okuyan bir raporlama servisi ya da cache ısıtma job’ı için Data Reader yeterli. Burada altın kural:
</>
? scope?>
-
</>
-
</>
-
</>
Miktar olarak burada ciddi bozulma öldü. Yine de ana fikir aynı: /dbs/ordersdb/colls/orders gibi container seviyesine inmek en dar. En güvenli seçeneklerden biri. Account geneli yetki vermek isterseniz scope’u / yaparsınız, ama ben açık konuşayım, bunu prod’da mümkün olduğunca kaçırırım.
Bu noktada iyi olan şey şu: “least privilege” kuralını bozmadığınız sürece geri kalan her şey yoluna giriyor. Tam da öyle.
Ve işler burada ilginçleşiyor.
Kodda Nasıl Görünüyor?
Sdk tarafında değişiklik küçük gibi dürüyor, ama etkisi büyük oluyor. *DefaultAzureCredential*'a geçiyorsunuz, connection string işi kapanıyor:—
// C# — Azure.Identity ve Microsoft.Azure.Cosmos paketleri
var credential = new DefaultAzureCredential();
var client = new CosmosClient(
accountEndpoint:"https://my-cosmos-account.documents.azure.com:**443**/",
tokenCredential:»
);
var container = client.GetContainer("oordersdb", "oorders");
await container.CreateItemAsync(newOrder);>>```
“Hepsi bu” demek kolay geliyor ama burada güzel olan şey lokal ile prod arasındaki farkın neredeyse kaybolması.&nbs p;
Lokalde geliştirirken DefaultAzureCredential sizin Azure CLI oturumunuzu kullanır,
deploy ettiğinizde ise Azure'daki managed identity'y i otomatik yakalar.
Aynı kod,
sıfır config farkı.
Eskiden bunun için ayrı yol yazmak gerekiyordu;
şimdi gerek kalmıyor.
Fena değil.</? p>
<.h2?>
Türkiye'deki Kurumlar İçin Pratik Notlar
</h2?>
Sahada gözlemlediğim kadarıyla,
Türkiye'deki finans ve telekom tarafı RBAC adaptasyonunda biraz ağır gidiyor.
Sebep teknik değil,
daha çok alışkanlık meselesi.
Geliştirici ekipler "key ile çalışıyordu zaten" diyor,
güvenlik ekipleri "a nahtar rotasyonu yapıyoruz,
yeterli"
diyor.
Oysa gerçek biraz sert:
anahtar rotasyonu manuel ve maliyetli bir iş.
Managed identity ile bu dert tamamen azalıyor.
</? p>
Kurumsal müşterilerin sık takıldığı başka bir nokta daha var:
&l t;b&n bsp;
Custom rol yok
&l t;/b&n bsp;
sanıyorlar.
Aslında var.
Built-in iki rol işinizi görmüyorsa
(
mesela "yazsın ama silmesin"
gibi ince senaryolar
),
kendi rolünüzü tanımlayabiliyorsunuz.
JSON ile role definition oluşturup atıyorsunuz.
Şöyle düşünün:
{
"RoleName":
"oOrderWriterNoDelete",
"\Type\":
\CustomRole\",
\AssignableScopes\":[\"/\"],
\"Permissions\": [{
\"DataActions\": [
\"Microsoft.DocumentDB/databaseAccounts/readMetadata\",
\"Microsoft.DocumentDB/.../items/create\",
\"Microsoft.DocumentDB/.../items/read\",
\"Microsoft.DocumentDB/.../items/replace\"
]
}]
}
This especially helps with PCI-DSS or KVKK scope applications maybe?
Audit ekibi geldiğinde
"biz sadece bu işlemlere izin veriyoruz"
demek,
"Contributor verdik"
demekten epey farklı duruyor.
Miyiz,amp Enterprise mı?
If you're a small team with a 2-3 service architecture:
System-assigned managed identity + Data Contributor + database-level scope makes sense.
Enterprise tarafındaysanız hikaye biraz değişiyor:
User-assigned managed identity tercih edin
(
birden fazla servis aynı kimliği paylaşabilsin
),
custom roller tanımlayın,
scope'u mutlaka container seviyesine indirin,
ve hepsini Bicep/Terraform ile IaC altında yönetin.
Manuel birkaç CLI komutu dışında elle işlem bırakmayın;
denetlenebilirlik için bu önemli.
Sık Yapılan Hatalar ve Çözümleri
Bu konuda en sık karşılaştığım sorunlar şunlar:
"Forbidden" hatası alıyorum: %90 ihtimalle yanlış rolü atamışsınızdır.
Lokalde çalışıyor&comma Azure'da çalışmıyor: Managed identity Azure'da açılmamış olabilir.az webapp identity show ile kontrol edin.
readMetadata yetkisi unutuluyor: Custom rol yazarken bu permission'ı eklemezseniz&comma SDK ilk bağlantıda hata verir.
Rol ataması "anında" çalışmıyor : 5 dakika bekleyin&period Token cache'in yenilenmesi lazım&period
;Deep Agents + Cosmos DB:&nbs p Operasyonel Veride Plan-Eylem-Doğrulama</a>; yazısına da göz atabilirsiniz.
Java tarafında vektör araması üzerine çalışıyorsanız ise
;Spring AI 2&period0 GA:&nb sp Cosmos DB ile Java Tarafında Vektör Devri</a>; faydalı olur.Maliyet Tarafı:& nbsp RBAC Bedava mı?
Evet&comma RBAC kullanmak ekstra ücret getirmiyor&period Cosmo s DB tarafında RU bazlı faturalandırma değişmiyor&period Ama Entra ID
(
eski adıyla Azure AD
)
tarafında token alma işlemi var ve bunun network latency olarak küçük bir maliyeti oluyor&period SDK token'ı zaten cache'lediği için gerçek dünyada ölçülebilir büyük bir fark çıkarmıyor&period
Asıl “maliyet” kazancı başka yerde:
Bir secret leak vakası yaşadığınızda anahtar rotasyonu için harcayacağınız mühendislik saatleri + downtime riski azalıyor&period Orta ölçekli bir kurumda bunun faturası rahatlıkla 200-300 saate çıkabiliyor&period Managed identity ile risk ciddi biçimde düşüyor&period
Envanter çıkarın
>:
Hangi uygulama&comma hangi Cosmos hesabına&comma hangi yetkilerle bağlanıyor?
Bu listeyi yapmadan başlamayın&period >
>
Önce non-prod'da deneyin
>:
Dev veya staging ortamında managed identity + Data Contributor ile test edin&period SDK versiyonunuzun güncel olduğundan emin olun (&period NET için Microsoft.Azure.Cosmos 3&period32+ tavsiye edilir)&period >
>
Paralel çalıştırıp sonra key'i çekin
>:
Bir süre hem RBAC hem key aktif kalsın&period Loglarda hata görmediğinizden emin olduktan sonra key authentication'ı Cosmos hesabı seviyesinde devre dışı bırakın (). >
Evet, doğru duydunuz.
Sıkça Sorulan Sorular
Managed identity ile bağlanınca connection string'i tamamen silebilir miyim?
Araya gireyim: Evet, silebilirsin. SDK'ya sadece account endpoint URL'ini (https://...documents.azure.com:443/) ve TokenCredential nesnesini vermen yeterli, yani key'e hiç gerek kalmıyor. Hatta bir adım daha ileri gidip Cosmos hesabında disableLocalAuth ayarını açarsan key kullanımını tamamen yasaklayabilirsin. Bence bu en temiz yol.
System-assigned ile user-assigned managed identity arasındaki fark ne?
System-assigned, hani tek bir kaynağa (mesela tek bir App Service'e) bağlı olan türdür — o kaynak silinince o da gidiyor. User-assigned ise bağımsız bir kaynak olarak duruyor ve birden fazla servis aynı identity'yi paylaşabiliyor. Açıkçası, birden fazla uygulamanın aynı veriye erişmesi gerekiyorsa user-assigned çok daha pratik.
Data plane rolünü portal'dan atayamıyor muyum?
Bakın, Atayamıyorsun, maalesef. Şu an için Azure CLI, PowerShell, ARM template ya da Bicep kullanman gerekiyor. Aslında bu Microsoft'un bilinçli bir güvenlik kararı — yanlışlıkla geniş veri erişimi vermemek için böyle tasarlamışlar.
Custom rol oluşturmak gerçekten gerekli mi?
Çoğu durumda hayır. Built-in Data Reader ve Data Contributor rolleri uygulamaların %95'ini karşılıyor. Custom rolü ancak çok özel bir kısıtlamaya ihtiyacın varsa düşün, mesela "sadece okuma + güncelleme, ama silme yok" gibi bir senaryoda. Tecrübeme göre gereksiz yere custom rol açmak sadece karmaşıklık ekliyor.
RBAC kullanmak performansı etkiler mi?
Pratikte etkilemiyor. SDK aldığı access token'ı cache'liyor ve süresi dolana kadar tekrar istek atmıyor. Siz ne dersiniz? Aslında sadece ilk bağlantıda birkaç yüz milisaniyelik bir token alma maliyeti oluyor, ondan sonrası key kullanımıyla aynı performansta devam ediyor.
Kaynaklar ve İleri Okuma
Which Azure Cosmos DB Role Does My App Need? (Orijinal makale — Microsoft DevBlogs)
Configure role-based access control with Microsoft Entra ID for Azure Cosmos DB (Microsoft Learn)
Yani, Managed Identities for Azure Resources Overview (Microsoft Learn)
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.








0 comments