AZ CLI - Assign User Role
Tags: azure, cli, aad
Published: 2021-09-08 11:03:45

This is a series of quick posts, tips and tricks when working with the Azure CLI. 

## Assigning Roles for RBAC
To take advantage of the built in roles and fine grained RBAC support many of the resources in Azure support, you should assign Roles to Security Principals. 

To do so, the principal that will be _performing_ the assignment must have the relevant permissions. You'll have this if you are an Administrator or Owner of an Azure subscription, but if not you'll explicitly need the permissions to read & write by granting the *roleAssignments*, which looks like so

```
"permissions": [
    {
        "actions": [
            "Microsoft.Authorization/*/read",
            "Microsoft.Authorization/roleAssignments/read",
            "Microsoft.Authorization/roleAssignments/write",
            "Microsoft.Authorization/roleAssignments/delete"
        ],
        "notActions": [],
        "dataActions": [],
        "notDataActions": []
    }
]
```
OK, so you've authenticated as a principal that has the correct permissions and you want to assign a role to another principal - documentation for this is available at [the az cli role page](https://docs.microsoft.com/en-us/cli/azure/role/assignment?view=azure-cli-latest)

However, I noticed a little quirk when trying to assign a role to a *user principal*, where the assignee here is the object id of a user principal from AAD.

```
az role assignment create 
--assignee 00000000-0000-0000-0000-000000000000 
--role "Storage Account Key Operator Service Role" 
--scope $id
```

ForbiddenError: Operation failed with status: 'Forbidden'. Details: 403 Client Error: Forbidden for url: https://graph.windows.net/{guid}/getObjectsByObjectIds?api-version=1.6

What's going on here? I have permissions to assign roles, this command is working for me for other principal types, but for *user principals* I'm receiving this error. 

You can always pass the --debug flag to your az cli to see what's going on in a bit more depth, for this command we can see

msrest.http_logger : {"odata.error":{"code":"Authorization_RequestDenied","message":{"lang":"en","value":"Insufficient privileges to complete the operation."},"requestId":"{guid}","date":"2021-09-08T08:50:40"}}
msrest.exceptions : Operation failed with status: 'Forbidden'. Details: 403 Client Error: Forbidden for url: https://graph.windows.net/{guid}/getObjectsByObjectIds?api-version=1.6

What's happening is the command is trying to perform a user account lookup which means it requires additional privileges to do so, specifically 'Read directory data' permission with Azure AD Graph API.

![Read Directory Data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df6fphkgglhu80s1q5m9.png)
 
You _could_ grant the account the permission and that would solve, but I'd rather keep to least privilege and not do that if possible. Luckily, the command provides another way to assign the role, by passing parameters in a slightly different form

```
az role assignment create 
--assignee-object-id "guid" 
--assignee-principal-type "User" 
.--role "The Role Name" 
--scope "the/full/resource/id" 
```

By using the command in this format, you won't perform a call to the graph API and therefore don't need 'Read directory data' permission - nice!