Use role-based access control with Azure Cosmos DB for Table (preview)
APPLIES TO: Table
Diagram of the sequence of the deployment guide including these locations, in order: Overview, Concepts, Prepare, Role-based access control, and Reference. The 'Role-based access control' location is currently highlighted.
This article walks through the steps to grant an identity access to manage data in an Azure Cosmos DB for Table account. The steps in this article only cover data plane access to perform operations on individual items and run queries.
Prerequisites
- An Azure account with an active subscription. Create an account for free.
- An existing Azure Cosmos DB for Table account.
- One or more existing identities in Microsoft Entra ID.
Use the Bash environment in Azure Cloud Shell. For more information, see Quickstart for Bash in Azure Cloud Shell.
If you prefer to run CLI reference commands locally, install the Azure CLI. If you're running on Windows or macOS, consider running Azure CLI in a Docker container. For more information, see How to run the Azure CLI in a Docker container.
If you're using a local installation, sign in to the Azure CLI by using the az login command. To finish the authentication process, follow the steps displayed in your terminal. For other sign-in options, see Sign in with the Azure CLI.
When you're prompted, install the Azure CLI extension on first use. For more information about extensions, see Use extensions with the Azure CLI.
Run az version to find the version and dependent libraries that are installed. To upgrade to the latest version, run az upgrade.
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 Table.
First, get the resource identifier of the existing Azure Cosmos DB for Table account using az cosmsodb show
and store it in a variable. Then, list all of the role definitions associated with your Azure Cosmos DB for Table account using az rest
. Finally, 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.
resourceId=$( \
az cosmosdb show \
--resource-group "<name-of-existing-resource-group>" \
--name "<name-of-existing-table-account>" \
--query "id" \
--output tsv \
)
az rest \
--method "GET" \
--url $resourceId/tableRoleDefinitions?api-version=2023-04-15
[
...,
{
"id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/tableRoleDefinitions/00000000-0000-0000-0000-000000000002",
"name": "00000000-0000-0000-0000-000000000002",
"properties": {
"assignableScopes": [
"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
],
"permissions": [
{
"dataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/tables/*",
"Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*"
],
"notDataActions": []
}
],
"roleName": "Cosmos DB Built-in Data Contributor",
"type": "BuiltInRole"
},
"type": "Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions"
}
...
]
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/tableRoleDefinitions/00000000-0000-0000-0000-000000000002
. This example uses fictitious data and your identifier would be distinct from this example. This example output is truncated.
Use Get-AzCosmosDBAccount
to get the resource identifier of the existing Azure Cosmos DB for Table account and store it in a variable. Then, use Invoke-AzRestMethod
to list all of the role definitions associated with your Azure Cosmos DB for Table 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>"
Name = "<name-of-existing-table-account>"
}
$resourceId = (
Get-AzCosmosDBAccount @parameters |
Select-Object -Property Id -First 1
).Id
$parameters = @{
Path = "$resourceId/tableRoleDefinitions?api-version=2023-04-15"
Method = "GET"
}
Invoke-AzRestMethod @parameters
StatusCode : 200
Content : {
"value": [
...,
{
"id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql/tableRoleDefinitions/00000000-0000-0000-0000-000000000002",
"name": "00000000-0000-0000-0000-000000000002",
"properties": {
"assignableScopes": [
"/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-nosql"
],
"permissions": [
{
"dataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/tables/*",
"Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*"
],
"notDataActions": []
}
],
"roleName": "Cosmos DB Built-in Data Contributor",
"type": "BuiltInRole"
},
"type": "Microsoft.DocumentDB/databaseAccounts/tableRoleDefinitions"
}
...
]
}
...
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/tableRoleDefinitions/00000000-0000-0000-0000-000000000002
. This example uses fictitious data and your identifier would be distinct from this example. This example output is truncated.
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 Table.
Important
This assignment task requires you to have the unique identifier of any identity you want to grant role-based access control permissions. If you do not have a unique identifier for an identity, follow the instructions in the create managed identity or get signed-in identity guides.
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-resource-group>" \ --query "{id:id}"
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.Create a new JSON file named role-assignment.json. In the JSON file, add the unique identifier for your identity and unique identifier for the account resource.
{ "properties": { "roleDefinitionId": "<account-resource-id>/tableRoleDefinitions/d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4", "scope": "<account-resource-id>", "principalId": "<id-of-existing-identity>" } }
Note
In this example, the unique GUID specified was
d3d3d3d3-eeee-ffff-aaaa-b4b4b4b4b4b4
. You can use the unique GUID you used previously for your own role definition.Now create or update a role assignment using
az cosmosdb show
andaz rest
together to issue an HTTPPUT
request. As part of this request, specify a unique GUID for your role assignment.resourceId=$( \ az cosmosdb show \ --resource-group "<name-of-existing-resource-group>" \ --name "<name-of-existing-table-account>" \ --query "id" \ --output tsv \ ) az rest \ --method "PUT" \ --url $resourceId/tableRoleAssignments/e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5?api-version=2023-04-15 \ --body @role-assignment.json
Note
In this example, the unique GUID specified was
e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5
. You can specify any unique GUID for your own role assignment.
Create another Bicep file to assign a role to an identity. Name this file data-plane-role-assignment.bicep.
metadata description = 'Assign RBAC role for data plane access to Azure Cosmos DB for Table.' @description('Name of the Azure Cosmos DB for Table 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@2023-04-15' existing = { name: accountName } resource assignment 'Microsoft.DocumentDB/databaseAccounts/tableRoleAssignments@2023-04-15' = { name: guid(roleDefinitionId, identityId, account.id) parent: account properties: { principalId: identityId roleDefinitionId: roleDefinitionId scope: account.id } } output id string = assignment.id
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 Table account to theaccountName
parameter, the previously recorded role definition identifiers to theroleDefinitionId
parameter, and the unique identifier for your identity to theidentityId
parameter.using './data-plane-role-assignment.bicep' param accountName = '<name-of-existing-table-account>' param roleDefinitionId = '<id-of-new-role-definition>' param identityId = '<id-of-existing-identity>'
Deploy this 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
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.
Use `Get-AzCosmosDBAccount to get the unique identifier for your current account.
$parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-nosql-account>" } Get-AzCosmosDBAccount @parameters | Select -Property Id
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.Now create or update a role assignment using
Get-AzCosmosDBAccount
andInvoke-AzRestMethod
together to issue an HTTPPUT
request. As part of this request, specify a unique GUID for your role assignment. Finally, create a resource assignment payload specifying the unique identifier for your identity.$parameters = @{ ResourceGroupName = "<name-of-existing-resource-group>" Name = "<name-of-existing-table-account>" } $resourceId = ( Get-AzCosmosDBAccount @parameters | Select-Object -Property Id -First 1 ).Id $payload = @{ properties = @{ roleDefinitionId = "$resourceId/tableRoleDefinitions/00000000-0000-0000-0000-000000000002" scope = "$resourceId" principalId = "<id-of-existing-identity>" } } $parameters = @{ Path = "$resourceId/tableRoleAssignments/e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5?api-version=2023-04-15" Method = "PUT" Payload = $payload | ConvertTo-Json -Depth 2 } Invoke-AzRestMethod @parameters
Note
In this example, the unique GUID specified was
e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5
. You can specify any unique GUID for your own role assignment.
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.Identity;
using Azure.Data.Tables;
string endpoint = "<account-endpoint>";
DefaultAzureCredential credential = new();
TableServiceClient client = new(
endpoint: new Uri(endpoint),
tokenCredential: credential
);
TableClient table = client.GetTableClient(
tableName: "<name-of-table>"
);
Important
This code sample uses the Azure.Data.Tables
and Azure.Identity
libraries from NuGet.
Warning
If you are using a user-assigned managed identity, you will need to specify the unique identifier of the managed identity as part of creating the credentials object.