Connect to Azure Cosmos DB for Apache Gremlin by using role-based access control and Microsoft Entra ID

Role-based access control refers to a method to manage access to resources in Azure. This method is based on specific identities being assigned roles that manage what level of access they have to one or more resources. Role-based access control provides a flexible system of fine-grained access management to ensure that identities have only the least privileged level of access that they need to perform their task.

For more information, see Role-based access control.

Prerequisites

  • Use an Azure account with an active subscription. Create an account.
  • Use an existing Azure Cosmos DB for Gremlin account.
  • Use one or more existing identities in Microsoft Entra ID.
  • 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.

Disable key-based authentication

Disabling key-based authorization prevents your account from being used without the more secure Microsoft Entra ID authentication method. You should perform the steps in this procedure on new accounts in secure workloads. Alternatively, perform this procedure on existing accounts being migrated to a secure workload pattern.

Disable key-based authentication to your existing account so that applications are required to use Microsoft Entra ID authentication. Use az resource update to modify properties.disableLocalAuth of the existing account.

az resource update \
    --resource-group "<name-of-existing-resource-group>" \
    --name "<name-of-existing-account>" \
    --resource-type "Microsoft.DocumentDB/databaseAccounts" \
    --set properties.disableLocalAuth=true

Create a new account with key-based authentication disabled so that applications are required to use Microsoft Entra authentication.

  1. Create a new Bicep file to deploy your new account with key-based authentication disabled. Name the file deploy-new-account.bicep.

    metadata description = 'Deploys a new Azure Cosmos DB account with key-based auth disabled.'
    
    @description('Name of the Azure Cosmos DB account.')
    param name string = 'csms-${uniqueString(resourceGroup().id)}'
    
    @description('Primary location for the Azure Cosmos DB account.')
    param location string = resourceGroup().location
    
    resource account 'Microsoft.DocumentDB/databaseAccounts@2024-05-15' = {
      name: name
      location: location
      kind: 'GlobalDocumentDB'
      properties: {
        databaseAccountOfferType: 'Standard'
        locations: [
          {
            locationName: location
          }
        ]
        disableLocalAuth: true
      }
    }
    
  2. Use az deployment group create to deploy the Bicep file with the new account.

    az deployment group create \
        --resource-group "<name-of-existing-resource-group>" \
        --template-file deploy-new-account.bicep
    

Disable key-based authentication to your existing account so that applications are required to use Microsoft Entra authentication. Use Get-AzResource to read the existing account. Use Set-AzResource to update the account.

$parameters = @{
    ResourceGroupName = "<name-of-existing-resource-group>"
    ResourceName = "<name-of-existing-account>"
    ResourceType = "Microsoft.DocumentDB/databaseAccounts"
}
$resource = Get-AzResource @parameters

$resource.Properties.DisableLocalAuth = $true

$resource | Set-AzResource -Force

Follow these steps to create a new Azure Cosmos DB for NoSQL account with key-based authentication disabled so that applications are required to use only Microsoft Entra authentication.

  1. When you set up a new Azure Cosmos DB for NoSQL account, go to the Security section of the account-creation process.

  2. For the Key-based authentication option, select Disable.

    Screenshot that shows the option to disable key-based authentication when you create a new account in the Azure portal.

Important

Modifying an Azure Cosmos DB account requires an Azure role with at least the Microsoft.DocumentDb/databaseAccounts/*/write permission. For more information, see Permissions for Azure Cosmos DB.

Validate that key-based authentication is disabled

To validate that key-based access is disabled, attempt to use the Azure SDK to connect to Azure Cosmos DB for Gremlin by using a resource-owner password credential. This attempt should fail. If necessary, code samples for common programming languages are provided here.

using Azure.Data.Tables;
using Azure.Core;

string connectionString = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;";

TableServiceClient client = new(connectionString);
const { TableServiceClient } = require('@azure/data-tables');

const connectionString = 'AccountEndpoint=<table-endpoint>;AccountKey=<key>;';

const client = new TableServiceClient(connectionString);
from azure.data.tables import TableServiceClient

connection_string = "AccountEndpoint=<table-endpoint>;AccountKey=<key>;"

client = TableServiceClient(endpoint, connection_string)

Grant control plane role-based access

Control plane access refers to the ability to manage resources for an Azure service without managing data. For example, Azure Cosmos DB control plane access could include the ability to:

  • Read all account and resource metadata.
  • Read and regenerate account keys and connection strings.
  • Perform account backups and restore.
  • Start and track data transfer jobs.
  • Manage databases and containers.
  • Modify account properties.

Important

In Azure Cosmos DB, you need control plane access to manage native data-plane role-based access control definitions and assignments. Because the Azure Cosmos DB data plane role-based access control mechanism is native, you need control plane access to create definitions and assignments and store them as resources within an Azure Cosmos DB account.

First, you must prepare a role definition with a list of actions to grant access to manage account resources in Azure Cosmos DB. In this article, you prepare a built-in and custom role. Then, you assign the newly defined role or roles to an identity so that your applications can access resources in Azure Cosmos DB.

  1. List all the role definitions associated with your Azure Cosmos DB account by using az role definition list.

    az role definition list \
        --name "Cosmos DB Operator"
    
  2. Review the output and locate the role definition named Cosmos DB Operator. The output contains the unique identifier of the role definition in the id property. Record this value because you must use it in the assignment step later in this article.

    [
      {
        "assignableScopes": [
          "/"
        ],
        "description": "Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings.",
        "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa",
        "name": "230815da-be43-4aae-9cb4-875f7bd000aa",
        "permissions": [
          {
            "actions": [
              "Microsoft.DocumentDb/databaseAccounts/*",
              "Microsoft.Insights/alertRules/*",
              "Microsoft.Authorization/*/read",
              "Microsoft.ResourceHealth/availabilityStatuses/read",
              "Microsoft.Resources/deployments/*",
              "Microsoft.Resources/subscriptions/resourceGroups/read",
              "Microsoft.Support/*",
              "Microsoft.Network/virtualNetworks/subnets/joinViaServiceEndpoint/action"
            ],
            "condition": null,
            "conditionVersion": null,
            "dataActions": [],
            "notActions": [
              "Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*",
              "Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*",
              "Microsoft.DocumentDB/databaseAccounts/regenerateKey/*",
              "Microsoft.DocumentDB/databaseAccounts/listKeys/*",
              "Microsoft.DocumentDB/databaseAccounts/listConnectionStrings/*",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/delete",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/write",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/delete",
              "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/delete",
              "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/delete"
            ],
            "notDataActions": []
          }
        ],
        "roleName": "Cosmos DB Operator",
        "roleType": "BuiltInRole",
        "type": "Microsoft.Authorization/roleDefinitions",
      }
    ]
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa. This example uses fictitious data, and your identifier is distinct from this example. However, the identifier (230815da-be43-4aae-9cb4-875f7bd000aa) is globally unique across all role definitions in Azure.

  3. Use az group show to get the metadata for your current resource group.

    az group show \
        --name "<name-of-existing-resource-group>"
    
  4. Observe the output of the previous command. Record the value of the id property for this resource group because you must use it in the next step.

    {
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example",
      "location": "chinanorth3",
      "name": "msdocs-identity-example",
      "type": "Microsoft.Resources/resourceGroups"
    }
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example. This example uses fictitious data, and your identifier is distinct from this example. This string is a truncated example of the output.

  5. Create a new JSON file named role-definition.json. In the file, create this resource definition that specifies the values listed here. For the AssignableScopes list, add the id property of the resource group recorded in the previous step.

    {
      "Name": "Azure Cosmos DB Control Plane Owner",
      "IsCustom": true,
      "Description": "Can perform all control plane actions for an Azure Cosmos DB account.",
      "Actions": [
        "Microsoft.DocumentDb/*"
      ],
      "AssignableScopes": [
        "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example"
      ]
    }
    

    This example uses the /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example value recorded from the previous step. Your actual resource identifier could be different.

  6. Create a new role definition by using az role definition create. Use role-definition.json as the input for the --role-definition argument.

    az role definition create \
        --role-definition role-definition.json
    
  7. Review the output from the definition creation command. The output contains the unique identifier of the role definition in the id property. Record this value because you must use it in the assignment step later in this article.

    {
      "assignableScopes": [
        "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example"
      ],
      "description": "Can perform all control plane actions for an Azure Cosmos DB account.",
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1",
      "name": "e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5",
      "permissions": [
        {
          "actions": [
            "Microsoft.DocumentDb/*"
          ]
        }
      ],
      "roleName": "Azure Cosmos DB Control Plane Owner",
      "roleType": "CustomRole"
    }
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1. This example uses fictitious data, and your identifier is distinct from this example. This example is a subset of the typical JSON outputted from the deployment for clarity.

  8. Use az group show to get the metadata for your current resource group again.

    az group show \
        --name "<name-of-existing-resource-group>"
    
  9. Observe the output of the previous command. Record the value of the id property for this resource group because you must use it in the next step.

    {
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example",
      "location": "westus",
      "name": "msdocs-identity-example",
      "type": "Microsoft.Resources/resourceGroups"
    }
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example. This example uses fictitious data, and your identifier is distinct from this example. This string is a truncated example of the output.

  10. Assign the new role by using az role assignment create. Use your resource group's identifier for the --scope argument, the role's identifier for the -role argument, and the unique identifier for your identity to the --assignee argument.

    az role assignment create \
        --assignee "<your-principal-identifier>" \
        --role "subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1" \
        --scope "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example"
    

    In this example command, the scope property was set to the fictitious example /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example from the previous step's example. Your resource group's identifier is distinct from this example. The role value was also set to the fictitious /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1. Again, your role identifier is distinct.

  11. Observe the output from the command. The output includes a unique identifier for the assignment in the id property.

    {
      "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1",
      "name": "ffffffff-5555-6666-7777-aaaaaaaaaaaa",
      "principalId": "aaaaaaaa-bbbb-cccc-1111-222222222222",
      "resourceGroup": "msdocs-identity-example",
      "roleDefinitionId": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1",
      "scope": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example",
      "type": "Microsoft.Authorization/roleAssignments"
    }
    

    In this example, the id property is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1, which is another fictitious example.

  12. Repeat these steps to grant access to the account from any other identities that you want to use.

    You can repeat these steps for as many identities as you want. Typically, these steps are at least repeated to allow developers access to an account by using their human identity and to allow applications access to the data by using a managed identity.

  1. List all the role definitions associated with your Azure Cosmos DB account by using az role definition list.

    az role definition list \
        --name "Cosmos DB Operator"
    
  2. Review the output and locate the role definition named Cosmos DB Operator. The output contains the unique identifier of the role definition in the id property. Record this value because you must use it in the assignment step later in this article.

    [
      {
        "assignableScopes": [
          "/"
        ],
        "description": "Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings.",
        "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa",
        "name": "230815da-be43-4aae-9cb4-875f7bd000aa",
        "permissions": [
          {
            "actions": [
              "Microsoft.DocumentDb/databaseAccounts/*",
              "Microsoft.Insights/alertRules/*",
              "Microsoft.Authorization/*/read",
              "Microsoft.ResourceHealth/availabilityStatuses/read",
              "Microsoft.Resources/deployments/*",
              "Microsoft.Resources/subscriptions/resourceGroups/read",
              "Microsoft.Support/*",
              "Microsoft.Network/virtualNetworks/subnets/joinViaServiceEndpoint/action"
            ],
            "condition": null,
            "conditionVersion": null,
            "dataActions": [],
            "notActions": [
              "Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*",
              "Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*",
              "Microsoft.DocumentDB/databaseAccounts/regenerateKey/*",
              "Microsoft.DocumentDB/databaseAccounts/listKeys/*",
              "Microsoft.DocumentDB/databaseAccounts/listConnectionStrings/*",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleDefinitions/delete",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/write",
              "Microsoft.DocumentDB/databaseAccounts/sqlRoleAssignments/delete",
              "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/mongodbRoleDefinitions/delete",
              "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/write",
              "Microsoft.DocumentDB/databaseAccounts/mongodbUserDefinitions/delete"
            ],
            "notDataActions": []
          }
        ],
        "roleName": "Cosmos DB Operator",
        "roleType": "BuiltInRole",
        "type": "Microsoft.Authorization/roleDefinitions",
      }
    ]
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/providers/Microsoft.Authorization/roleDefinitions/230815da-be43-4aae-9cb4-875f7bd000aa. This example uses fictitious data, and your identifier is distinct from this example. However, the identifier (230815da-be43-4aae-9cb4-875f7bd000aa) is globally unique across all role definitions in Azure.

  3. Create a new Bicep file to define your role definition. Name the file control-plane-role-definition.bicep. Add the following action to the definition:

    Action Description
    Microsoft.DocumentDb/* Enables all possible actions.
    metadata description = 'Create RBAC definition for control plane access to Azure Cosmos DB.'
    
    @description('Name of the role definition.')
    param roleDefinitionName string = 'Azure Cosmos DB Control Plane Owner'
    
    @description('Description of the role definition.')
    param roleDefinitionDescription string = 'Can perform all control plane actions for an Azure Cosmos DB account.'
    
    resource definition 'Microsoft.Authorization/roleDefinitions@2022-04-01' = {
      name: guid(subscription().id, resourceGroup().id, roleDefinitionName)
      scope: resourceGroup()
      properties: {
        roleName: roleDefinitionName
        description: roleDefinitionDescription
        type: 'CustomRole'
        permissions: [
          {
            actions: [
              'Microsoft.DocumentDb/*'
            ]
          }
        ]
        assignableScopes: [
          resourceGroup().id
        ]
      }
    }
    
    output definitionId string = definition.id
    
  4. Deploy the Bicep template by using az deployment group create. Specify the name of the Bicep template and Azure resource group.

    az deployment group create \
        --resource-group "<name-of-existing-resource-group>" \
        --template-file control-plane-role-definition.bicep
    
  5. Review the output from the deployment. The output contains the unique identifier of the role definition in the properties.outputs.definitionId.value property. Record this value because you must use it in the assignment step later in this article.

    {
      "properties": {
        "outputs": {
          "definitionId": {
            "type": "String",
            "value": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1"
          }
        }
      }
    }
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleDefinitions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1. This example uses fictitious data, and your identifier is distinct from this example. This example is a subset of the typical JSON outputted from the deployment for clarity.

  6. Create a new Bicep file to define your role assignment. Name the file control-plane-role-assignment.bicep.

    metadata description = 'Assign RBAC role for control plane access to Azure Cosmos DB.'
    
    @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 assignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
      name: guid(subscription().id, resourceGroup().id, roleDefinitionId, identityId)
      scope: resourceGroup()
      properties: {
        roleDefinitionId: roleDefinitionId
        principalId: identityId
      }
    }
    
  7. Create a new Bicep parameters file named control-plane-role-assignment.bicepparam. In this parameters file, assign the previously recorded role definition identifiers to the roleDefinitionId parameter. Assign the unique identifier for your identity to the identityId parameter.

    using './control-plane-role-assignment.bicep'
    
    param roleDefinitionId = '<id-of-new-role-definition>'
    param identityId = '<id-of-existing-identity>'
    
  8. Deploy this Bicep template by using az deployment group create.

    az deployment group create \
        --resource-group "<name-of-existing-resource-group>" \
        --parameters control-plane-role-assignment.bicepparam \
        --template-file control-plane-role-assignment.bicep
    
  9. Repeat these steps to grant access to the account from any other identities that you want to use.

    You can repeat these steps for as many identities as you want. Typically, these steps are at least repeated to allow developers access to an account by using their human identity and to allow applications access to the data by using a managed identity.

  1. Sign in to the Azure portal.

  2. Enter Resource group in the global search bar.

    Screenshot that shows the global search bar in the Azure portal.

  3. Within Services, select Resource groups.

    Screenshot that shows the Resource groups option selected in the search menu.

  4. In the Resource groups pane, select your existing resource group.

    Screenshot that shows an existing resource group in the list of resource groups for the subscription.

    This example screenshot includes the msdocs-identity-example resource group. Your actual resource group name could be different.

  5. Within the pane for the resource group, select Access control (IAM) on the service menu.

    Screenshot that shows the Access Control (IAM) option on the service menu for a resource group.

  6. In the Access control (IAM) pane, select Roles.

    Screenshot that shows the Roles option in the Access Control (IAM) pane.

  7. In the Roles section, use the search phrase Cosmos DB and locate the Cosmos DB Operator role definition. Then, select the View option associated with that definition.

    Screenshot that shows a list of role definitions at the current assignable scope filtered to include only definitions with Cosmos DB in the title.

  8. In the Cosmos DB Operator role definition dialog, observe the actions assigned as part of this role definition.

    Screenshot that shows the Cosmos DB Operator dialog with details about the built-in role definition.

  9. Close the Cosmos DB Operator role definition dialog.

  10. Back in the Access control (IAM) pane, select Add. Then select Add custom role.

    Screenshot that shows the Add custom role option in the Access Control (IAM) menu for the Add option.

  11. In the Basics pane, configure the following options, and then select Next.

    Option Value
    Custom role name Azure Cosmos DB Control Plane Owner
    Description Can perform all control plane actions for an Azure Cosmos DB account.
    Baseline permissions Start from scratch

    Screenshot that shows the Basics pane for adding a custom role.

  12. In the Permissions pane, select Add permissions. Then, search for DocumentDB in the Permissions dialog. Finally, select the Microsoft.DocumentDB option.

    Screenshot that shows the Permissions pane for adding a custom role.

    Screenshot that shows the Add permissions dialog filtered to permissions related to DocumentDB for adding a custom role.

  13. In the Permissions dialog, select all Actions for Microsoft.DocumentDB. Then, select Add to return to the Permissions pane.

    Screenshot that shows all permissions selected for DocumentDB in a dialog for a custom role.

  14. Back in the Permissions pane, observe the list of permissions. Then, select Review + create.

    Screenshot that shows the Permissions pane with multiple permissions added to the list for a custom role.

  15. In the Review + create pane, review the specified options for the new role definition. Finally, select Create.

    Screenshot that shows the Review + create pane for adding a custom role.

  16. Wait for the portal to finish creating the role definition.

  17. In the Access control (IAM) pane, select Add > Add role assignment.

    Screenshot that shows the Add role assignment option on the Access Control (IAM) menu for the Add option.

  18. In the Role pane, search for Azure Cosmos DB and then select the Azure Cosmos DB Control Plane Owner role that you created earlier in this article. Then select Next.

    Screenshot that shows the Role pane for adding a role assignment.

    You can optionally filter the list of roles to include only custom roles.

  19. In the Members pane, select the Select members option. In the Members dialog, select the identity that you want to grant this level of access for your Azure Cosmos DB account. Then use the Select option to confirm your choice.

    Screenshot that shows the Members pane for adding a role assignment.

    Screenshot that shows the identity selection dialog for adding a role assignment.

    This screenshot illustrates an example user named Kai Carter with a principal of kai@adventure-works.com.

  20. Back in the Members pane, review the selected members and then select Review + assign.

    Screenshot that shows the Members pane with a selected identity for a role assignment.

  21. In the Review + assign pane, review the specified options for the new role assignment. Finally, select Review + assign.

    Screenshot that shows the Review + create pane for a role assignment.

  22. Wait for the portal to finish creating the role assignment.

  1. Use Get-AzRoleDefinition to list all the role definitions associated with your Azure Cosmos DB account.

    $parameters = @{
        Name = "Cosmos DB Operator"
    }
    Get-AzRoleDefinition @parameters
    
  2. 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 because you must use it in the assignment step later in this article.

    Name             : Cosmos DB Operator
    Id               : 230815da-be43-4aae-9cb4-875f7bd000aa
    IsCustom         : False
    Description      : Lets you manage Azure Cosmos DB accounts, but not access data in them. Prevents access to account keys and connection strings.
    Actions          : {Microsoft.DocumentDb/databaseAccounts/*, Microsoft.Insights/alertRules/*, Microsoft.Authorization/*/read, Microsoft.ResourceHealth/availabilityStatuses/read…}
    NotActions       : {Microsoft.DocumentDB/databaseAccounts/dataTransferJobs/*, Microsoft.DocumentDB/databaseAccounts/readonlyKeys/*, Microsoft.DocumentDB/databaseAccounts/regenerateKey/*, Microsoft.DocumentDB/databaseAccounts/listKeys/*…}
    DataActions      : {}
    NotDataActions   : {}
    AssignableScopes : {/}
    

    In this example, the Id value is 230815da-be43-4aae-9cb4-875f7bd000aa. The identifier is globally unique across all role definitions in Azure.

  3. Use Get-AzResourceGroup to get the metadata for your current resource group.

    $parameters = @{
        Name = "<name-of-existing-resource-group>"
    }
    Get-AzResourceGroup @parameters
    
  4. Observe the output of the previous command. Record the value of the ResourceId property for this resource group because you must use it in the next step.

    ResourceGroupName : msdocs-identity-example
    Location          : westus
    ProvisioningState : Succeeded
    ResourceId        : /subscriptions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1/resourcegroups/msdocs-identity-example
    

    In this example, the ResourceId value is /subscriptions/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1/resourcegroups/msdocs-identity-example. This example uses fictitious data, and your identifier is distinct from this example. This string is a truncated example of the typical output.

  5. First, import the Az.Resources module. Then, create a new Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition object. In the object, create this resource definition that specifies the values listed here. For the AssignableScopes list, add the ResourceId property of the resource group recorded in the previous step. Finally, use the role definition object as the input for the -Role parameter of New-AzRoleDefinition.

    Import-Module Az.Resources
    
    $parameters = @{
        TypeName = "Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleDefinition"
        Property = @{
            Name = "Azure Cosmos DB Control Plane Owner"
            Description = "Can perform all control plane actions for an Azure Cosmos DB account."
            IsCustom = $true
            Actions = @(
                "Microsoft.DocumentDb/*"
            )
            AssignableScopes = @(
                "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example"
            )
        }
    }
    $role = New-Object @parameters
    
    New-AzRoleDefinition -Role $role
    

    This example uses the /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example value recorded from the previous step. Your actual resource identifier could be different.

  6. Review the output from the definition creation command. The output contains the unique identifier of the role definition in the Name property. Record this value because you must use it in the assignment step later in this article.

    Name             : Azure Cosmos DB Control Plane Owner
    Id               : e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5
    IsCustom         : True
    Description      : Can perform all control plane actions for an Azure Cosmos DB account.
    Actions          : {Microsoft.DocumentDb/*}
    AssignableScopes : {/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example}
    

    In this example, the Name value is Azure Cosmos DB Control Plane Owner. This example is a subset of the typical output of the deployment for clarity.

  7. Assign the new role by using New-AzRoleAssignment. Use the role's name for the RoleDefinitionName parameter and the unique identifier for your identity to the ObjectId parameter.

    $parameters = @{
        ResourceGroupName = "<name-of-existing-resource-group>"
        ObjectId = "<your-principal-identifier>"
        RoleDefinitionName = "Azure Cosmos DB Control Plane Owner"
    }
    New-AzRoleAssignment @parameters
    
  8. Observe the output from the command. The output includes a unique identifier for the assignment in the RoleAssignmentId property.

    RoleAssignmentName : ffffffff-5555-6666-7777-aaaaaaaaaaaa
    RoleAssignmentId   : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1
    Scope              : /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example
    DisplayName        : Kai Carter
    SignInName         : <kai@adventure-works.com>
    RoleDefinitionName : Azure Cosmos DB Control Plane Owner
    RoleDefinitionId   : e4e4e4e4-ffff-aaaa-bbbb-c5c5c5c5c5c5
    

    In this example, the RoleAssignmentId property is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.Authorization/roleAssignments/a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1, which is another fictitious example. This example is a subset of the typical output of the deployment for clarity.

  9. Repeat these steps to grant access to the account from any other identities that you want to use.

    You can repeat these steps for as many identities as you want. Typically, these steps are at least repeated to allow developers access to an account by using their human identity and to allow applications access to the data by using a managed identity.

Important

Assigning a role definition requires you to already have the unique identifier of any identity that you want to grant role-based access control permissions.

Validate control plane role-based access in code

Validate that you correctly granted access by using application code and the Azure Management SDK.

using Azure.Identity;
using Azure.ResourceManager;

DefaultAzureCredential credential = new();

ArmClient client = new(credential);
const { CosmosDBManagementClient } = require('@azure/arm-cosmosdb');
const { DefaultAzureCredential } = require('@azure/identity');

const subscriptionId = "<subscription-id>";

const credential = new DefaultAzureCredential();

const client = new CosmosDBManagementClient(credential, subscriptionId);
import { CosmosDBManagementClient } from '@azure/arm-cosmosdb';
import { TokenCredential, DefaultAzureCredential } from '@azure/identity';

let subscriptionId: string = "<subscription-id>";

let credential: TokenCredential = new DefaultAzureCredential();

const client: CosmosDBManagementClient = new CosmosDBManagementClient(credential, subscriptionId);
from azure.mgmt.cosmosdb import CosmosDBManagementClient
from azure.identity import DefaultAzureCredential

subscription_id = "<subscription-id>"

credential = DefaultAzureCredential()

client = CosmosDBManagementClient(credential=credential, subscription=subscription_id)
package main

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos"
)

const subscriptionId = "<subscription-id>"

func main() {
    credential, _ := azidentity.NewDefaultAzureCredential(nil)
    
    client, _ := armcosmos.NewDatabaseClient(subscriptionId, credential, nil)
}
package com.example;

import com.azure.core.management.profile.AzureProfile;
import com.azure.core.management.AzureEnvironment;
import com.azure.identity.DefaultAzureCredential;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.resourcemanager.cosmos.CosmosManager;

public class CosmosDB {
    public static void main(String[] args) {
        AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
          .build();

        CosmosManager manager = CosmosManager.authenticate(credential, profile);
    }
}

Grant data plane role-based access

Data plane access refers to the ability to read and write data within an Azure service without the ability to manage resources in the account. For example, Azure Cosmos DB data plane access could include the ability to:

  • Read some account and resource metadata.
  • Create, read, update, patch, and delete items.
  • Run Gremlin queries.
  • Read from a container's change feed.
  • Run stored procedures.
  • Manage conflicts in the conflict feed.

First, you must prepare a role definition with a list of data actions to grant access to read, query, and manage data in Azure Cosmos DB for Gremlin. In this article, you prepare a built-in and custom role. Then, assign the newly defined role to an identity so that your applications can access data in Azure Cosmos DB for Gremlin.

  1. List all the role definitions associated with your Azure Cosmos DB for Gremlin account by using az cosmosdb gremlin role definition list.

    az cosmosdb gremlin role definition list \
      --account-name <account-name> \
      --resource-group <resource-group>
    
  2. 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 because you need to use it in the assignment step later in this article.

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004. This example uses fictitious data, and your identifier is distinct from this example.

  3. Create a new JSON file named role-definition.json. In this file, create a resource definition that specifies the data actions that you want to allow.

  4. Use az cosmosdb gremlin role definition create to create the role definition. Use role-definition.json as the input for the --body argument.

    az cosmosdb gremlin role definition create \
      --account-name <account-name> \
      --resource-group <resource-group> \
      --body @role-definition.json
    
  5. List all the role definitions again and record the id property of your new custom role.

  6. Assign the new role by using az cosmosdb gremlin role assignment create. Use the previously recorded role definition identifier, the unique identifier for your identity, and the scope (account, database, or graph).

    az cosmosdb gremlin role assignment create \
      --account-name <account-name> \
      --resource-group <resource-group> \
      --role-definition-id <role-definition-id> \
      --principal-id <principal-id> \
      --scope /
    
  7. Use az cosmosdb gremlin role assignment list to list all role assignments for your account, and verify your assignment.

    az cosmosdb gremlin role assignment list \
      --account-name <account-name> \
      --resource-group <resource-group>
    
  1. First, get the resource identifier of the existing Azure Cosmos DB for Gremlin account by using az cosmsodb show, and store it in a variable.

    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/gremlinRoleDefinitions?api-version=2023-04-15
    
  2. Then, list all the role definitions associated with your Azure Cosmos DB for Gremlin account by 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 because you need to use it in the assignment step later in this article.

    [
      ...,
      {
        "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004",
        "name": "00000000-0000-0000-0000-000000000004",
        "properties": {
          "assignableScopes": [
            "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin"
          ],
          "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/gremlinRoleDefinitions"
      }
      ...
    ]
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-gremlin/gremlinRoleDefinitions/00000000-0000-0000-0000-000000000004. This example uses fictitious data, and your identifier is distinct from this example. This example output is truncated.

  3. Create a new Bicep file to define your role definition. Name the file data-plane-role-definition.bicep. Add the following data actions to the definition:

    Data action Description
    Microsoft.DocumentDB/databaseAccounts/readMetadata
    Microsoft.DocumentDB/databaseAccounts/tables/*
    Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*
    metadata description = 'Create RBAC definition for data plane access to Azure Cosmos DB for Gremlin.'
    
    @description('Name of the Azure Cosmos DB for Gremlin account.')
    param accountName string
    
    @description('Name of the role definition.')
    param roleDefinitionName string = 'API for Gremlin Data Plane Owner'
    
    resource account 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' existing = {
      name: accountName
    }
    
    resource definition 'Microsoft.DocumentDB/databaseAccounts/gremlinRoleDefinitions@2023-04-15' = {
      name: guid('table-role-definition', account.id)
      parent: account
      properties: {
        roleName: roleDefinitionName
        type: 'CustomRole'
        assignableScopes: [
          account.id
        ]
        permissions: [
          {
            dataActions: [
              'Microsoft.DocumentDB/databaseAccounts/readMetadata'
              'Microsoft.DocumentDB/databaseAccounts/tables/*'
              'Microsoft.DocumentDB/databaseAccounts/tables/containers/entities/*'
            ]
          }
        ]
      }
    }
    
    output definitionId string = definition.id
    

    Tip

    In the Azure Cosmos DB native implementation of role-based access control, scope refers to the granularity of resources within an account for which you want permission applied. At the highest level, you can scope a data plane role-based access control assignment to the entire account by using the largest scope. This scope includes all databases and containers within the account:

    /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/
    

    Or, you can scope your data plane role assignment to a specific database:

    /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>
    

    Finally, you can scope the assignment to a single container, the most granular scope:

    /subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.DocumentDB/databaseAccounts/<account-name>/dbs/<database-name>/colls/<container-name>
    

    In many cases, you can use the relative scope instead of the fully qualified scope. For example, you can use this relative scope to grant data plane role-based access control permissions to a specific database and container from an Azure CLI command:

    /dbs/<database-name>/colls/<container-name>
    

    You can also grant universal access to all databases and containers by using the relative scope:

    /
    
  4. Create a new Bicep parameters file named data-plane-role-definition.bicepparam. In this parameters file, assign the name of your existing Azure Cosmos DB for Gremlin account to the accountName parameter.

    using './data-plane-role-definition.bicep'
    
    param accountName = '<name-of-existing-table-account>'
    
  5. Deploy the Bicep template by using az deployment group create. Specify the name of the Bicep template, parameters file, and Azure resource group.

    az deployment group create \
        --resource-group "<name-of-existing-resource-group>" \
        --parameters data-plane-role-definition.bicepparam \
        --template-file data-plane-role-definition.bicep
    
  6. Review the output from the deployment. The output contains the unique identifier of the role definition in the properties.outputs.definitionId.value property. Record this value because you need to use it in the assignment step later in this article.

    {
      "properties": {
        "outputs": {
          "definitionId": {
            "type": "String",
            "value": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table-account/gremlinRoleDefinitions/dddddddd-9999-0000-1111-eeeeeeeeeeee"
          }
        }
      }
    }
    

    In this example, the id value is /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourcegroups/msdocs-identity-example/providers/Microsoft.DocumentDB/databaseAccounts/msdocs-identity-example-table-account/gremlinRoleDefinitions/dddddddd-9999-0000-1111-eeeeeeeeeeee. This example uses fictitious data, and your identifier is distinct from this example. This example is a subset of the typical JSON outputted from the deployment for clarity.

  7. 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 Gremlin.'
    
    @description('Name of the Azure Cosmos DB for Gremlin 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
    
  8. 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 Gremlin account to the accountName parameter. Assign the previously recorded role definition identifiers to the roleDefinitionId parameter. Also assign the unique identifier for your identity to the identityId 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>'
    
  9. Deploy this Bicep template by 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
    
  10. Repeat these steps to grant access to the account from any other identities that you want to use.

    You can repeat these steps for as many identities as you want. Typically, these steps are at least repeated to allow developers access to an account by using their human identity and to allow applications access to data by using a managed identity.

  1. List all the role definitions associated with your Azure Cosmos DB for Gremlin account by using Get-AzCosmosDBGremlinRoleDefinition.

    Get-AzCosmosDBGremlinRoleDefinition \
      -AccountName <account-name> \
      -ResourceGroupName <resource-group>
    
  2. 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 because you need to use it in the assignment step later in this article.

  3. Create a new role definition by using New-AzCosmosDBGremlinRoleDefinition and a JSON file that describes the permissions that you want to allow.

    New-AzCosmosDBGremlinRoleDefinition \
      -AccountName <account-name> \
      -ResourceGroupName <resource-group> \
      -InputObject (Get-Content -Raw -Path ./role-definition.json | ConvertFrom-Json)
    
  4. List all the role definitions again, and record the Id value of your new custom role.

  5. Assign the new role by using New-AzCosmosDBGremlinRoleAssignment. Use the previously recorded role definition identifier, the unique identifier for your identity, and the scope (account, database, or graph).

    New-AzCosmosDBGremlinRoleAssignment \
      -AccountName <account-name> \
      -ResourceGroupName <resource-group> \
      -RoleDefinitionId <role-definition-id> \
      -PrincipalId <principal-id> \
      -Scope /
    
  6. List all role assignments for your account, and verify your assignment.

    Get-AzCosmosDBGremlinRoleAssignment \
      -AccountName <account-name> \
      -ResourceGroupName <resource-group>
    

Warning

Managing data plane role-based access control isn't supported in the Azure portal.

Validate data plane role-based access in code

Validate that you correctly granted access by using application code and the Azure SDK.

using Azure.Identity;
using Azure.Core;
using Azure.Identity;
using Microsoft.Azure.Cosmos.Gremlin;

ManagedIdentityCredential defaultCredential = new ManagedIdentityCredential();
var scopes = new string[] { $"https://cosmos.azure.cn/.default" };
CancellationTokenSource cts = new CancellationTokenSource();

var accessToken = await defaultCredential.GetTokenAsync(new TokenRequestContext(scopes), cts.Token);
var credentialString = accessToken.Token;

var server = new GremlinServer(
    hostname: "<account-name>.gremlin.cosmos.azure.cn",
    port: 443,
    username: "/dbs/<database-name>/colls/<graph-name>",
    password: credentialString,
    enableSsl: true
);

var client = new GremlinClient(
    gremlinServer: server,
    graphSONReader: new GraphSON3Reader(),
    graphSONWriter: new GraphSON2Writer(),
    GremlinClient.GraphSON2MimeType
);
const { DefaultAzureCredential } = require('@azure/identity');
const gremlin = require('gremlin');

const credential = new DefaultAzureCredential();
const tokenResponse = await credential.getToken('https://cosmos.azure.cn/.default');
const accessToken = tokenResponse.token;

const credentials = new gremlin.driver.auth.PlainTextSaslAuthenticator(
  `/dbs/<database-name>/colls/<graph-name>`,
  accessToken
);

const client = new gremlin.driver.Client(
  `https://<account-name>.gremlin.cosmos.azure.cn:443/`,
  {
    authenticator: credentials,
    traversalSource: 'g',
    mimeType: 'application/vnd.gremlin-v2.0+json',
  }
);
from azure.identity import ManagedIdentityCredential
from gremlin_python.driver import client, serializer

credential = ManagedIdentityCredential()
access_token = credential.get_token(SCOPE)
credential_string = access_token.token

gremlin_client = client.Client(
    url="wss://<account-name>.gremlin.cosmos.azure.cn",
    traversal_source="g",
    username="/dbs/<database-name>/colls/<graph-name>}",
    password=f"{credential_string}",
    message_serializer=serializer.GraphSONSerializersV2d0(),
)
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.core.credential.TokenRequestContext;
import com.azure.core.credential.AccessToken;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.apache.tinkerpop.gremlin.driver.Client;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV2d0;

TokenCredential credential = new DefaultAzureCredentialBuilder().build();
TokenRequestContext requestContext = new TokenRequestContext().addScopes(scope);
AccessToken accessToken = credential.getToken(requestContext).block();
String credentialString = accessToken.getToken();

String resourcePath = "/dbs/" + "<database-name>" + "/colls/" + "<graph-name>";
Cluster cluster = Cluster.build()
        .addContactPoint("<account-endpoint>")
        .port(443)
        .credentials(resourcePath, credentialString)
        .enableSsl(true)
        .maxWaitForConnection(100000)
        .serializer(new GraphSONMessageSerializerV2d0())
        .create();

Client client = cluster.connect();