Limiting the Scope of Application Permissions

Limiting the Scope of Application Permissions is critical to security

In previous blogs, we have already talked about the dangers of applications permissions used in app registrations. While they have their uses, the danger lies within the fact that these permissions are always tenant wide. When you create an app registration with the application permission ‘Mail.ReadWrite’, this application has the ability to update every mailbox within your organization.

This might be less than desirable more often than not, because a lot of applications only require permissions on a subset of resources within your tenant. In this blog, we’ll walk you through how to scope application permissions to a subset of resources within Exchange and Sharepoint Online.

Exchange Online

Scoping applications within Exchange Online is done through application access policies. These policies allow us to do the following:

Allow access to only a certain group of mailboxes (Whitelisting)
Deny access to a certain group of mailboxes (Blacklisting)
You should always try to whitelist instead of blacklist as this ensures that you are 100% controlling the access the application has.

Application access policies are supported for the following Microsoft Graph Application permissions:

  • Read

  • ReadBasic

  • ReadBasic.All

  • ReadWrite

  • Send

  • Read

  • ReadWrite

  • Read

  • ReadWrite

  • Read

  • ReadWrite

  • Application access policies cannot be configured through the GUI, Powershell is your only option here. In total there are five commands at your disposal.

  • Get-ApplicationAccessPolicy

  • New-ApplicationAccessPolicy

  • Remove-ApplicationAccessPolicy

  • Set-ApplicationAccessPolicy

  • Test-ApplicationAccessPolicy

Creating your first application access policy

The first command you will use is ‘New-ApplicationAccessPolicy’, this will allow you to create a new policy to restrict access for your applications. The parameters that are of interest are:

Name: Provide a name for the policy
Description: A meaningful summary for the policy, this should help you identify the policy in the future. I like to reference the internal documentation of the app here.

AccessRight: This will determine if you are whitelisting/blacklisting access. There are two available options here: RestrictAccess (Whitelist) and DenyAccess (blacklist)

AppId: The application/client ID of your application
PolicyScopeGroupId: The mail enabled security group for which you want to restrict accessTo retrieve the AppId, navigate to the app registration for which you want to restrict access and copy the ‘Application ID’.

If you want to whitelist access for the group ‘ERP Users’, you would use the following command:

New-ApplicationAccessPolicy -AppId 2977f32f-6805-42df-9ced-7a30137b23eb -PolicyScopeGroupId "ERPUsers" -AccessRight RestrictAccess -Description "This policy is created for our Accounting ERP Application. See Confluence for more information"

This will ensure that the application only has access to mailboxes which are a member of the group ‘ERP Users’.

When you want to make sure that an application does not have access to the mailboxes of your VIP Users (blacklisting access), the following command is applicable:

New-ApplicationAccessPolicy -AppId 2977f32f-6805-42df-9ced-7a30137b23eb -PolicyScopeGroupId "VIP Users" -AccessRight DenyAccess -Description "This policy is created for our Accounting ERP Application. See Confluence for more information".

Testing the policy

After you have created the policy, you can validate it by using the ‘Test-ApplicationAccessPolicy’. This is especially useful when you have multiple policies, which might be active on one application.

To validate if the application ‘2977f32f-6805-42df-9ced-7a30137b23eb’ is able the access the mailbox of your CEO, use the following command:

Test-ApplicationAccessPolicy -AppId 2977f32f-6805-42df-9ced-7a30137b23eb -Identity
Within the output, you can reference the ‘AccessCheckResult’ variable to validate if a certain application has access to the mailbox.

Sharepoint Online

The ability to restrict application permissions for Sharepoint Online has only been announced recently (February 2021) and can only be configured through the Microsoft Graph. The configuration also differs from the implementation for Exchange Online. While Exchange Online will restrict applications with (almost) all EXO related permissions, Sharepoint has introduced a new permission called ‘Sites.Selected’

With this permission, the application will only be able to access sites it has explicitly been allowed for.

In order to provide the application access to a specific site, you need to retrieve the ID of the Sharepoint Site. This can be easily done by navigating to the Microsoft Graph Explorer and using the query ‘{tenantName}{SiteName}’. You will find the ID within the output of your request.

After you have retrieved the site ID, you need to approve access for the application to your desired site. To do so, you need to update the permissions for your site. This is also possible through the Graph Explorer.

Use the URL ‘{siteId}/permissions’, where {siteId} is the ID of the site you just retrieved. The body of the request should include the application ID of the app registration you whish to provide access to the Sharepoint site and the kind of access you want to provide to the app (defined in the roles parameter). This allows you to configure whether your applications requires read or write permissions.


"roles": ["write"],

"grantedToIdentities": [{

"application": {

"id": "{AppID}”

"displayName": "CRM App"



Sharepoint doesn’t offer the same built-in validation as Exchange to easily validate the permissions on application has over a specific site. The only option to validate your configuration is by manually creating a query which executes actions on specific sites.

Identifying tenant wide application permissions

By using Senserva and KQL, it’s rather easy to identify permissions used within app registrations that need to be scoped down. Below is an example query that can be used to search for ‘Sites.FullControl.All’ permissions.
Only a limited set of applications should have access to all your Sharepoint sites, most of them should be using the ‘Sites.Selected’ permissions to limit the applications scope.

let PermissionsSearch = "Sites.FullControl.All";
| where ControlName_s == "ApplicationPermission"
| extend values =parse_json(Value_s)
| mv-expand values
| where values.Tag == "ApplicationPermission"
| extend permissions=parse_json(values.Value).["$values"], AppName = parse_json(Value_s)[0].Value
| mv-expand permissions
| where permissions.RoleName startswith PermissionsSearch and permissions.RoleType == "Application Permission"
| distinct tostring(AppName), ControlName_s, Description_s, ObjectId_g, MitreControls_s, tostring(permissions.RoleName)

While Sharepoint and Exchange both provide a way to scope application permissions to a certain set of resources, the situation is still less than ideal. The configuration for Sharepoint and Exchange is very different and they don’t support the same capabilities. While Exchange supports both black-and whitelisting, Sharepoint only supports whitelisting.

In general, there is a lot that can be improved when we are talking about scoping application permissions. There are currently only two workloads that support it, while other workloads are in dire need of it (such as Teams and Microsoft Endpoint Manager).

Senserva is focused on automating Azure Active Directory security and Azure Sentinel for things like those reviewed in this article.

By Thijs Lecomte|June 2, 2021