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
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 getTokenCredentialand use this credential to initializeCosmosClientorCosmosAsyncClient.TokenCredentialis an interface and there are lots of implementation class of the interface, includingManagedIdentityCredential. So, we can also use Managed Identity to configure RBAC for Cosmos DB.
We can get aTokenCredentialinstance with the following code.DefaultAzureCredentialBuilder()is used in this example, but ,ManagedIdentityCredentialBuilder()is also applicable.
TokenCredential tokenCredential = new DefaultAzureCredentialBuilder().build();
Next, we pass theTokenCredentialinstance toCosmosClientBuilder()to initializeCosmosClientorCosmosAsyncClient. As you can see, we don’t have to use any keys to create a client instance. We can createCosmosClient with the following code. AsCosmosClientandCosmosAsyncClientis auto-closable, we should create the client instance surrounded withtry-with-resourcesclause.
After that, codes corresponding toGETmethod andPOSTmethod 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 :role-definition-ro.json
JSON file for read-write role configuration :role-definition-rw.json
Create custom rolesMyReadOnlyRoleandMyReadWriteRolewith 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 acquireroleDefinitionIdof each role with the following command.
roleDefinitionIdis corresponding to the attribute “name” in output JSON document.
Finally, eachroleDefinitionIdis used to assign Function Apps to eitherMyReadOnlyRolerole orMyReadWriteRolerole. 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 inMyReadOnlyRole.GETmethod works fine and get data stored in Cosmos DB.
However,POSTmethod raises exception due to RBAC and returned403. 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, bothGETandPOSTmethods work fine in case of another Function App inMyReadWriteRole.
UsePOSTmethod to modify document...
And useGETmethod 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.