Azure Cosmos DB with Managed Identity
Cosmos DB for NoSQL data access uses Cosmos DB native data-plane RBAC. Azure RBAC management-plane roles can manage account metadata but are not sufficient for reading or writing items.
Required design decisions
- Disable key/local authentication for new accounts where supported.
- Use Azure SDK clients with a
TokenCredential. - Assign Cosmos DB native data-plane roles to the workload identity.
- Scope the role to the narrowest practical account, database, or container scope.
Disable local/key authentication
Use IaC at creation time. For existing accounts, remediate only after validating all clients use Microsoft Entra authentication.
az resource update \
--resource-group "<resource-group>" \
--name "<cosmos-account>" \
--resource-type "Microsoft.DocumentDB/databaseAccounts" \
--set properties.disableLocalAuth=trueDo not confuse disableLocalAuth with disableKeyBasedMetadataWriteAccess. The latter restricts key-based metadata writes but does not fully disable local/key authentication for data access.
Native data-plane role assignment
List role definitions:
az cosmosdb sql role definition list \
--resource-group "<resource-group>" \
--account-name "<cosmos-account>" \
-o tableAssign a role to the workload identity:
az cosmosdb sql role assignment create \
--resource-group "<resource-group>" \
--account-name "<cosmos-account>" \
--role-definition-id "<role-definition-id>" \
--principal-id "<managed-identity-principal-id>" \
--scope "/dbs/<database-name>/colls/<container-name>"Use / only when the app truly needs access to every database and container in the account.
Bicep pattern
resource cosmos_account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = {
name: cosmos_account_name
}
resource role_assignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2024-05-15' = {
name: guid(cosmos_account.id, principal_id, role_definition_id, data_scope)
parent: cosmos_account
properties: {
principalId: principal_id
roleDefinitionId: role_definition_id
scope: data_scope
}
}Code pattern
using Azure.Identity;
using Microsoft.Azure.Cosmos;
var credential = new ManagedIdentityCredential();
var client = new CosmosClient("https://<account>.documents.azure.com:443/", credential);Common failures
| Failure | Likely cause | Fix |
|---|---|---|
| Azure RBAC role exists but item reads fail | Management-plane role only | Add Cosmos native SQL role assignment |
| Connection string still works | Local auth not disabled | Set disableLocalAuth: true and verify key-based path fails |
| Role assignment command not available in portal | Cosmos data-plane RBAC is managed through CLI, PowerShell, ARM/Bicep, or SDK | Use IaC/CLI |
| Access works at account scope but not container scope | Scope mismatch | Assign at /dbs/<db>/colls/<container> or update app target |