Configure RBAC for Cosmos DB with Managed Identity instead of Service Principal
[As of December 20, 2021]
The original Japanese edition is here.
Managed Identity を使い Azure Cosmos DB の RBAC を構成する
このエントリは2021/12/20現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容との乖離が発生する可能性があります。 以前からManaged Identityを使ったCosmos…
As the document below mentioned, we can access Cosmos DB with Managed Identity.
How to use a system-assigned managed identity to access Azure Cosmos DB data
APPLIES TO: SQL API In this article, you'll set up a robust, key rotation agnostic solution to access Azure Cosmos DB…
Recently, a new feature, RBAC for Cosmos DB, is added and it allows us to configure fine-grain control to data operations for Cosmos DB with Azure Active Directory accounts.
Configure role-based access control for your Azure Cosmos DB account with Azure AD
APPLIES TO: SQL API Note This article is about role-based access control for data plane operations in Azure Cosmos DB…
We don’t have to use any keys when using this feature to connect to Cosmos DB. Therefore, we can keep Cosmos DB more secure than ordinal style in connecting the DB.
The document mentioned above describes RBAC configuration with Service Principal, but Managed Identity also works. In this article, I elaborate how to configure RBAC for Cosmos DB with Managed Identity.
Topology and service components
In this article, I use the following configuration.
- Function App (Read Only and Read/Write)
- Runtime: Java 11
- HTTP binding/trigger
- Cosmos DB Java SDK v4
- The SDK is used in each Function App to interact with Cosmos DB.
As I mentioned before, each Function App uses HTTP binding (trigger, output) and contains logic to interact with Cosmos DB. After creating a scaffold, we will add Cosmos DB interaction logic.
When accessing RBAC configured Cosmos DB with SDK, we have to get
TokenCredential and use this credential to initialize
TokenCredential is an interface and there are lots of implementation class of the interface, including
ManagedIdentityCredential. So, we can also use Managed Identity to configure RBAC for Cosmos DB.
We can get a
TokenCredential instance with the following code.
DefaultAzureCredentialBuilder() is used in this example, but ,
ManagedIdentityCredentialBuilder() is also applicable.
Next, we pass the
TokenCredential instance to
CosmosClientBuilder() to initialize
CosmosAsyncClient. As you can see, we don’t have to use any keys to create a client instance. We can create
CosmosClient with the following code. As
CosmosAsyncClient is auto-closable, we should create the client instance surrounded with
After that, codes corresponding to
GET method and
POST method are added.
GET: retrieve data from Cosmos DB.
POST: update or insert data passed in HTTP request body.
To check the response code from Cosmos DB, this response code is used in the “upsert” code as a HTTP status returned by Function App.
When the implementation is completed, build Function Apps and deploy them to Azure.
Next, we create Managed Identity of each Function App. Navigate “Settings” > “Identity” in Azure Portal, and enable system assigned managed identity. As “Object (principal) ID” is used afterwards, I recommend you take a note of this ID. This operation is required in both Function Apps.
As usual, create Cosmos DB account, database, and container. In this article, database is named “Inventories”, and container is “Tracks”. Data listed below are populated in the container.
Next, two custom roles should be created for RBAC; one is “read only” role (
MyReadOnlyRole), and the other is “read write” role (
MyReadWriteRole). This operation is the same one in the document.
- JSON file for read-only role configuration :
- JSON file for read-write role configuration :
Create custom roles
MyReadWriteRole with both JSON files. The following example describes how to create custom roles with Azure CLI.
To assign Managed Identity to each role, we have to acquire
roleDefinitionIdof each role with the following command.
roleDefinitionId is corresponding to the attribute “name” in output JSON document.
roleDefinitionId is used to assign Function Apps to either
MyReadOnlyRole role or
MyReadWriteRole role. As you can see in the sample code below, Principal ID is object ID of each managed identity, which you would have taken notes in the previous section.
That’s it. Now let’s do test!
At first, check behaviors by a Function App in
GET method works fine and get data stored in Cosmos DB.
POST method raises exception due to RBAC and returned
403. This is an expected behavior. Masked principal is equal to Principal ID of Managed Identity for read-only Function App.
We can see error messages via Log Streams in Azure Portal.
On the other hand, both
POST methods work fine in case of another Function App in
POST method to modify document...
GET method again to retrieve all data, we can see id:4321 modified.
We confirmed that RBAC configuration provided safe access to Cosmos DB for applications. Even if “upsert” or “delete” method is called from an application in read-only role, no data is modified and we can keep data safe and exception arises.
Demo code used in this article is available in the following GitHub repository.