-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
az ad and --subscription
--subscription(_subscription) is explicitly ignored for az ad commands as az ad commands are tenant-level. They have nothing to do with subscription.
| c.ignore('_subscription') # hide global subscription param |
However, since subscription ID is the primary key of Azure CLI's account, this gives --subscription another functionality - temporarily switching login context.
send_raw_request only switches subscription when the subscription ID is in an ARM URL:
| token_info, _, _ = profile.get_raw_token(resource, subscription=token_subscription) |
As Graph API's URL is like https://graph.microsoft.com/, send_raw_request uses the current login context:
| logger.debug('Retrieving token for resource %s', resource) |
So --subscription doesn't take effect in:
az rest -u "https://graph.microsoft.com/v1.0/me" --subscription xxx
Problem in doc
The in-tool help says az ad commands don't support --subscription
> az ad app show -h
...
Global Arguments
--debug : Increase logging verbosity to show all debug logs.
--help -h : Show this help message and exit.
--only-show-errors : Only show errors, suppressing warnings.
--output -o : Output format. Allowed values: json, jsonc, none, table, tsv, yaml, yamlc.
Default: json.
--query : JMESPath query string. See http://jmespath.org/ for more information and
examples.
--verbose : Increase logging verbosity. Use --debug for full debug logs.
but the online doc says they do, which is wrong (#21806, #23412): https://learn.microsoft.com/en-us/cli/azure/ad/app?view=azure-cli-latest#az-ad-app-show
Problem in az keyvault create
Consider sub1 is the current subscription+login context while sub2 is another one, and az keyvault create is run with --subscription sub2
| subscription | sub1 (current) | sub2 |
|---|---|---|
| tenant | tenant1 | tenant2 |
| user | user1 | user2 |
Creating keyvault
As subscription can be read from cmd.cli_ctx.data.get['subscription_id']:
| subscription = profile.get_subscription(subscription=cmd.cli_ctx.data.get('subscription_id', None)) |
The keyvault is created with the identity of the --subscription-specified account - (sub2, tenant2, user2).
_get_current_user_object_id
When granting permissions for the keyvault, az keyvault create first calls _get_current_user_object_id
| object_id = _get_current_user_object_id(graph_client) |
_get_current_user_object_id internally calls the /me API on Microsoft Graph with the current account's identity, so it grants permission to the identity of the current account - (N/A, tenant1, user1). This causes a mismatch.
_get_object_id
If _get_current_user_object_id fails, it calls _get_object_id:
| object_id = _get_object_id(graph_client, subscription=subscription) |
which resolves the identity of the --subscription-specified account, but in the current tenant - (N/A, tenant1, user2).
Solution
The best solution is to implement a 3-layer structure (#15005).
More information
- Creating role assignment must require all assignee, role definition and scope to be specified explicitly #24753 (comment)
- [Feature Request] Show object ID of the signed in account #22776
- [Feature Request] Drop multi-account login #17607
- {Role} Fix #15196:
az role assignment list --subscriptionshows emptyprincipalName#15532