Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

az ad app permission grant not working or usable as expected #12137

Closed
dmprantz opened this issue Feb 11, 2020 · 28 comments
Closed

az ad app permission grant not working or usable as expected #12137

dmprantz opened this issue Feb 11, 2020 · 28 comments
Assignees
Labels
Milestone

Comments

@dmprantz
Copy link

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

@arrownj
Copy link
Contributor

arrownj commented Feb 12, 2020

Hi @jiasli , could you please help take a look at this ?

@yonzhan yonzhan added this to the S166 milestone Feb 12, 2020
@yonzhan
Copy link
Collaborator

yonzhan commented Feb 12, 2020

add to S166.

@yonzhan yonzhan modified the milestones: S166, S167 Mar 7, 2020
@dmprantz
Copy link
Author

dmprantz commented Mar 9, 2020

This was pushed to a future release. How many times is it going to get pushed before being addressed and resolved. Is any one able to comment on a commitment that this will be resolved with a definitive timeline?

@jiasli jiasli modified the milestones: S167, Backlog Mar 9, 2020
@jiasli
Copy link
Member

jiasli commented Mar 9, 2020

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

@dmprantz
Copy link
Author

dmprantz commented Mar 9, 2020

Thanks for all of the detailed information! I'll take some time and digest this, and come back if I have any further questions on this. I understand a bit more on the delays though.

@jiasli
Copy link
Member

jiasli commented Mar 9, 2020

Hi @dmprantz , thanks a lot for your understanding. We have been working tightly with AAD team on this feature. Don't hesitate to let us know if there are any concerns.

@jiasli
Copy link
Member

jiasli commented Mar 9, 2020

For the granting app (or service principal, which you use to log in and grant permissions to another service principal),

  • Directory.ReadWrite.All is needed for granting Delegated Permissions
  • AppRoleAssignment.ReadWrite.All is needed for granting Application Permissions

⚠ Keep in mind that AppRoleAssignment.ReadWrite.All is extremely privileged, as it allows granting any app-only permission, including RoleManagement.ReadWrite.Directory, which can then be used to give anyone (or any app) even higher privileges up to and including Company Administrator (i.e. Global Admin).

If you use az ad command, make sure the permission is given under Azure Active Directory Graph, since az ad internally uses AD Graph API. If you use az rest --uri https://graph.microsoft.com/, the permission should be given under Microsoft Graph.

Reference: https://winsmarts.com/how-to-grant-admin-consent-to-an-api-programmatically-e32f4a100e9d

@fume
Copy link
Member

fume commented Apr 10, 2020

Hi @jiasli ,using the az ad app permission grant command to grand Delegated Permission is giving us a 404 NotFound error (like microsoftgraph/microsoft-graph-docs#12797, but we are NOT using a Service Principal). In our case the Delegated Permission is from Microsoft Graph (Directory.ReadWrite.All). Can you please clarify HOW to grant Delegated Permissions programmatically?

@fume
Copy link
Member

fume commented Apr 10, 2020

I found a solution.
BEFORE invoking the az ad app permission grant, the Service Principal for your App Registration MUST exists (that's why you get the 404 NotFound!). So, invoking the az ad sp create --id <yourAppId> before the az ad app permission grant will fix everything.

This is really confusing and undocumented.

@jiasli
Copy link
Member

jiasli commented Apr 11, 2020

@fume, glad to know it is solved. You may use --debug to check which request failed and fix it accordingly. BTW, We will track MS Graph related issues at microsoftgraph/docs-issue-transfer#2413.

@jiasli
Copy link
Member

jiasli commented May 25, 2020

Update

Service Principal API of Microsoft Graph is now GA. I have updated my answer #12137 (comment) to reflect the most recent changes.

The GA APIs have some changes from this blog I provided earlier for granting Application Permissions.

In short

  1. The subject of appRoleAssignments and appRoleAssignedTo are interchanged.
  2. Only follow the official document and don't use the unsupported combinations.

TL;DR

We can consider the assignment as a relationship/binding between 2 service principals. There are 4 ways to create an assignment.

In the blog, the APIs are

  • {resourceId}/appRoleAssignments
  • {principalId}/appRoleAssignedTo

Now the official APIs are

We can draw a diagram like this:

Id API Correctness
{principalId} appRoleAssignments (1) 🟢 Correct
(2) 🟡 Undocumented, unsupported
(3) 🟡 Undocumented, unsupported
{resourceId} appRoleAssignedTo (4) 🟢 Correct

Ideally the same URL can be used for 4 operations:

  1. POST to create
  2. GET to list
  3. GET to show, by appending the id of the assignment
  4. DELETE to delete, by appending the id of the assignment

To use the above operations with URLs:

  • (1)(4): {principalId}/appRoleAssignments and {resourceId}/appRoleAssignedTo are the only official ways. All 4 operations are supported.
  • (2)(3): {resourceId}/appRoleAssignments and {principalId}/appRoleAssignedTo are undocumented and unsupported. They only work for an individual assignment (operation 1, 3, 4), but not GET to list (operation 2).

If we enumerate all combinations:

POST:

  • 🟢 POST {principalId}/appRoleAssignments
  • 🟢 POST {resourceId}/appRoleAssignedTo
  • 🟡 POST {principalId}/appRoleAssignedTo (Unsupported)
  • 🟡 POST {resourceId}/appRoleAssignments (Unsupported)

GET to list:

  • 🟢 GET {principalId}/appRoleAssignments
  • 🟢 GET {resourceId}/appRoleAssignedTo
  • 🔴 GET {principalId}/appRoleAssignedTo (Not return the desired result)
  • 🔴 GET {resourceId}/appRoleAssignments (Not return the desired result)

GET to show:

  • 🟢 GET {principalId}/appRoleAssignments/id
  • 🟢 GET {resourceId}/appRoleAssignedTo/id
  • 🟡 GET {principalId}/appRoleAssignedTo/id (Unsupported)
  • 🟡 GET {resourceId}/appRoleAssignments/id (Unsupported)

DELETE:

  • 🟢 DELETE {principalId}/appRoleAssignments/id
  • 🟢 DELETE {resourceId}/appRoleAssignedTo/id
  • 🟡 DELETE {principalId}/appRoleAssignedTo/id (Unsupported)
  • 🟡 DELETE {resourceId}/appRoleAssignments/id (Unsupported)

Examples

Using {principalId}/appRoleAssignments (1)

# POST {principalId}/appRoleAssignments (1)
$ az rest --method POST --url 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"}'
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('8aaa6158-7450-4407-ba08-61377f23d05f')/appRoleAssignments/$entity",
  "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
  "createdDateTime": "2020-05-26T08:12:09.7096052Z",
  "deletedDateTime": null,
  "id": "WGGqilB0B0S6CGE3fyPQX_E14wqwY2lBhDlpweb26uo",
  "principalDisplayName": "myapp",
  "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
  "principalType": "ServicePrincipal",
  "resourceDisplayName": "Microsoft Graph",
  "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
}

# GET {principalId}/appRoleAssignments (1) to list
$ az rest --method GET --url https://graph.microsoft.com/v1.0/servicePrincipals/8aaa6158-7450-4407-ba08-61377f23d05f/appRoleAssignments
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('8aaa6158-7450-4407-ba08-61377f23d05f')/appRoleAssignments",
  "value": [
    {
      "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
      "createdDateTime": "2020-05-26T08:12:09.7096052Z",
      "deletedDateTime": null,
      "id": "WGGqilB0B0S6CGE3fyPQX_E14wqwY2lBhDlpweb26uo",
      "principalDisplayName": "myapp",
      "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
      "principalType": "ServicePrincipal",
      "resourceDisplayName": "Microsoft Graph",
      "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
    }
  ]
}

# GET {resourceId}/appRoleAssignments (3) to list doesn't return the desired assignment
$ az rest --method GET --url https://graph.microsoft.com/v1.0/servicePrincipals/a3efc889-f1b7-4532-9e01-91e32d1039f4/appRoleAssignments
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('a3efc889-f1b7-4532-9e01-91e32d1039f4')/appRoleAssignments",
  "value": []
}

# GET {resourceId}/appRoleAssignments/{id} (3) to show is unsupported, but works
$ az rest --method GET --url https://graph.microsoft.com/v1.0/servicePrincipals/a3efc889-f1b7-4532-9e01-91e32d1039f4/appRoleAssignments/WGGqilB0B0S6CGE3fyPQX_E14wqwY2lBhDlpweb26uo
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('a3efc889-f1b7-4532-9e01-91e32d1039f4')/appRoleAssignments/$entity",
  "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
  "createdDateTime": "2020-05-26T08:12:09.7096052Z",
  "deletedDateTime": null,
  "id": "WGGqilB0B0S6CGE3fyPQX_E14wqwY2lBhDlpweb26uo",
  "principalDisplayName": "myapp",
  "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
  "principalType": "ServicePrincipal",
  "resourceDisplayName": "Microsoft Graph",
  "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
}

# DELETE {principalId}/appRoleAssignments/{id} (1)
$ az rest --method DELETE --url https://graph.microsoft.com/v1.0/servicePrincipals/8aaa6158-7450-4407-ba08-61377f23d05f/appRoleAssignments/WGGqilB0B0S6CGE3fyPQX0ka7r14XhdLpH3TFDkPj6I

Using {resourceId}/appRoleAssignedTo (4)

# POST {resourceId}/appRoleAssignments (4) 
$ az rest --method POST --url 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"}'
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('a3efc889-f1b7-4532-9e01-91e32d1039f4')/appRoleAssignedTo/$entity",
  "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
  "createdDateTime": "2020-05-26T08:13:58.8505897Z",
  "deletedDateTime": null,
  "id": "WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y",
  "principalDisplayName": "myapp",
  "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
  "principalType": "ServicePrincipal",
  "resourceDisplayName": "Microsoft Graph",
  "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
}

# We don't list all appRoleAssignedTo items because the list is too large

# GET {resourceId}/appRoleAssignments/{id} (4) to show
$ az rest --method GET --url https://graph.microsoft.com/v1.0/servicePrincipals/a3efc889-f1b7-4532-9e01-91e32d1039f4/appRoleAssignedTo/WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('a3efc889-f1b7-4532-9e01-91e32d1039f4')/appRoleAssignedTo/$entity",
  "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
  "createdDateTime": "2020-05-26T08:13:58.8505897Z",
  "deletedDateTime": null,
  "id": "WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y",
  "principalDisplayName": "myapp",
  "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
  "principalType": "ServicePrincipal",
  "resourceDisplayName": "Microsoft Graph",
  "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
}

# GET {principalId}/appRoleAssignedTo/{id} (2) to show is unsupported, but works
az rest --method GET --url https://graph.microsoft.com/v1.0/servicePrincipals/8aaa6158-7450-4407-ba08-61377f23d05f/appRoleAssignedTo/WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('8aaa6158-7450-4407-ba08-61377f23d05f')/appRoleAssignedTo/$entity",
  "appRoleId": "19dbc75e-c2e2-444c-a770-ec69d8559fc7",
  "createdDateTime": "2020-05-26T08:13:58.8505897Z",
  "deletedDateTime": null,
  "id": "WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y",
  "principalDisplayName": "myapp",
  "principalId": "8aaa6158-7450-4407-ba08-61377f23d05f",
  "principalType": "ServicePrincipal",
  "resourceDisplayName": "Microsoft Graph",
  "resourceId": "a3efc889-f1b7-4532-9e01-91e32d1039f4"
}

# DELETE {resourceId}/appRoleAssignments/{id} (4) 
$ az rest --method DELETE --url https://graph.microsoft.com/v1.0/servicePrincipals/a3efc889-f1b7-4532-9e01-91e32d1039f4/appRoleAssignedTo/WGGqilB0B0S6CGE3fyPQX1Gp1oD6w_JCqCeCp4QUT0Y

However I still find the doc titles of the API appRoleAssignments and appRoleAssignedTo confusing. Will track at issue https://github.com/microsoftgraph/microsoft-graph-docs-contrib/issues/5197.

@estemendoza
Copy link

@jiasli Thanks for the provided info. I am having issues when running the az rest command to grant permissions.

I tried this command last year and it was working fine, i didn't have to use it these last few months but now I am getting the following error:

"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the operation.

Any idea on what this could be?

My user is Owner and trying to run this on the PowerShell console

@jiasli
Copy link
Member

jiasli commented Dec 3, 2021

@estemendoza
Copy link

Hi @jiasli Thanks for the links, but I am still having issues. I tried to execute it using PowerShell on the Portal and got the following error:

> az rest --method POST --uri https://graph.microsoft.com/v1.0/servicePrincipals/875f4d30-XXXX-XXXX-XXXX-XXXXXXXX/appRoleAssignedTo --body '{"principalId":"0a699965-XXXX-XXXX-XXXX-XXXXXXXXXXX","resourceId":"875f4d30-XXXX-XXXX-XXXX-XXXXXXXX","appRoleId":"5778995a-XXX-XXX-XXX-XXXXXXXXXXX"}' --headers "Content-Type=application/json"
Bad Request({"error":{"code":"BadRequest","message":"Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.","innerError":{"date":"2021-12-03T15:38:15","request-id":"398f4a1d-8b28-4233-abbb-360ebee96f33","client-request-id":"398f4a1d-8b28-4233-abbb-XXXXXXXX"}}})

What am I doing wrong on the command? Thanks in advance

@estemendoza
Copy link

@jiasli Nevermind, I needed to run the script as an Administrator, thanks for the help.

@jiasli
Copy link
Member

jiasli commented Dec 6, 2021

@estemendoza, passing JSON in PowerShell requires additional quoting rules. Please see https://github.com/Azure/azure-cli/blob/dev/doc/quoting-issues-with-powershell.md.

Azure CLI doesn't need Administrator permission to run.

@MartinHatchUK
Copy link

@jiasli
Can I please have some clarification on this as I'm facing the exact issues but cannot get this working using the examples you provided

I'm logged into Azure CLI in a Windows Terminal (PowerShell) using a Service Principal.

I'm trying to grant admin consent for an Application Scoped API permission

Executing the following
az rest --method POST --uri https://graph.microsoft.com/v1.0/servicePrincipals/9fd6352e-9cba-4e76-9fff-74c41c0ec4fc/appRoleAssignments --body '{"principalId": "9fd6352e-9cba-4e76-9fff-74c41c0ec4fc", "resourceId": "00000003-0000-0ff1-ce00-000000000000", "appRoleId": "678536fe-1083-478a-9c59-b99265e6b0d3" }' --headers "content-type: application/json"

I get an error message:

The command failed with an unexpected error. Here is the traceback:
not enough values to unpack (expected 2, got 1)
Traceback (most recent call last):
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/util.py", line 575, in shell_safe_json_parse
  File "json\__init__.py", line 359, in loads
  File "json\decoder.py", line 337, in decode
  File "json\decoder.py", line 355, in raw_decode
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

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

Traceback (most recent call last):
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/util.py", line 883, in send_raw_request
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/util.py", line 601, in shell_safe_json_parse
azure.cli.core.azclierror.InvalidArgumentValueError: Failed to parse string as JSON:
content-type: application/json
Error detail: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\knack/cli.py", line 233, in invoke
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 663, in execute
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 726, in _run_jobs_serially
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 697, in _run_job
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/__init__.py", line 333, in __call__
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/commands/command_operation.py", line 121, in handler
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/command_modules/util/custom.py", line 24, in rest_call
  File "D:\a\_work\1\s\build_scripts\windows\artifacts\cli\Lib\site-packages\azure/cli/core/util.py", line 886, in send_raw_request
ValueError: not enough values to unpack (expected 2, got 1)

@Yvand
Copy link

Yvand commented Mar 29, 2023

@MartinHatchL365 seems related to the value of --headers, and I think you can remove that parameter completely: I do not set it in my working scenario.

@MartinHatchUK
Copy link

MartinHatchUK commented Mar 29, 2023

@Yvand

If I don't use that then I get the following error message

Bad Request({"error":{"code":"BadRequest","message":"Write requests (excluding DELETE) must contain the Content-Type header declaration.","innerError":{"date":"2023-03-29T11:41:10","request-id":"9207c760-0ffc-45f9-9663-f9a88adf9a7a","client-request-id":"9207c760-0ffc-45f9-9663-f9a88adf9a7a"}}})

@MartinHatchUK
Copy link

@Yvand could it be that the URL is incorrect?

According to the official documentation on MS Graph, the correct endpoint is /appRoleAssignedTo and not /appRoleAssignments which is in the example above

Ref:
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/grant-admin-consent?pivots=ms-graph#grant-admin-consent-for-application-permissions-1

@Yvand
Copy link

Yvand commented Mar 29, 2023

@MartinHatchL365 it looks good to me: In my script I am using endpoint /appRoleAssignments just fine...

@MartinHatchUK
Copy link

Does it make a difference that I'm logged in using a Service Principal?

@jiasli
Copy link
Member

jiasli commented Aug 9, 2023

Another workaround is to use Microsoft Graph PowerShell SDK which is another client tool for AAD:

@StefH
Copy link

StefH commented Jun 27, 2024

Just a quick note (I hope I'm not confusing anyone), but on my Azure Tenant, the MS Graph (00000003-0000-0000-c000-000000000000) does not have an objectId but (only) a id.

So in my case, the code to get the correct resourceId for MS Graph is

az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "id" --output tsv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants