Secure access to data in Azure Cosmos DB using RBAC

In today’s data-driven world, organizations rely heavily on secure and reliable data storage solutions. Azure Cosmos DB is a popular choice due to its flexibility, scalability, and global distribution capabilities. However, securing access to your Cosmos DB data is of utmost importance to protect sensitive information. While connection strings with keys are a quick way to get started, they are not recommended for production environments. In this blog post, we’ll explore how to achieve secure access to your Azure Cosmos DB using Role-Based Access Control (RBAC) instead of connection strings for C# Azure Functions.

The Problem with Cosmos DB Keys

Azure Cosmos DB provides two types of keys: the primary key and the secondary key. While these keys are convenient for initial development and testing, they pose significant security risks in production environments:

  1. Lack of Granularity: Keys provide full control over the Cosmos DB account, granting access to all resources. In production, you often need to restrict access to specific collections or databases.
  2. Rotation Challenges: Rotating keys periodically is a security best practice, but it can be complex to update keys in all your application components.
  3. Audit and Accountability: Using keys makes it difficult to track who accesses your Cosmos DB data and when.

Now, let’s explore a simple implementation of Azure Functions using a connection string with a key and then move on to RBAC roles and assignments.

Simple Implementation using Connection String with Key

Here’s a basic Azure Function code snippet using a connection string with a key to access Cosmos DB:

using System;
using Microsoft.Azure.Documents;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

public static class CosmosDBFunction
{
    [FunctionName("ReadDataFromCosmosDB")]
    public static void Run(
        [TimerTrigger("0 */5 * * * *")] TimerInfo myTimer,
        ILogger log)
    {
        string connectionString = "your-cosmosdb-connection-string";
        string databaseName = "your-database-name";
        string collectionName = "your-collection-name";

        using (var client = new DocumentClient(new Uri(connectionString), new ConnectionPolicy()))
        {
            var collectionUri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);

            // Query or perform operations on the Cosmos DB data here
        }
    }
}
C#

RBAC Roles and Assignments

Role-based access control
Azure Cosmos DB exposes a built-in role-based access control (RBAC) system that lets you:

Authenticate your data requests with a Microsoft Entra identity.
Authorize your data requests with a fine-grained, role-based permission model.
Azure Cosmos DB RBAC is the ideal access control method in situations where:

You don’t want to use a shared secret like the primary key, and prefer to rely on a token-based authentication mechanism,
You want to use Microsoft Entra identities to authenticate your requests,
You need a fine-grained permission model to tightly restrict which database operations your identities are allowed to perform,
You wish to materialize your access control policies as “roles” that you can assign to multiple identities.

Benjamin isch doof!

Azure Cosmos DB supports Role-Based Access Control (RBAC) for fine-grained access control. RBAC allows you to assign roles to users, service principals, or managed identities to access specific resources in your Azure subscription.

Here are some key RBAC roles relevant to Cosmos DB:

  • Cosmos DB Account Contributor: Allows management of the Cosmos DB account, but not data access.
  • Cosmos DB Operator: Allows read/write access to data in Cosmos DB.
  • Cosmos DB Reader: Allows read-only access to data in Cosmos DB.

Benefits of RBAC

  1. Granularity: RBAC enables fine-grained control over who can access your Cosmos DB resources, down to the collection or database level.
  2. Key Rotation: RBAC eliminates the need to manage keys manually. Users and services can be granted RBAC roles, and access remains secure even after key rotation.
  3. Auditing and Monitoring: Azure provides comprehensive auditing and monitoring capabilities, making it easier to track and review access to your Cosmos DB data.

Implementation using RBAC instead of Connection String

bicep template

resource sqlRoleDefinition 'Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions@2023-09-15' = {
  parent: account
  name: roleDefinitionId
  properties: {
    roleName: roleDefinitionName
    type: 'CustomRole'
    assignableScopes: [
      account.id
    ]
    permissions: [
      {
        dataActions: [
          'Microsoft.DocumentDB/databaseAccounts/readMetadata'
          'Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*'
        ]
      }
    ]
  }
}
BICEP

bicep template for assignment

resource sqlRoleAssignment 'Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments@2023-09-15' = {
  parent: account
  name: roleAssignmentId
  properties: {
    roleDefinitionId: sqlRoleDefinition.id
    principalId: principalId
    scope: account.id // or database.id or container.id
  }
}
BICEP

To implement Azure Functions using RBAC for Cosmos DB access, follow these steps:

  1. Create a Managed Identity: If you haven’t already, create a managed identity for your Azure Function. This identity will be used to grant RBAC roles.
  2. Assign RBAC Roles: Assign the appropriate RBAC roles (e.g., Cosmos DB Operator or Reader) to the managed identity at the Cosmos DB account, database, or collection level, depending on your access requirements.
  3. Use Managed Identity in Azure Function: Modify your Azure Function code to use the managed identity to authenticate with Cosmos DB. You can use the Azure SDK for Cosmos DB to achieve this.

using System;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;

public static class CosmosDBFunction
{
    [FunctionName("ReadDataFromCosmosDB")]
    public static void Run(
        [TimerTrigger("0 */5 * * * *")] TimerInfo myTimer,
        ILogger log)
    {
        string endpoint = "your-cosmosdb-endpoint";
        string databaseName = "your-database-name";
        string collectionName = "your-collection-name";

        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        var tokenCredentials = new DocumentClientTokenCredential(azureServiceTokenProvider);
        var client = new DocumentClient(new Uri(endpoint), tokenCredentials);

        var collectionUri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);

        // Query or perform operations on the Cosmos DB data here
    }
}
C#

By implementing RBAC for Azure Cosmos DB access, you enhance the security and manageability of your application while adhering to best practices for data protection.

Conclusion: Securing access to data in Azure Cosmos DB is a crucial aspect of building robust and reliable applications. While connection strings with keys are suitable for development and testing, they are not recommended for production environments due to their limitations in security and manageability. Leveraging RBAC roles and assignments provides a more granular, secure, and auditable way to control access to your Cosmos DB resources. By following best practices and implementing RBAC, you can ensure that your data remains protected and accessible only to authorized users and services.

Leave a Reply