Use data plane role-based access control with Azure Cosmos DB for NoSQL

APPLIES TO: NoSQL

Diagram of the current location ('Role-based access control') in the sequence of the deployment guide.

Diagram of the sequence of the deployment guide including these locations, in order: Overview, Concepts, Prepare, Role-based access control, Network, and Reference. The 'Role-based access control' location is currently highlighted.

Tip

Visit our new Samples Gallery for the latest samples for building new apps

This article walks through the steps to grant an identity access to manage data in an Azure Cosmos DB for NoSQL account.

Important

The steps in this article only cover data plane access to perform operations on individual items and run queries. To learn how to manage databases and containers for the control plane, see grant control plane role-based access.

Prerequisites

  • An Azure account with an active subscription. Create an account for free.
  • An existing Azure Cosmos DB for NoSQL account.
  • One or more existing identities in Microsoft Entra ID.

Prepare role definition

First, you must prepare a role definition with a list of dataActions to grant access to read, query, and manage data in Azure Cosmos DB for NoSQL.

Important

Obtaining an existing data plane role definition requires these control plane permissions:

  • Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/read

For more information, see grant control plane role-based access.

List all of the role definitions associated with your Azure Cosmos DB for NoSQL account using az cosmosdb sql role definition list. Review the output and locate the role definition named Cosmos DB Built-in Data Contributor. The output contains the unique identifier of the role definition in the id property. Record this value as it is required to use in the assignment step later in this guide.

az cosmosdb sql role definition list \
    --resource-group "<name-of-existing-resource-group>" \
    --account-name "<name-of-existing-nosql-account>"
[
  ...,
  {
    "assignableScopes": [
      "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
    ],
    "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002",
    "name": "00000000-0000-0000-0000-000000000002",
    "permissions": [
      {
        "dataActions": [
          "Microsoft.DocumentDB/databaseAccounts/readMetadata",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*",
          "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*"
        ],
        "notDataActions": []
      }
    ],
    "resourceGroup": "msdocs-identity-example",
    "roleName": "Cosmos DB Built-in Data Contributor",
    "type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions",
    "typePropertiesType": "BuiltInRole"
  }
  ...
]

Note

In this example, the id value would be /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002. This example uses fictitious data and your identifier would be distinct from this example.

Use Get-AzCosmosDBSqlRoleDefinition to list all of the role definitions associated with your Azure Cosmos DB for NoSQL account. Review the output and locate the role definition named Cosmos DB Built-in Data Contributor. The output contains the unique identifier of the role definition in the Id property. Record this value as it is required to use in the assignment step later in this guide.

$parameters = @{
    ResourceGroupName = "<name-of-existing-resource-group>"
    AccountName = "<name-of-existing-nosql-account>"
}
Get-AzCosmosDBSqlRoleDefinition @parameters
Id                         : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002
RoleName                   : Cosmos DB Built-in Data Contributor
Type                       : BuiltInRole
AssignableScopes           : {/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccountsmsdocs-identity-example-nosql}
Permissions.DataActions    : {Microsoft.DocumentDB/databaseAccounts/readMetadata, Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*, Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*}
Permissions.NotDataActions : 

Note

In this example, the Id value would be /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/sqlRoleDefinitions/00000000-0000-0000-0000-000000000002. This example uses fictitious data and your identifier would be distinct from this example. However, the identifier (00000000-0000-0000-0000-000000000002) is unique across all role definitions in your account.

Assign role to identity

Now, assign the newly defined role to an identity so that your applications can access data in Azure Cosmos DB for NoSQL.

Important

Creating a new data plane role assignment requires these control plane permissions:

  • Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/read
  • Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/read
  • Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/write

For more information, see grant control plane role-based access.

  1. Use az cosmosdb show to get the unique identifier for your current account.

    az cosmosdb show \
        --resource-group "<name-of-existing-resource-group>" \
        --name "<name-of-existing-nosql-account>" \
        --query "{id:id}"
    
  2. Observe the output of the previous command. Record the value of the id property for this account as it is required to use in the next step.

    {
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
    }
    

    Note

    In this example, the id value would be /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql. This example uses fictitious data and your identifier would be distinct from this example.

  3. Assign the new role using az cosmosdb sql role assignment create. Use the previously recorded role definition identifiers to the --role-definition-id argument, and the unique identifier for your identity to the --principal-id argument. Finally, use your account's identifier for the --scope argument.

    az cosmosdb sql role assignment create \
        --resource-group "<name-of-existing-resource-group>" \
        --account-name "<name-of-existing-nosql-account>" \
        --role-definition-id "<id-of-new-role-definition>" \
        --principal-id "<id-of-existing-identity>" \
        --scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
    
  4. Use az cosmosdb sql role assignment list to list all role assignments for your Azure Cosmos DB for NoSQL account. Review the output to ensure your role assignment was created.

    az cosmosdb sql role assignment list \
        --resource-group "<name-of-existing-resource-group>" \
        --account-name "<name-of-existing-nosql-account>"
    
  1. Create a new Bicep file to define your role assignment. Name the file data-plane-role-assignment.bicep.

    metadata description = 'Assign RBAC role for data plane access to Azure Cosmos DB for NoSQL.'
    
    @description('Name of the Azure Cosmos DB for NoSQL account.')
    param accountName string
    
    @description('Id of the role definition to assign to the targeted principal in the context of the account.')
    param roleDefinitionId string
    
    @description('Id of the identity/principal to assign this role in the context of the account.')
    param identityId string
    
    resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' existing = {
      name: accountName
    }
    
    resource assignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2024-05-15' = {
      name: guid(roleDefinitionId, identityId, account.id)
      parent: account
      properties: {
        principalId: identityId
        roleDefinitionId: roleDefinitionId
        scope: account.id
      }
    }
    
    output assignmentId string = assignment.id
    
  2. Create a new Bicep parameters file named data-plane-role-assignment.bicepparam. In this parameters file, assign the name of your existing Azure Cosmos DB for NoSQL account to the accountName parameter, the previously recorded role definition identifiers to the roleDefinitionId parameter, and the unique identifier for your identity to the identityId parameter.

    using './data-plane-role-assignment.bicep'
    
    param accountName = '<name-of-existing-nosql-account>'
    param roleDefinitionId = '<id-of-new-role-definition>'
    param identityId = '<id-of-existing-identity>'
    
  3. Deploy the Bicep template using az deployment group create.

    az deployment group create \
        --resource-group "<name-of-existing-resource-group>" \
        --parameters data-plane-role-assignment.bicepparam \
        --template-file data-plane-role-assignment.bicep
    
  4. Repeat these steps to grant access to the account from any other identities you would like to use.

    Tip

    You can repeat these steps for as many identities as you'd like. Typically, these steps are at least repeated to allow developers access to an account using their human identity and to allow applications access using a managed identity.

  1. Use Get-AzCosmosDBAccount to get the metadata for your current account.

    $parameters = @{
        ResourceGroupName = "<name-of-existing-resource-group>"
        Name = "<name-of-existing-nosql-account>"
    }    
    Get-AzCosmosDBAccount @parameters | Select -Property Id
    
  2. Observe the output of the previous command. Record the value of the Id property for this account as it is required to use in the next step.

    Id
    --    
    /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql
    

    Note

    In this example, the Id value would be /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql. This example uses fictitious data and your identifier would be distinct from this example.

  3. Use New-AzCosmosDBSqlRoleAssignment to assign the new role. Use the previously recorded role definition identifiers to the RoleDefinitionId parameter, and the unique identifier for your identity to the PrincipalId parameter. Finally, use your account's identifier for the Scope parameter.

    $parameters = @{
        ResourceGroupName = "<name-of-existing-resource-group>"
        AccountName = "<name-of-existing-nosql-account>"
        RoleDefinitionId = "<id-of-new-role-definition>"
        PrincipalId = "<id-of-existing-identity>"
        Scope = "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
    }    
    New-AzCosmosDBSqlRoleAssignment @parameters
    
  4. List all role assignments for your Azure Cosmos DB for NoSQL account using Get-AzCosmosDBSqlRoleAssignment. Review the output to ensure your role assignment was created.

    $parameters = @{
        ResourceGroupName = "<name-of-existing-resource-group>"
        AccountName = "<name-of-existing-nosql-account>"
    }
    Get-AzCosmosDBSqlRoleAssignment @parameters
    

Validate data plane access in code

Finally, validate that you correctly granted access using application code and the Azure SDK in your preferred programming language.

using Azure.Core;
using Azure.Identity;
using Microsoft.Azure.Cosmos;

string endpoint = "<account-endpoint>";

TokenCredential credential = new DefaultAzureCredential();

CosmosClient client = new(endpoint, credential);

Important

This code sample uses the Microsoft.Azure.Cosmos and Azure.Identity libraries from NuGet.