Search code examples
c#azureazure-cosmosdbazure-cosmosdb-sqlapi

What are causes for RBAC permission error in the Azure CosmosDB .Net Library?


While testing basic functionality for Azure CosmosDB noSQL i kept on getting this error:

"Request is blocked because principal [PrincipalID] does not have required RBAC permissions to perform action"

(Full Error)

"Response status code does not indicate success: Forbidden (403); Substatus: 5301; ActivityId: [ActivityId]; Reason: ({\"code\":\"Forbidden\",\"message\":\"Request blocked by Auth [cosmosdbaccountname] : Request is blocked because principal [PrincipalID] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [/]. RequestUri: https://[cosmosdbaccountname].documents.azure.com/;\r\nRequestMethod: GET;\r\nHeader: Authorization Length: [AuthorizationLength];\r\nHeader: Cache-Control Length: 8;\r\nHeader: User-Agent Length: [UserAgentLength];\r\nHeader: x-ms-version Length: 10;\r\nHeader: x-ms-cosmos-sdk-supportedcapabilities Length: 1;\r\nHeader: Accept Length: 16;\r\n, Request URI: /, RequestStats: , SDK: Windows/10.0.19045 cosmos-netstandard-sdk/3.37.1);"}Microsoft.Azure.Cosmos.CosmosException"

Im the owner and only user of this DB, i tried to make sure i am owner by adding that role to my account again. Im logged in with both az login and azd auth login. I have both the database and the container already.

Heres the code im using it in (used foo as example)

using Azure.Identity;
using Microsoft.Azure.Cosmos;

CosmosClient client = new CosmosClient(
    accountEndpoint: "https://[censored].documents.azure.com:[censored]/",
    tokenCredential: new DefaultAzureCredential()
);
Database database = client.GetDatabase("SampleDB");
Container container = database.GetContainer("Foo");

Foo foo = new()
{
    id = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
    Name = "Lorem Ipsum",
    Description = "Lorem Ipsum...",
    Category = (Categories)1 //Enum
};

ItemResponse<Foo> response = await container.CreateItemAsync(foo); //error here

Also tried the CreateContainerIfNotExists method which just got the error itself to.
This was tested in both vscode at first and then later Visual Studio for the debugger.


Solution

  • Request is blocked because principal [PrincipalID] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource

    As per the error you need to give Microsoft.DocumentDB/databaseAccounts/readMetadata to the service principal. To resolve this, you need to create custom role to assign required permission to service principal.

    You can Follow below steps to create and assign role to the Service principal:

    • Create a new role definition using New-AzCosmosDBSqlRoleDefinition.
    $parameters = @{
        ResourceGroupName = "RGName"
        AccountName = "CosmosAccName"
        RoleName = "Azure Cosmos DB for NoSQL Data Plane Owner"
        Type = "CustomRole"
        AssignableScope = @(
            "/"
        )
        DataAction = @(
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*"
        )
    }
    New-AzCosmosDBSqlRoleDefinition @parameters
    

    • Use [Get-AzCosmosDBSqlRoleDefinition] to list all of the role definitions associated with your Azure Cosmos DB.
    $parameters = @{
        ResourceGroupName = "RGName"
        AccountName = "CosmosAccName"
    }
    Get-AzCosmosDBSqlRoleDefinition @parameters
    

    enter image description here

    • Use Get-AzCosmosDBAccount to get the ID for your current account.
    $parameters = @{
        ResourceGroupName = "RGName"
        Name = "CosmosAccName"
    }    
    Get-AzCosmosDBAccount @parameters | Select -Property Id
    

    enter image description here

    • Use New-AzCosmosDBSqlRoleAssignment to assign the new role. List all role assignments for your Azure Cosmos DB for NoSQL account using Get-AzCosmosDBSqlRoleAssignment to check.
    $parameters = @{
        ResourceGroupName = "RGName"
        AccountName = "CosmosAccName"
        RoleDefinitionId = "Id you will get from above created role"
        PrincipalId = "Object ID that you will get from Enterprise applications"
        Scope = "ID obtain fromlast step"
    }    
    New-AzCosmosDBSqlRoleAssignment @parameters
    
    $parameters = @{
        ResourceGroupName = "RGName"
        AccountName = "CosmosAccName"
    }
    Get-AzCosmosDBSqlRoleAssignment @parameters
    

    enter image description here