Azure / azure-cli

Azure Command-Line Interface
MIT License
3.97k stars 2.95k forks source link

`az role assignment list`: Replace `--all` with `--at-scope` #14302

Open jongio opened 4 years ago

jongio commented 4 years ago

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. image

The portal does not show roles image

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

image

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')

image

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

  1. Create a new SP az ad sp create-for-rbac --skip-assignment
  2. 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
  3. 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

jiasli commented 4 years ago

Possibly related to https://github.com/Azure/azure-cli/pull/13762. @qianwens, could you help take a look as well?

qianwens commented 4 years ago

@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.

jongio commented 4 years ago

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

jiasli commented 4 years ago

@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

Jelledb commented 3 years ago

Just started messing around with the Azure CLI for the first time and I noticed this weirdness;

I'm happy the --all fixes it, but it's not intuitive at all...

jiasli commented 1 year ago

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.

jiasli commented 1 month ago

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,

  1. When --all is provided, --resource-group or --scope is disallowed. scope is set to None and defaults to the subscription: https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L221-L224 atScope() is not used: https://github.com/Azure/azure-cli/blob/38eaebb6936a32be13e2c4afba8e600ce9c91513/src/azure-cli/azure/cli/command_modules/role/custom.py#L550-L562

  2. When --resource-group or --scope is 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.

jiasli commented 1 month ago

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.