Requested Scope Not Present in Access Token scp Claim

Frequent Visitor

TL,DR version:

  • I have an Azure AD app registration for a UI configured with permission to request an API scope from another app registration.
  • The UI app is correctly requesting the API scope and the scope is present in the consent UI presented to the user.
  • The scp claim does not contain the API scope even though it was authorized.
  • Is this expected behavior?

Hello all. I have a pretty extensive background in leveraging OAuth 2.0 and OIDC for authorization and authentication management. However, I'm just breaking into the Azure implementation of these concepts, and I'm finding myself a little confused by some of the specifics. My goal is to use Azure AD app registrations to secure the interaction between a UI and the API it consumes. Historically, I'm used to defining a scope, granting my UI client permission to request that scope from my IdP, and demanding on the API side that the scope claim be present in an access token to authorize access to that API.


I've defined an app registration for my API, as well as defined an "all access" scope for it under the Expose an API blade. I've also defined an app registration for my UI and requested that scope under the API Permissions blade. I've created the UI client app and added the fully qualified scope name (something like api:// to the requested scopes for the authorize request to be made using the MSAL. When logging in, my user is presented with the consent UI, and the API scope and app are listed as part of the requested permissions. When monitoring the request in my browser network tab, the scope form data element includes the expected value, something like:


scope: User.Read api:// openid profile offline_access


This is what I would expect if I wanted to request API scope access, MS Graph access, and user profile information from Azure AD, all appropriate for my goals. However, when checking the access token returned from the request, the scp claim only includes the following:


  "scp": "openid profile User.Read email"


I'm a little confused by the results here, because if I'm requesting access to a resource scope, my expectation is that the resource should be able to verify the access token presented contains the required scope for access. Is there some reason the app registration's resource principal is cut out of the list here? Am I misunderstanding the access model intended with these app registrations? Or did I just mess up my configuration somewhere?


It appears, after some testing, that the order in which I request scopes in MSAL determines the output of the access token. It would seem that I cannot request Microsoft Graph API scopes at the same time as one of my app registration API scopes, and the first requested scope defines what else is included in the token. Is my understanding correct, and is this expected? I can imagine some of the reasons why this is so, but could use validation.

1 Reply
This question is not for MS Defender for Cloud Apps (MDCA), formerly MS Cloud App Security (MCAS).

Please post your question to the Azure AD community, instead.