Search code examples
azure-resource-managerazure-keyvaultazure-bicepazure-rbac

Bicep roleAssignments/write permission error when assigning a role to Keyvault


I am using GitHub Actions to deploy via Bicep:

- name: Login
  uses: azure/login@v1
  with:
    creds: ${{ secrets.AZURE_CREDENTIALS }}
        
- name: Deploy Bicep file
  uses: azure/arm-deploy@v1
  with:
    scope: subscription
    subscriptionId: ${{ secrets.AZURE_CREDENTIALS_subscriptionId }}
    region: ${{ env.DEPLOY_REGION }}
    template: ${{ env.BICEP_ENTRY_FILE }}
    parameters: parameters.${{ inputs.selectedEnvironment }}.json

I have used a contributor access for my AZURE_CREDENTIALS based on the output of the next command:

az ad sp create-for-rbac --n infra-bicep --role contributor --scopes /subscriptions/my-subscription-guid --sdk-auth

I am using Azure Keyvault with RBAC. This Bicep has worked fine until I tried to give an Azure Web App a keyvault read access to the Keyvault as such:

var kvSecretsUser = '4633458b-17de-408a-b874-0445c86b69e6'
var kvSecretsUserRole = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', kvSecretsUser)
resource kx_webapp_roleAssignments 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
  name: 'kv-webapp-roleAssignments'
  scope: kv
  properties: {
    principalId: webappPrincipleId
    principalType: 'ServicePrincipal'
    roleDefinitionId: kvSecretsUserRole
  }
}

Then I was hit with the following error:

'Authorization failed for template resource 'kv-webapp-roleAssignments' 
of type 'Microsoft.Authorization/roleAssignments'. 
The client 'guid-value' with object id 'guid-value' does not have permission to perform action 
'Microsoft.Authorization/roleAssignments/write' at scope
 '/subscriptions/***/resourceGroups/rg-x/providers/Microsoft.KeyVault/vaults/
kv-x/providers/Microsoft.Authorization/roleAssignments/kv-webapp-roleAssignments'.'

What are the total minimal needed permissions and what should my az ad sp create-for-rbac statement(s) be and are there any other steps I need to do to assign role permissions?


Solution

  • To assign RBAC roles, you need to have either User Access Administrator or Owner role that includes below permission: Microsoft.Authorization/roleAssignments/write

    With Contributor role, you cannot assign RBAC roles to Azure resources. To confirm that, you can check this MS Doc.

    I tried to reproduce the same in my environment and got below results:

    I used the same command and created one service principal with Contributor role as below:

    az ad sp create-for-rbac --n infra-bicep --role contributor --scopes /subscriptions/my-subscription-guid --sdk-auth
    

    Response:

    enter image description here

    I generated one access token via Postman with below parameters:

    POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
    
    grant_type:client_credentials
    client_id: <clientID from above response>
    client_secret: <clientSecret from above response>
    scope: https://management.azure.com/.default
    

    Response:

    enter image description here

    When I used this token to assign Key Vault Secrets User role with below API call, I got same error as you like below:

    PUT https://management.azure.com/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxxx/providers/Microsoft.Authorization/roleAssignments/xxxxxxxxxxx?api-version=2022-04-01
    {
      "properties": {
        "roleDefinitionId": "/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6",
        "principalId": "456c2d5f-12e7-4448-88ba-xxxxxxxxx",
        "principalType": "ServicePrincipal"
      }
    }
    

    Response:

    enter image description here

    To resolve the error, create a service principal with either User Access Administrator or Owner role.

    In my case, I created a service principal with Owner role like below:

    az ad sp create-for-rbac --n infra-bicep-owner --role owner --scopes /subscriptions/my-subscription-guid --sdk-auth
    

    Response:

    enter image description here

    Now, I generated access token again via Postman by replacing clientId and clientSecret values like below:

    POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
    
    grant_type:client_credentials
    client_id: <clientID from above response>
    client_secret: <clientSecret from above response>
    scope: https://management.azure.com/.default
    

    Response:

    enter image description here

    When I used this token to assign Key Vault Secrets User role with below API call, I got response successfully like below:

    PUT https://management.azure.com/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxxx/providers/Microsoft.Authorization/roleAssignments/xxxxxxxxxxx?api-version=2022-04-01
    {
      "properties": {
        "roleDefinitionId": "/subscriptions/d689e7fb-47d7-4fc3-b0db-xxxxxxxxxx/providers/Microsoft.Authorization/roleDefinitions/4633458b-17de-408a-b874-0445c86b69e6",
        "principalId": "456c2d5f-12e7-4448-88ba-xxxxxxxxx",
        "principalType": "ServicePrincipal"
      }
    }
    

    Response:

    enter image description here

    UPDATE:

    Considering least privileges principle, you need to create custom RBAC role instead of assigning Owner role.

    To create custom RBAC role, follow below steps:

    Go to Azure Portal -> Subscriptions -> Your Subscription -> Access control (IAM) -> Add -> Add custom role

    enter image description here

    Fill the details with name and description, make sure to select Contributor role after choosing Clone a role like below:

    enter image description here

    Now, remove below permission from NotAction Microsoft.Authorization/roleAssignments/write

    enter image description here

    Now, add Microsoft.Authorization/roleAssignments/write permission in Action:

    enter image description here

    Now, click on Create like below:

    enter image description here

    You can create service principal with above custom role using this command:

    az ad sp create-for-rbac --n infra_bicep_custom_role --role 'Custom Contributor' --scopes /subscriptions/my-subscription-guid --sdk-auth
    

    Response:

    enter image description here