- An Azure Cosmos DB for MongoDB (vCore) cluster on a paid tier (M10 or higher). Entra auth is not available on Free.
- A user-assigned managed identity assigned to your app (App Service, Container Apps, AKS, etc.).
- For local development, Azure CLI, Azure Developer CLI etc logged in to the right tenant.
# Set these once for the session. $RESOURCE_GROUP = "<resource-group>" $CLUSTER = "<cluster-name>" $LOCATION = "<region>" # Enable Entra ID auth (keep NativeAuth). '{"authConfig":{"allowedModes":["MicrosoftEntraID","NativeAuth"]}}'|
Set-Content authConfig.json -Encoding ascii -NoNewline az resource patch ` --resource-group $RESOURCE_GROUP ` --name $CLUSTER ` --resource-type Microsoft.DocumentDB/mongoClusters ` --properties "@authConfig.json" ` --latest-include-preview
# App's managed identity, registered as a ServicePrincipal. $PRINCIPAL_ID = az identity show ` --resource-group $RESOURCE_GROUP ` --name <identity-name> ` --query principalId ` --output tsv '{"identityProvider":{"type":"MicrosoftEntraID","properties":{"principalType":"ServicePrincipal"}},"roles":[{"db":"admin","role":"root"}]}' | Set-Content user.json -Encoding ascii -NoNewline az resource create ` --resource-group $RESOURCE_GROUP ` --name "$CLUSTER/users/$PRINCIPAL_ID" ` --resource-type Microsoft.DocumentDB/mongoClusters/users ` --location $LOCATION ` --properties "@user.json" ` --latest-include-preview
- principalType is either ServicePrincipal or User. A managed identity is registered as a ServicePrincipal and User for your own account during local development.
- vCore currently only allows the cluster root role on the admin database for Entra principals, there is no per-database readWrite option, so Entra access is effectively cluster-admin.
# Your own user (local dev). $PRINCIPAL_ID = az ad signed-in-user show ` --query id ` --output tsv '{"identityProvider":{"type":"MicrosoftEntraID","properties":{"principalType":"User"}},"roles":[{"db":"admin","role":"root"}]}' | Set-Content user.json -Encoding ascii -NoNewline az resource create ` --resource-group $RESOURCE_GROUP ` --name "$CLUSTER/users/$PRINCIPAL_ID" ` --resource-type Microsoft.DocumentDB/mongoClusters/users ` --location $LOCATION ` --properties "@user.json" ` --latest-include-preview
|
|
| Authentication |
Now the code. We need a tiny shim that fetches an Entra access token and feeds it to the driver. The driver exposes an IOidcCallback interface (from the MongoDB.Driver.Authentication.Oidc namespace), and we back it with an Azure.Core.TokenCredential.
- The token scope is https://ossrdbms-aad.database.windows.net/.default.
- For a guest or local user, you typically need to pin the tenantId in the TokenRequestContext. A managed identity ignores it, so leaving it null is fine in Azure.
using Azure.Core; using MongoDB.Driver.Authentication.Oidc; internal sealed class EntraOidcCallback(TokenCredential credential, string? tenantId) : IOidcCallback { // vCore validates a token issued for the Azure OSS RDBMS resource. private static readonly string[] _scopes = ["https://ossrdbms-aad.database.windows.net/.default"]; public OidcAccessToken GetOidcAccessToken(OidcCallbackParameters parameters, CancellationToken cancellationToken) { TokenRequestContext tokenRequestContext = BuildContext(); AccessToken accessToken = credential.GetToken(tokenRequestContext, cancellationToken); return ToOidcAccessToken(accessToken); } public async Task<OidcAccessToken> GetOidcAccessTokenAsync(OidcCallbackParameters parameters, CancellationToken cancellationToken) { TokenRequestContext tokenRequestContext = BuildContext(); AccessToken accessToken = await credential.GetTokenAsync(tokenRequestContext, cancellationToken); return ToOidcAccessToken(accessToken); } private static OidcAccessToken ToOidcAccessToken(AccessToken accessToken) => new(accessToken.Token, accessToken.ExpiresOn - DateTimeOffset.UtcNow);
private TokenRequestContext BuildContext() { // A guest/local user needs the home tenant pinned.
// A managed identity ignores it. if (string.IsNullOrEmpty(tenantId)) { return new TokenRequestContext(_scopes);
} return new TokenRequestContext(_scopes, tenantId: tenantId);
} }
using Azure.Identity; using MongoDB.Driver; string host = "<HOST_NAME>.mongocluster.cosmos.azure.com"; string tenantId = "<TENANT_ID>"; MongoClientSettings settings = MongoClientSettings.FromUrl(MongoUrl.Create($"mongodb+srv://{host}/")); settings.UseTls = true; settings.RetryWrites = false; settings.MaxConnectionIdleTime = TimeSpan.FromMinutes(2); TokenCredential credential = new DefaultAzureCredential(); settings.Credential = MongoCredential.CreateOidcCredential(new EntraOidcCallback(credential, tenantId)); MongoClient mongoClient = new(settings); // Omitted for brevity
Hope this helps.
Happy Coding.
Regards,
Jaliya
