Role assigned to scope not returned unless scope is specified
Describe the bug
When I assign a role to an SP at a given scope that role is not returned with the az role assignment list command.
Doesn't work in both CLI and Portal, works in REST API
Both
az role assignment list --assignee [objectId]
az role assignment list --assignee [appId]
Do not return roles that are assigned.

The portal does not show roles

But, if I add a scope, roles are returned:

The REST API does not require scope. Roles are returned without scope.
https://management.azure.com/subscriptions/{{subscriptionId}}/providers/Microsoft.Authorization/roleAssignments?api-version=2020-04-01-preview&$filter=assignedTo('aae06f9f-3c90-442b-bdc4-f688818132c6')

If I create a new SP and assign it the Tag Contributor role, then that roles is returned when using the CLI without scope.
To Reproduce
- Create a new SP
az ad sp create-for-rbac --skip-assignment - Assign a role with scope
az role assignment create --assignee 32c6eeab-6338-4bdb-b21f-69836b2d99c4 --role "Tag Contributor" --scope /subscriptions/25fd0362-aa79-488b-b37b-d6e892009fdf/resourceGroups/aztagsync1 - Query for roles
az role assignment list --assignee 32c6eeab-6338-4bdb-b21f-69836b2d99c4
Zero results are returned.
Expected behavior
Roles are returned without specifying a scope.
This is also true for the Azure portal, but I'm not sure where to report that bug. If you know, Please let me know.
Environment summary
azure-cli 2.8.0 WSL2
Additional context
I'm Microsoft, so ping me on Teams to diagnose further.
azsdke2e
Possibly related to https://github.com/Azure/azure-cli/pull/13762. @qianwens, could you help take a look as well?
@jongio @jiasli , this behavior is by design that CLI will build a subscription level scope if there is no scope specified https://github.com/Azure/azure-cli/blob/dev/src/azure-cli/azure/cli/command_modules/role/custom.py#L181 You need to specify --all to list all the assignments under the current subscription. I agree that this behavior is not intuitive for the customer, but fix this issue may cause a breaking change.
I have confirmed that using the --all switch returns the role:
Do we have tests in place to see if this will cause a breaking change to make --all the default?
I personally, an avid CLI user and my customer, a novice CLI user, could not figure this out. I strongly suggest that we make --all the default to avoid these types of situations. In fact, I had to engage multiple on-call support teams, which involved many hours of their time, plus my time, plus the customer uncertainty of not knowing why the Tag update was working without (what we thought) was no roles assigned.
If we have tests in place, then we can try to make --all the default and see what breaks and then determine if it is worth it to make the change.
Thanks, Jon
@qianwens, Nice analysis. In other words, by default CLI only lists assignments at the subscription level. With --all specified, all assignments at sub-resource levels are also listed.
I am able to reproduce with
> az role assignment create --assignee baf0218a-2f6b-44b0-9e3e-9118f8ad5979 --role "Tag Contributor" --scope /subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/resourceGroups/rg1
> az role assignment list --assignee baf0218a-2f6b-44b0-9e3e-9118f8ad5979
[]
> az role assignment list --assignee baf0218a-2f6b-44b0-9e3e-9118f8ad5979 --all
[
{
"canDelegate": null,
"id": "/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/resourceGroups/rg1/providers/Microsoft.Authorization/roleAssignments/142298ff-27ac-41c5-868d-96accdb08801",
"name": "142298ff-27ac-41c5-868d-96accdb08801",
"principalId": "c726656d-b23f-4f6f-b01e-9db96e3f0c4f",
"principalName": "http://azure-cli-2020-07-20-04-29-35",
"principalType": "ServicePrincipal",
"resourceGroup": "rg1",
"roleDefinitionId": "/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/providers/Microsoft.Authorization/roleDefinitions/4a9ae827-6dc8-4573-8ac7-8239d42aa03f",
"roleDefinitionName": "Tag Contributor",
"scope": "/subscriptions/0b1f6471-1bf0-4dda-aec3-cb9272f09590/resourceGroups/rg1",
"type": "Microsoft.Authorization/roleAssignments"
}
]
This is also indicated in the help message:
> az role assignment list -h
Command
az role assignment list : List role assignments.
By default, only assignments scoped to subscription will be displayed. To view assignments
scoped by resource or group, use `--all`.
Arguments
--all : Show all assignments under the current subscription.
The lines responsible for this behavior are at
https://github.com/Azure/azure-cli/blob/4c28536a6db8c8e43b7182d0aaf202ac2b4ab777/src/azure-cli/azure/cli/command_modules/role/custom.py#L176-L182
https://github.com/Azure/azure-cli/blob/4c28536a6db8c8e43b7182d0aaf202ac2b4ab777/src/azure-cli/azure/cli/command_modules/role/custom.py#L511
However, I do think what @jongio suggests makes sense. Let's do some evaluation internally. + PM @achandmsft
Just started messing around with the Azure CLI for the first time and I noticed this weirdness;
- When listing roles using
az role assignment list --subscription xyzit gives me only the directly assigned roles, guess that makes sense - Azure docs tell me: you should use
--include-inheritedto view inherited assignments, okay sounds cool. - I run the query with
--include-inheritedand I see direct assignment and root-inherited assignments, but not assignments inherited via Management Groups ??? This behavior is very odd.
I'm happy the --all fixes it, but it's not intuitive at all...
az role assignment list by default only lists role assignments exactly at the subscription level.
The original issue @jongio faces is that resource-group-level role assignments (below subscription-level, such as on /subscriptions/25fd0362-aa79-488b-b37b-d6e892009fdf/resourceGroups/aztagsync1) are not listed by az role assignment list.
@Jelledb, your issue is that management-group-level role assignments (above subscription-level) are not listed by az role assignment list --include-inherited. Let's track this in https://github.com/Azure/azure-cli/issues/25078.
An excerpt from email: Role assigned to scope not returned unless scope is specified
The problem is that CLI doesn’t have a nice mapping of $filter=atScope(), which limits the assignment to the specified scope. See https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-list-rest
In CLI's implementation,
-
When
--allis provided,--resource-groupor--scopeis disallowed.scopeis set toNoneand defaults to the subscription: https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L221-L224atScope()is not used: https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L550-L562 -
When
--resource-groupor--scopeis provided (without--all),atScope()is forced: https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L550-L551
In other words, even though --all can be used as the default and to list all sub-scope assignments under the subscription, it is not possible to list sub-scope assignments under a user-specified --scope, such as a resource group.
Proposal: Replace --all with the opposite, more general --at-scope, so that CLI is elegantly consistent with the REST API and covers the full functionality of the REST API.
Another issue: Even though principalId and atScope() are mutually exclusive, principalId and scope are not. Forcefully binding atScope() to scope also forbids using principalId with scope.
To work around this, CLI does a client-side filtering:
https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L576-L579
But the issue itself is caused by the bad design of --all and can be avoided from the very beginning.