I am currently creating an integration with Microsoft Partner Center utilizing GDAP.
The current flow I have is:
- An admin (either Global Admin, Cloud Apps Administrator, or Application Admin) consents to a basic application (scopes include
DelegatedAdminRelationship.Read.Alland Partner Center'suser_impersonation) - 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:
- Grant delegated permission via admin consent like above
- Assign app roles to the service principal that gets installed from the consent
- 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 
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?
Immediately after posting this I figured out the solution. If you are using
grant_type: refresh_tokento obtain your access token, this will only ever return delegated permissions. In order to use my app roles (application permissions) I needed to usegrant_type: client_credentials.Note:
client_credentialsaccess 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.