Solvedazure cli az ad app permission grant not working or usable as expected

Describe the bug
"az ad app permission grant" only seems to grant a single scope. If I call it successive times, the existing scope is overwritten. This behaviour is not clearly documented, nor is the way to grant. multiple scopes.

"az ad app permission admin-consent" appears to be non-functional. How can admin consent be granted without three key pieces of information, AppID, APIID, and Scope? What is this doing? How can a single scope be granted at the application level?

I would also consider it a bug that "az ad app permission grant" cannot be used to grant application type scopes.

To Reproduce
Try to execute the above commands. "az ad app permission admin-consent" is not documented in any way that makes sense. "az ad app permission grant" seems to work, but successive calls over-write your work.

Expected behavior
There should be a single command that allows you to grant individual (or comma separated lists) of scopes for an API to an app. That same command should have a flag for Delegated vs Application Type. It should not overwrite itself. Worst case, if there have to be two commands, the one used to grant admin-consent to the application type should allow appropriate parameters.

Documentation of these calls should be clear and concise.

Environment summary
Windows 10. Installed via downloaded MSI for x64. cmd.exe shell.

C:\Program Files\Microsoft SDKs\Azure.NET SDK\v2.9\bin>az --version
azure-cli 2.0.81

command-modules-nspkg 2.0.3
core 2.0.81
nspkg 3.0.4
telemetry 1.0.4

Python location 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\dpomerantz.azure\cliextensions'

Python (Windows) 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 02:47:15) [MSC v.1900 32 bit (Intel)]

21 Answers

✔️Accepted Answer

az ad app permission admin-consent is the old way of granting all Application Permissions and Delegated Permissions to an app at the same time. It calls an internal API:

url = 'https://main.iam.ad.ext.azure.com/api/RegisteredApplications/{}/Consent?onBehalfOfAll=true'.format(

It can only be called by a user, not a service principal.
It fails in Cloud Shell, because main.iam.ad.ext.azure.com is an endpoint not supported by Cloud Shell.
We will deprecate it in the future.

For example, we can call it with app's Application ID:

az ad app permission admin-consent --id 46eb4122-bd2b-4f54-af7b-6d79b46ee31a

Before:

After:

Grant Delegated Permissions

To grant Delegated Permissions, we recommend using az ad app permission grant. If multiple scopes are needed, separate them with spaces and surround the scopes with quotes: "a b". For example, to grant MS Graph (whose Application ID is 00000003-0000-0000-c000-000000000000) Delegated Permission to my app (Application ID 46eb4122-bd2b-4f54-af7b-6d79b46ee31a):

# Line breaks for legibility only, same for following commands
az ad app permission grant --id 46eb4122-bd2b-4f54-af7b-6d79b46ee31a 
                           --api 00000003-0000-0000-c000-000000000000
                           --scope "Directory.Read.All Directory.ReadWrite.All"

Grant Application Permissions

To grant Application Permissions, we can use any of these 2 APIs:

  • {principalId}/appRoleAssignments

    # URL contains principalId
    az rest --method POST 
            --uri https://graph.microsoft.com/v1.0/servicePrincipals/8aaa6158-7450-4407-ba08-61377f23d05f/appRoleAssignments
            --body '{
              "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
              "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4",
              "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7"
            }' 
  • {resourceId}/appRoleAssignedTo

    # URL contains resourceId
    az rest --method POST 
            --uri https://graph.microsoft.com/v1.0/servicePrincipals/a3efc889-f1b7-4532-9e01-91e32d1039f4/appRoleAssignedTo
            --body '{
              "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
              "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4",
              "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7"
            }' 

principalId (8aaa6158-7450-4407-ba08-61377f23d05f) is the objectId of the assigned client service principal. Service principal is also called Managed application in local directory or Enterprise Application.

You may get it from Azure Portal:

1

2

Or query principalId with Application ID:

> az ad sp show --id 46eb4122-bd2b-4f54-af7b-6d79b46ee31a --query "objectId" --output tsv
8aaa6158-7450-4407-ba08-61377f23d05f

resourceId (a3efc889-f1b7-4532-9e01-91e32d1039f4) is the objectId of the resource service principal. In this case it is for MS Graph's service principal. It varies in different tenants (directories). Retrieve it with MS Graph's Application ID:

$ az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "objectId" --output tsv
a3efc889-f1b7-4532-9e01-91e32d1039f4

appRoleId (19dbc75e-c2e2-444c-a770-ec69d8559fc7) is the ID of the permission. In this case, it is for Directory.ReadWrite.All. Retrieve it with MS Graph's Application ID:

> az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?value=='Directory.ReadWrite.All']"
[
  {
    "allowedMemberTypes": [
      "Application"
    ],
    "description": "Allows the app to read and write data in your organization's directory, such as users, and groups, without a signed-in user.  Does not allow user or group deletion.",
    "displayName": "Read and write directory data",
    "id": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
    "isEnabled": true,
    "value": "Directory.ReadWrite.All"
  }
]

You may also use F12 Developer Tools of the browser to capture network trace to check related ID conversions. (Quite complicated I admit.)

More Issues: