The relationship between Graph permission scopes and Entra RBAC roles supports a user’s ability to access resources in Microsoft 365. Combined with a client app and the idea that the app needs to access these resources on behalf of a user, then how delegated access works can become quite confusing.
This article will guide you through understanding how delegated access in Microsoft Graph works with some practical scenarios using Microsoft Graph PowerShell.
Understanding delegated access
To start off, it is important to have a strong grasp of how delegated access works when working with permissions and access in Microsoft Entra and Microsoft Graph. In summary, delegated access refers to the scenario when an application can access resources on behalf of a user in Microsoft Graph when it is authorised to do so.
For example, if you sign into an application that reads your Exchange emails (like Microsoft Outlook), that application will need to be able to access your mailbox on your behalf to return the data that has been requested. At a high level, you may access a desktop app that reads your mail, that app will utilise the Exchange service, which then accesses your data on your behalf via the Microsoft Graph API.
This process is dependent on two types of permissions being available, the Graph API permission scope and the Entra role-based access permissions. Both the application (or service) must have consented to the graph permission scope and you need the correct authorisation to access the data being requested. The diagram below (created by Microsoft) visually represents how the combination of both permission types grants access to a resource.
To break this down a little more, when a user logs into the application and makes a request to the Microsoft Graph API to access a resource via the client app (a Service Principal in Entra ID), all permissions that have been consented to the client app, will be available in the user’s access token. This doesn’t mean that every permission in the user’s access token will be available to use. When a request is then made, a check will be made against the user’s access level in Entra ID, then only the actions made available by both the Entra Role and permission scope can be performed.
A practical scenario of delegated access
Let’s run through a common scenario:
You are compliance administrator and you need to read messages inside a users mailbox that has been shared with you using Microsoft Graph PowerShell.
The first thing to do is open PowerShell and run the following command to provide admin consent for the Mail.ReadBasic.Shared permission to the built-in Microsoft Graph Command Line Tools application, which must be done as a Global Administrator or Privileged Role Administrator. This permission allows the app to read mail that the signed-in user can access.
Connect-MgGraph -Scope Mail.ReadBasic.Shared
Now consent has been provided, the application (which you connect to via PowerShell) can access messages on your behalf for the mailboxes you have access to. Use the following example to view messages for a mailbox that has been shared with you.
Get-MgUserMessage -UserId [email protected]
As you can see from the below image, I have connected to Microsoft Graph PowerShell in the delegated auth type, using the [email protected] user account. I then used the Get-MgUserMessage cmdlet to view messages that are contained inside another mailbox.
Finding the correct Entra RBAC role
As mentioned earlier, just having consent to a permission scope in Microsoft Graph will not immediately provide you access to the resources in the delegated auth type scenario, you must also have a ‘matching’ Entra RBAC role assigned and activated on your account. What is confusing is that as soon as the permission is consented to, the permission will be within the SCP claim in your access token, regardless of your Entra RBAC role. The SCP claim is a set of scopes which the client application has consent for.
Take this scenario for example. Below I have connected to Microsoft Graph PowerShell as user ‘Bill’. When I check what permissions are available, I notice the Group.ReadWrite.All permission is available. This is because the Microsoft Graph Command Line Tools application was previously used by a Global Administrator who consented to that permission already.
I then decide that I need to modify the name of a group, to do this, I run the Update-MgGroup cmdlet to modify the name of the Marketing group, however, I am met with an error message.
The error message simply states that I have insufficient privileges to complete the operation, with a 403 (Forbidden) status. Digging a little deeper into this problem, we can highlight the issue by viewing the claims in the access token. To get the raw access token from your session, you can run the following two commands:
$data = Invoke-MgGraphRequest -Uri "https://graph.microsoft.com/v1.0/me" -Method GET -OutputType HttpResponseMessage
$data.RequestMessage.Headers.Authorization.Parameter
Running these commands will output the access token into your PowerShell session, where you can copy it to your clipboard. A web-based tool like https://jwt.io/ can decode your access token so you can view the claims. In this instance, I have decoded Bill’s access token to find the following:
"scp": "Group.ReadWrite.All Mail.ReadBasic.Shared openid profile User.Read email",
"sub": "JjdmqPHCitYPx8wQwfw7LBTO_th39vPidbnd2TtaW9g",
"tenant_region_scope": "EU",
"tid": "4e67cd72-f73a-42aa-a841-b8dd6ec328ca",
"unique_name": "[email protected]",
"upn": "[email protected]",
"uti": "vaWzBfCPoUS4oLkWYggEAQ",
"ver": "1.0",
"wids": [
"fe930be7-5e62-47db-91af-98c3a49a38b1",
"b79fbf4d-3ef9-4689-8143-76b194e85509"
],
You can see already that the Group.ReadWrite.All permission is available in the token, but more important is the wids claim which denotes the Entra RBAC roles assigned to this user. In this case, ‘88d8e3e3-8f55-4a1e-953a-9b9898b8876b‘ is the template ID for the Directory Readers role, which based on the name, it can be assumed that this role does not allow for modification to groups, hence the authorisation error.
Of-course in true Microsoft style, there is no direct mapping available between Entra RBAC roles, the actions within those roles and Microsoft Graph API Permission scopes, making it difficult to practise true least privilege in the delegated scenario for some cases. Your best bet would be to analyse the ‘allowedResourceActions’ property on the Entra RBAC role of choice using the ‘unifiedRoleDefinition’ endpoint as I have done in a recent article on this blog ‘Microsoft recommends use of the unifiedRoleDefinition APIs‘.