Search code examples
microsoft-graph-apimulti-tenantazure-app-registrationmicrosoft-partner-center

Assigning app role to Partner Center consented application not available in access token's scope


I am currently creating an integration with Microsoft Partner Center utilizing GDAP.

The current flow I have is:

  1. An admin (either Global Admin, Cloud Apps Administrator, or Application Admin) consents to a basic application (scopes include DelegatedAdminRelationship.Read.All and Partner Center's user_impersonation)
  2. Using the refresh token from the consent, obtain an access token to the Partner Center API and perform an admin consent for each of the delegated tenant relationships. This consent includes basic scopes for the Graph API like Directory.Read.All, UserAuthenticationMethod.Read.All, etc.

The problem lies herein that the admin consents are delegated permissions. I need an application permission for the MailboxSettings.Read scope in order to determine if an inbox is shared.

I understand the flow would be something like:

  1. Grant delegated permission via admin consent like above
  2. Assign app roles to the service principal that gets installed from the consent
  3. Obtain new access token and perform operations as needed

The app roles are being added correctly via the following

POST https://graph.microsoft.com/v1.0/servicePrincipals/:spId/appRoleAssignedTo
{
    "principalId":"a-b-c-d", // My app's service principal in the tenant
    "resourceId":"e-f-g-h", // Microsoft Graph's service principal in the tenant
    "appRoleId":"40f97065-369a-49f4-947c-6a255697ae91" // this is MailboxSettings.Read
}

I can see them in the tenant's Azure enter image description here

However, when I obtain the new access token (by using a refresh token) those added app roles are not in list of scopes, just the delegated permissions. So that token does not let me read mailbox settings as example:

{
    "error": {
        "code": "NoUserFoundWithGivenClaims",
        "message": "The user specified by the user-context in the token does not exist.",
        "innerError": {
            "oAuthEventOperationId": "--",
            "oAuthEventcV": "--",
            "errorUrl": "https://aka.ms/autherrors#error-InvalidUser",
            "requestId": "--",
            "date": "2024-01-11T18:15:50"
        }
    }
}

What am I missing?


Solution

  • Immediately after posting this I figured out the solution. If you are using grant_type: refresh_token to obtain your access token, this will only ever return delegated permissions. In order to use my app roles (application permissions) I needed to use grant_type: client_credentials.

    Note: client_credentials access token will only return application permissions. So to effectively use both sets of permissions you will either need two access tokens, or use app roles for all the permissions. I went with the former so ensure I only use the scopes when needed.