title | description | author | ms.service | ms.topic | ms.date | ms.author | ms.reviewer |
---|---|---|---|---|---|---|---|
Configure role-based access control for your Azure Cosmos DB account with Azure AD |
Learn how to configure role-based access control with Azure Active Directory for your Azure Cosmos DB account |
ThomasWeiss |
cosmos-db |
how-to |
02/16/2022 |
thweiss |
mjbrown |
[!INCLUDEappliesto-sql-api]
Note
This article is about role-based access control for data plane operations in Azure Cosmos DB. If you are using management plane operations, see role-based access control applied to your management plane operations article.
Azure Cosmos DB exposes a built-in role-based access control (RBAC) system that lets you:
- Authenticate your data requests with an Azure Active Directory (Azure AD) identity.
- Authorize your data requests with a fine-grained, role-based permission model.
The Azure Cosmos DB data plane RBAC is built on concepts that are commonly found in other RBAC systems like Azure RBAC:
-
The permission model is composed of a set of actions; each of these actions maps to one or multiple database operations. Some examples of actions include reading an item, writing an item, or executing a query.
-
Azure Cosmos DB users create role definitions containing a list of allowed actions.
-
Role definitions get assigned to specific Azure AD identities through role assignments. A role assignment also defines the scope that the role definition applies to; currently, three scopes are currently:
- An Azure Cosmos DB account,
- An Azure Cosmos DB database,
- An Azure Cosmos DB container.
:::image type="content" source="./media/how-to-setup-rbac/concepts.svg" alt-text="RBAC concepts":::
Important
This permission model covers only database operations that involve reading and writing data. It does not cover any kind of management operations on management resources, for example:
- Create/Replace/Delete Database
- Create/Replace/Delete Container
- Replace Container Throughput
- Create/Replace/Delete/Read Stored Procedures
- Create/Replace/Delete/Read Triggers
- Create/Replace/Delete/Read User Defined Functions
You cannot use any Azure Cosmos DB data plane SDK to authenticate management operations with an Azure AD identity. Instead, you must use Azure RBAC through one of the following options:
- Azure Resource Manager templates (ARM templates)
- Azure PowerShell scripts
- Azure CLI scripts
- Azure management libraries available in:
Read Database and Read Container are considered metadata requests. Access to these operations can be granted as stated in the following section.
The table below lists all the actions exposed by the permission model.
Name | Corresponding database operation(s) |
---|---|
Microsoft.DocumentDB/databaseAccounts/readMetadata |
Read account metadata. See Metadata requests for details. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/create |
Create a new item. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read |
Read an individual item by its ID and partition key (point-read). |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/replace |
Replace an existing item. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/upsert |
"Upsert" an item, which means to create or insert an item if it doesn't already exist, or to update or replace an item if it exists. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/delete |
Delete an item. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery |
Execute a SQL query. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed |
Read from the container's change feed. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeStoredProcedure |
Execute a stored procedure. |
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/manageConflicts |
Manage conflicts for multi-write region accounts (that is, list and delete items from the conflict feed). |
Wildcards are supported at both containers and items levels:
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*
When using Azure Cosmos DB SDKs, these SDKs issue read-only metadata requests during initialization and to serve specific data requests. These metadata requests fetch various configuration details such as:
- The global configuration of your account, which includes the Azure regions the account is available in.
- The partition key of your containers or their indexing policy.
- The list of physical partitions that make a container and their addresses.
They do not fetch any of the data that you've stored in your account.
To ensure the best transparency of our permission model, these metadata requests are explicitly covered by the Microsoft.DocumentDB/databaseAccounts/readMetadata
action. This action should be allowed in every situation where your Azure Cosmos DB account is accessed through one of the Azure Cosmos DB SDKs. It can be assigned (through a role assignment) at any level in the Azure Cosmos DB hierarchy (that is, account, database, or container).
The actual metadata requests allowed by the Microsoft.DocumentDB/databaseAccounts/readMetadata
action depend on the scope that the action is assigned to:
Scope | Requests allowed by the action |
---|---|
Account | - Listing the databases under the account - For each database under the account, the allowed actions at the database scope |
Database | - Reading database metadata - Listing the containers under the database - For each container under the database, the allowed actions at the container scope |
Container | - Reading container metadata - Listing physical partitions under the container - Resolving the address of each physical partition |
Azure Cosmos DB exposes two built-in role definitions:
ID | Name | Included actions |
---|---|---|
00000000-0000-0000-0000-000000000001 | Cosmos DB Built-in Data Reader | Microsoft.DocumentDB/databaseAccounts/readMetadata Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed |
00000000-0000-0000-0000-000000000002 | Cosmos DB Built-in Data Contributor | Microsoft.DocumentDB/databaseAccounts/readMetadata Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/* Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/* |
When creating a custom role definition, you need to provide:
- The name of your Azure Cosmos DB account.
- The resource group containing your account.
- The type of the role definition:
CustomRole
. - The name of the role definition.
- A list of actions that you want the role to allow.
- One or multiple scope(s) that the role definition can be assigned at; supported scopes are:
/
(account-level),/dbs/<database-name>
(database-level),/dbs/<database-name>/colls/<container-name>
(container-level).
Note
The operations described below are available in:
- Azure PowerShell: Az.CosmosDB version 1.2.0 or higher
- Azure CLI: version 2.24.0 or higher
Create a role named MyReadOnlyRole that only contains read actions:
$resourceGroupName = "<myResourceGroup>"
$accountName = "<myCosmosAccount>"
New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
-ResourceGroupName $resourceGroupName `
-Type CustomRole -RoleName MyReadOnlyRole `
-DataAction @( `
'Microsoft.DocumentDB/databaseAccounts/readMetadata',
'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read', `
'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery', `
'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed') `
-AssignableScope "/"
Create a role named MyReadWriteRole that contains all actions:
New-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
-ResourceGroupName $resourceGroupName `
-Type CustomRole -RoleName MyReadWriteRole `
-DataAction @( `
'Microsoft.DocumentDB/databaseAccounts/readMetadata',
'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*', `
'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*') `
-AssignableScope "/"
List the role definitions you've created to fetch their IDs:
Get-AzCosmosDBSqlRoleDefinition -AccountName $accountName `
-ResourceGroupName $resourceGroupName
RoleName : MyReadWriteRole
Id : /subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAcc
ounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>
Type : CustomRole
Permissions : {Microsoft.Azure.Management.CosmosDB.Models.Permission}
AssignableScopes : {/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAc
counts/<myCosmosAccount>}
RoleName : MyReadOnlyRole
Id : /subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAcc
ounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>
Type : CustomRole
Permissions : {Microsoft.Azure.Management.CosmosDB.Models.Permission}
AssignableScopes : {/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAc
counts/<myCosmosAccount>}
Create a role named MyReadOnlyRole that only contains read actions:
// role-definition-ro.json
{
"RoleName": "MyReadOnlyRole",
"Type": "CustomRole",
"AssignableScopes": ["/"],
"Permissions": [{
"DataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
]
}]
}
resourceGroupName='<myResourceGroup>'
accountName='<myCosmosAccount>'
az cosmosdb sql role definition create --account-name $accountName --resource-group $resourceGroupName --body @role-definition-ro.json
Create a role named MyReadWriteRole that contains all actions:
// role-definition-rw.json
{
"RoleName": "MyReadWriteRole",
"Type": "CustomRole",
"AssignableScopes": ["/"],
"Permissions": [{
"DataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
]
}]
}
az cosmosdb sql role definition create --account-name $accountName --resource-group $resourceGroupName --body @role-definition-rw.json
List the role definitions you've created to fetch their IDs:
az cosmosdb sql role definition list --account-name $accountName --resource-group $resourceGroupName
[
{
"assignableScopes": [
"/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>"
],
"id": "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>",
"name": "<roleDefinitionId>",
"permissions": [
{
"dataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
],
"notDataActions": []
}
],
"resourceGroup": "<myResourceGroup>",
"roleName": "MyReadWriteRole",
"sqlRoleDefinitionGetResultsType": "CustomRole",
"type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions"
},
{
"assignableScopes": [
"/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>"
],
"id": "/subscriptions/<mySubscriptionId>/resourceGroups/<myResourceGroup>/providers/Microsoft.DocumentDB/databaseAccounts/<myCosmosAccount>/sqlRoleDefinitions/<roleDefinitionId>",
"name": "<roleDefinitionId>",
"permissions": [
{
"dataActions": [
"Microsoft.DocumentDB/databaseAccounts/readMetadata",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/read",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQuery",
"Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed"
],
"notDataActions": []
}
],
"resourceGroup": "<myResourceGroup>",
"roleName": "MyReadOnlyRole",
"sqlRoleDefinitionGetResultsType": "CustomRole",
"type": "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions"
}
]
See this page for a reference and examples of using Azure Resource Manager templates to create role definitions.
You can associate built-in or custom role definitions with your Azure AD identities. When creating a role assignment, you need to provide:
-
The name of your Azure Cosmos DB account.
-
The resource group containing your account.
-
The ID of the role definition to assign.
-
The principal ID of the identity that the role definition should be assigned to.
-
The scope of the role assignment; supported scopes are:
/
(account-level)/dbs/<database-name>
(database-level)/dbs/<database-name>/colls/<container-name>
(container-level)
The scope must match or be a sub-scope of one of the role definition's assignable scopes.
Note
If you want to create a role assignment for a service principal, make sure to use its Object ID as found in the Enterprise applications section of the Azure Active Directory portal blade.
Note
The operations described below are available in:
- Azure PowerShell: Az.CosmosDB version 1.2.0 or higher
- Azure CLI: version 2.24.0 or higher
Assign a role to an identity:
$resourceGroupName = "<myResourceGroup>"
$accountName = "<myCosmosAccount>"
$readOnlyRoleDefinitionId = "<roleDefinitionId>" # as fetched above
$principalId = "<aadPrincipalId>"
New-AzCosmosDBSqlRoleAssignment -AccountName $accountName `
-ResourceGroupName $resourceGroupName `
-RoleDefinitionId $readOnlyRoleDefinitionId `
-Scope "/" `
-PrincipalId $principalId
Assign a role to an identity:
resourceGroupName='<myResourceGroup>'
accountName='<myCosmosAccount>'
readOnlyRoleDefinitionId = '<roleDefinitionId>' # as fetched above
principalId = '<aadPrincipalId>'
az cosmosdb sql role assignment create --account-name $accountName --resource-group $resourceGroupName --scope "/" --principal-id $principalId --role-definition-id $readOnlyRoleDefinitionId
See this page for a reference and examples of using Azure Resource Manager templates to create role assignments.
To use the Azure Cosmos DB RBAC in your application, you have to update the way you initialize the Azure Cosmos DB SDK. Instead of passing your account's primary key, you have to pass an instance of a TokenCredential
class. This instance provides the Azure Cosmos DB SDK with the context required to fetch an Azure AD token on behalf of the identity you wish to use.
The way you create a TokenCredential
instance is beyond the scope of this article. There are many ways to create such an instance depending on the type of Azure AD identity you want to use (user principal, service principal, group etc.). Most importantly, your TokenCredential
instance must resolve to the identity (principal ID) that you've assigned your roles to. You can find examples of creating a TokenCredential
class:
The examples below use a service principal with a ClientSecretCredential
instance.
The Azure Cosmos DB RBAC is currently supported in the .NET SDK V3.
TokenCredential servicePrincipal = new ClientSecretCredential(
"<azure-ad-tenant-id>",
"<client-application-id>",
"<client-application-secret>");
CosmosClient client = new CosmosClient("<account-endpoint>", servicePrincipal);
The Azure Cosmos DB RBAC is currently supported in the Java SDK V4.
TokenCredential ServicePrincipal = new ClientSecretCredentialBuilder()
.authorityHost("https://login.microsoftonline.com")
.tenantId("<azure-ad-tenant-id>")
.clientId("<client-application-id>")
.clientSecret("<client-application-secret>")
.build();
CosmosAsyncClient Client = new CosmosClientBuilder()
.endpoint("<account-endpoint>")
.credential(ServicePrincipal)
.build();
The Azure Cosmos DB RBAC is currently supported in the JavaScript SDK V3.
const servicePrincipal = new ClientSecretCredential(
"<azure-ad-tenant-id>",
"<client-application-id>",
"<client-application-secret>");
const client = new CosmosClient({
endpoint: "<account-endpoint>",
aadCredentials: servicePrincipal
});
The Azure Cosmos DB RBAC is supported in the Python SDK versions 4.3.0b4 and higher.
aad_credentials = ClientSecretCredential(
tenant_id="<azure-ad-tenant-id>",
client_id="<client-application-id>",
client_secret="<client-application-secret>")
client = CosmosClient("<account-endpoint>", aad_credentials)
When constructing the REST API authorization header, set the type parameter to aad and the hash signature (sig) to the oauth token as shown in the following example:
type=aad&ver=1.0&sig=<token-from-oauth>
Note
The data explorer exposed in the Azure portal does not support the Azure Cosmos DB RBAC yet. To use your Azure AD identity when exploring your data, you must use the Azure Cosmos DB Explorer instead.
When you access the Azure Cosmos DB Explorer with the specific ?feature.enableAadDataPlane=true
query parameter and sign in, the following logic is used to access your data:
- A request to fetch the account's primary key is attempted on behalf of the identity signed in. If this request succeeds, the primary key is used to access the account's data.
- If the identity signed in isn't allowed to fetch the account's primary key, this identity is directly used to authenticate data access. In this mode, the identity must be assigned with proper role definitions to ensure data access.
When using the Azure Cosmos DB RBAC, diagnostic logs get augmented with identity and authorization information for each data operation. This lets you perform detailed auditing and retrieve the Azure AD identity used for every data request sent to your Azure Cosmos DB account.
This additional information flows in the DataPlaneRequests log category and consists of two extra columns:
aadPrincipalId_g
shows the principal ID of the Azure AD identity that was used to authenticate the request.aadAppliedRoleAssignmentId_g
shows the role assignment that was honored when authorizing the request.
In situations where you want to force clients to connect to Azure Cosmos DB through RBAC exclusively, you have the option to disable the account's primary/secondary keys. When doing so, any incoming request using either a primary/secondary key or a resource token will be actively rejected.
When creating or updating your Azure Cosmos DB account using Azure Resource Manager templates, set the disableLocalAuth
property to true
:
"resources": [
{
"type": " Microsoft.DocumentDB/databaseAccounts",
"properties": {
"disableLocalAuth": true,
// ...
},
// ...
},
// ...
]
- You can create up to 100 role definitions and 2,000 role assignments per Azure Cosmos DB account.
- You can only assign role definitions to Azure AD identities belonging to the same Azure AD tenant as your Azure Cosmos DB account.
- Azure AD group resolution is not currently supported for identities that belong to more than 200 groups.
- The Azure AD token is currently passed as a header with each individual request sent to the Azure Cosmos DB service, increasing the overall payload size.
Only the SQL API is currently supported.
Azure portal support for role management is not available yet.
The .NET V3, Java V4 and JavaScript V3 SDKs are currently supported.
Yes.
Yes, see Enforcing RBAC as the only authentication method.
- Get an overview of secure access to data in Cosmos DB.
- Learn more about RBAC for Azure Cosmos DB management.