Skip to content

az ad app show with --id doesn't work without Application.Read.All permission #28293

@dvsp-iodigital

Description

@dvsp-iodigital

Describe the bug

I have been given access to a specific Azure AD application (I know both the client/application id and the object id), through a custom Entra ID role. I do not have the Application.Read.All role/permission in this AAD tenant.

In the portal, I can indeed see this app registration (I need to directly go to the right URL, using the client id).
I can also access this app registration using a custom application that accesses the MS Graph API via the Java SDK.

However, it doesn't work with the CLI:

$ az ad app show --id [CENSORED]
Insufficient privileges to complete the operation.

The problem is that the CLI supports both client id and object id, and needs to determine whether the value passed to --id is an object id or a client id. It does this in the _resolve_application function (https://github.com/Azure/azure-cli/blob/dev/src/azure-cli/azure/cli/command_modules/role/custom.py#L783):

if is_guid(identifier):
    # it is either app id or object id, let us verify
    result = client.application_list(filter="appId eq '{}'".format(identifier))
    # If not found, this looks like an object id
    return result[0][ID] if result else identifier

application_list fails of course with a permission error, since I don't have Application.Read.All.

Also all subcommands of az ad app that use this function (probably all of them) fail for the same reason.

Related command

az ad app show --id

Errors

$ az ad app show --id 00000000-0000-0000-0000-000000000000
Insufficient privileges to complete the operation.

Issue script & Debug output

DEBUG: cli.knack.cli: Command arguments: ['ad', 'app', 'show', '--id', '[CENSORED]', '--debug']
DEBUG: cli.knack.cli: init debug log:
Cannot enable color.
DEBUG: cli.knack.cli: Event: Cli.PreExecute []
DEBUG: cli.knack.cli: Event: CommandParser.OnGlobalArgumentsCreate [<function CLILogging.on_global_arguments at 0x7ffacc0153a0>, <function OutputProducer.on_global_arguments at 0x7ffacbfb5da0>, <function CLIQuery.on_global_arguments at 0x7ffacbfef880>]
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPreCommandTableCreate []
DEBUG: cli.azure.cli.core: Modules found from index for 'ad': ['azure.cli.command_modules.role']
DEBUG: cli.azure.cli.core: Loading command modules:
DEBUG: cli.azure.cli.core: Name Load Time Groups Commands
DEBUG: cli.azure.cli.core: role 0.004 17 61
DEBUG: cli.azure.cli.core: Total (1) 0.004 17 61
DEBUG: cli.azure.cli.core: These extensions are not installed and will be skipped: ['azext_ai_examples', 'azext_next']
DEBUG: cli.azure.cli.core: Loading extensions:
DEBUG: cli.azure.cli.core: Name Load Time Groups Commands Directory
DEBUG: cli.azure.cli.core: Total (0) 0.000 0 0
DEBUG: cli.azure.cli.core: Loaded 17 groups, 61 commands.
DEBUG: cli.azure.cli.core: Found a match in the command table.
DEBUG: cli.azure.cli.core: Raw command : ad app show
DEBUG: cli.azure.cli.core: Command table: ad app show
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPreCommandTableTruncate [<function AzCliLogging.init_command_file_logging at 0x7ffacb170f40>]
DEBUG: cli.azure.cli.core.azlogging: metadata file logging enabled - writing logs to '/home/user/.azure/commands/2024-02-02.12-48-34.ad_app_show.30346.log'.
INFO: az_command_data_logger: command args: ad app show --id {} --debug
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPreArgumentLoad [<function register_global_subscription_argument..add_subscription_parameter at 0x7ffacaf8d120>]
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPostArgumentLoad []
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPostCommandTableCreate [<function register_ids_argument..add_ids_arguments at 0x7ffacaf8d1c0>, <function register_cache_arguments..add_cache_arguments at 0x7ffacaf8d300>]
DEBUG: cli.knack.cli: Event: CommandInvoker.OnCommandTableLoaded []
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPreParseArgs []
DEBUG: cli.knack.cli: Event: CommandInvoker.OnPostParseArgs [<function OutputProducer.handle_output_argument at 0x7ffacbfb5e40>, <function CLIQuery.handle_query_parameter at 0x7ffacbfef920>, <function register_ids_argument..parse_ids_arguments at 0x7ffacaf8d260>]
DEBUG: cli.azure.cli.core.util: Retrieving token for resource https://graph.microsoft.com/
DEBUG: cli.azure.cli.core.auth.persistence: build_persistence: location='/home/user/.azure/msal_token_cache.json', encrypt=False
DEBUG: cli.azure.cli.core.auth.binary_cache: load: /home/user/.azure/msal_http_cache.bin
DEBUG: urllib3.util.retry: Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
DEBUG: msal.authority: openid_config = {'token_endpoint': 'https://login.microsoftonline.com/[CENSORED]/oauth2/v2.0/token', 'token_endpoint_auth_methods_supported': ['client_secret_post', 'private_key_jwt', 'client_secret_basic'], 'jwks_uri': 'https://login.microsoftonline.com/[CENSORED]/discovery/v2.0/keys', 'response_modes_supported': ['query', 'fragment', 'form_post'], 'subject_types_supported': ['pairwise'], 'id_token_signing_alg_values_supported': ['RS256'], 'response_types_supported': ['code', 'id_token', 'code id_token', 'id_token token'], 'scopes_supported': ['openid', 'profile', 'email', 'offline_access'], 'issuer': 'https://login.microsoftonline.com/[CENSORED]/v2.0', 'request_uri_parameter_supported': False, 'userinfo_endpoint': 'https://graph.microsoft.com/oidc/userinfo', 'authorization_endpoint': 'https://login.microsoftonline.com/[CENSORED]/oauth2/v2.0/authorize', 'device_authorization_endpoint': 'https://login.microsoftonline.com/[CENSORED]/oauth2/v2.0/devicecode', 'http_logout_supported': True, 'frontchannel_logout_supported': True, 'end_session_endpoint': 'https://login.microsoftonline.com/[CENSORED]/oauth2/v2.0/logout', 'claims_supported': ['sub', 'iss', 'cloud_instance_name', 'cloud_instance_host_name', 'cloud_graph_host_name', 'msgraph_host', 'aud', 'exp', 'iat', 'auth_time', 'acr', 'nonce', 'preferred_username', 'name', 'tid', 'ver', 'at_hash', 'c_hash', 'email'], 'kerberos_endpoint': 'https://login.microsoftonline.com/[CENSORED]/kerberos', 'tenant_region_scope': 'EU', 'cloud_instance_name': 'microsoftonline.com', 'cloud_graph_host_name': 'graph.windows.net', 'msgraph_host': 'graph.microsoft.com', 'rbac_url': 'https://pas.windows.net'}
DEBUG: msal.application: Broker enabled? False
DEBUG: cli.azure.cli.core.auth.msal_authentication: UserCredential.get_token: scopes=('https://graph.microsoft.com//.default',), claims=None, kwargs={}
DEBUG: msal.application: Cache hit an AT
DEBUG: msal.telemetry: Generate or reuse correlation_id: [CENSORED]
INFO: cli.azure.cli.core.util: Request URL: 'https://graph.microsoft.com/v1.0/applications?$filter=appId%20eq%20%[CENSORED]%27'
INFO: cli.azure.cli.core.util: Request method: 'GET'
INFO: cli.azure.cli.core.util: Request headers:
INFO: cli.azure.cli.core.util: 'User-Agent': 'python/3.11.5 (Linux-6.5.0-15-generic-x86_64-with-glibc2.35) AZURECLI/2.56.0 (DEB)'
INFO: cli.azure.cli.core.util: 'Accept-Encoding': 'gzip, deflate'
INFO: cli.azure.cli.core.util: 'Accept': '/'
INFO: cli.azure.cli.core.util: 'Connection': 'keep-alive'
INFO: cli.azure.cli.core.util: 'x-ms-client-request-id': 'ddcd3ba6-95ad-49ce-b2e6-da562601a77e'
INFO: cli.azure.cli.core.util: 'CommandName': 'ad app show'
INFO: cli.azure.cli.core.util: 'ParameterSetName': '--id --debug'
INFO: cli.azure.cli.core.util: 'Authorization': 'Bearer eyJ0eXAiOiJKV...'
INFO: cli.azure.cli.core.util: Request body:
INFO: cli.azure.cli.core.util: None
DEBUG: urllib3.connectionpool: Starting new HTTPS connection (1): graph.microsoft.com:443
DEBUG: urllib3.connectionpool: https://graph.microsoft.com:443 "GET /v1.0/applications?$filter=appId%20eq%20%[CENSORED]%27 HTTP/1.1" 403 None
INFO: cli.azure.cli.core.util: Response status: 403
INFO: cli.azure.cli.core.util: Response headers:
INFO: cli.azure.cli.core.util: 'Cache-Control': 'no-cache'
INFO: cli.azure.cli.core.util: 'Transfer-Encoding': 'chunked'
INFO: cli.azure.cli.core.util: 'Content-Type': 'application/json'
INFO: cli.azure.cli.core.util: 'Content-Encoding': 'gzip'
INFO: cli.azure.cli.core.util: 'Vary': 'Accept-Encoding'
INFO: cli.azure.cli.core.util: 'Strict-Transport-Security': 'max-age=31536000'
INFO: cli.azure.cli.core.util: 'request-id': '[CENSORED]'
INFO: cli.azure.cli.core.util: 'client-request-id': '[CENSORED]'
INFO: cli.azure.cli.core.util: 'x-ms-ags-diagnostic': '{"ServerInfo":{"DataCenter":"West Europe","Slice":"E","Ring":"5","ScaleUnit":"006","RoleInstance":"AM1PEPF00027E4B"}}'
INFO: cli.azure.cli.core.util: 'x-ms-resource-unit': '2'
INFO: cli.azure.cli.core.util: 'Date': 'Fri, 02 Feb 2024 11:48:34 GMT'
INFO: cli.azure.cli.core.util: Response content:
INFO: cli.azure.cli.core.util: {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-02-02T11:48:34","request-id":"[CENSORED]","client-request-id":"[CENSORED]"}}}
DEBUG: cli.azure.cli.core.azclierror: Traceback (most recent call last):
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/_msgrpah/_graph_client.py", line 52, in _send
r = send_raw_request(self._cli_ctx, method, url, resource=self._resource, uri_parameters=param,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/util.py", line 1004, in send_raw_request
raise HTTPError(reason, r)
azure.cli.core.azclierror.HTTPError: Forbidden({"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.","innerError":{"date":"2024-02-02T11:48:34","request-id":"[CENSORED]","client-request-id":"[CENSORED]"}}})

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/init.py", line 697, in _run_job
result = cmd_copy(params)
^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/init.py", line 333, in call
return self.handler(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/command_operation.py", line 363, in handler
show_exception_handler(ex)
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/arm.py", line 429, in show_exception_handler
raise ex
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/command_operation.py", line 361, in handler
return op(**command_args)
^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/custom.py", line 747, in show_application
object_id = _resolve_application(client, identifier)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/custom.py", line 791, in _resolve_application
result = client.application_list(filter="appId eq '{}'".format(identifier))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/_msgrpah/_graph_client.py", line 86, in application_list
result = self._send("GET", "/applications" + _filter_to_query(filter))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/_msgrpah/_graph_client.py", line 55, in _send
raise GraphError(ex.response.json()['error']['message'], ex.response) from ex
azure.cli.command_modules.role._msgrpah._graph_client.GraphError: Insufficient privileges to complete the operation.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/opt/az/lib/python3.11/site-packages/knack/cli.py", line 233, in invoke
cmd_result = self.invocation.execute(args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/init.py", line 663, in execute
raise ex
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/init.py", line 726, in _run_jobs_serially
results.append(self._run_job(expanded_arg, cmd_copy))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/core/commands/init.py", line 718, in _run_job
return cmd_copy.exception_handler(ex)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/az/lib/python3.11/site-packages/azure/cli/command_modules/role/commands.py", line 50, in graph_err_handler
raise CLIError(ex)
knack.util.CLIError: Insufficient privileges to complete the operation.

ERROR: cli.azure.cli.core.azclierror: Insufficient privileges to complete the operation.
ERROR: az_command_data_logger: Insufficient privileges to complete the operation.
DEBUG: cli.knack.cli: Event: Cli.PostExecute [<function AzCliLogging.deinit_cmd_metadata_logging at 0x7ffacb1711c0>]
INFO: az_command_data_logger: exit code: 1
INFO: cli.main: Command ran in 0.610 seconds (init: 0.145, invoke: 0.465)
INFO: telemetry.main: Begin splitting cli events and extra events, total events: 1
INFO: telemetry.client: Accumulated 0 events. Flush the clients.
INFO: telemetry.main: Finish splitting cli events and extra events, cli events: 1
INFO: telemetry.save: Save telemetry record of length 3529 in cache
INFO: telemetry.main: Begin creating telemetry upload process.
INFO: telemetry.process: Creating upload process: "/opt/az/bin/python3 /opt/az/lib/python3.11/site-packages/azure/cli/telemetry/init.py /home/user/.azure"
INFO: telemetry.process: Return from creating process
INFO: telemetry.main: Finish creating telemetry upload process.

Expected behavior

  • That all az ad app commands work when I pass the object id (not client id), without having to have the Application.Read.All permission.
  • This is a common situation for us, and I imagine for other organizations too: only a few limited admins have access to all applications, and access is given to applications only on an as-needed base (principle of least privilege).
  • This also works in the portal.

Suggestion: first check if it's an object id, using something like:

GET /applications/{identifier}

and only if that fails, try with:

GET /applications(appId='{identifier}')

Environment Summary

$ az --version
azure-cli 2.56.0

core 2.56.0
telemetry 1.1.0

Extensions:
account 0.2.5
front-door 1.0.17

Dependencies:
msal 1.24.0b2
azure-mgmt-resource 23.1.0b2

Python location '/opt/az/bin/python3'
Extensions directory '/home/dvsp/.azure/cliextensions'

Python (Linux) 3.11.5 (main, Jan 8 2024, 09:08:13) [GCC 11.4.0]

Legal docs and information: aka.ms/AzureCliLegal

Your CLI is up-to-date.

Additional context

No response

Metadata

Metadata

Assignees

Labels

AADAuto-AssignAuto assign by botAzure CLI TeamThe command of the issue is owned by Azure CLI teamGraphaz adbugThis issue requires a change to an existing behavior in the product in order to be resolved.customer-reportedIssues that are reported by GitHub users external to the Azure organization.potential-pruningquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions