Limit app permissions to a specific mailbox

Limit app permissions to a specific mailbox header image

As you might imagine I have been building a lot of apps over the years. Mostly using the Microsoft Graph to do stuff with my Microsoft 365 environment. But there is this one thing I always encounter when deploying to a customer. The requirements to limit what your app can do. Working with the Application Permissions you can scope most of the things you want to achieve, but there are a few exceptions.

Let’s say you want to have a daemon application that sends a status update through e-mail. This will result in adding the Mail.Send or Mail.Read permissions, but since it you require application permissions that would result in your application to be able to send e-mail’s for any e-mail address in your environment. Luckily you can scope that down and select specific e-mail addresses.

Limit the application to a specific (shared) mailbox

With your application Azure AD application registration in place and permissions handed out the default allows you to send e-mails as anyone. However, using an ApplicationAccessPolicy you can scope it down to specific mailboxes. You can scope down access to one or multiple mailboxes making sure your application cannot access other mailboxes. Even better is that you do not have to implement custom logic in code except perhaps the handling of not being able to access data. As an IT-administrator you can configure the ApplicationAccessPolicy for your tenant and applications yourself. Doing so is described in detail on Limiting application permissions to specific Exchange Online mailboxes. What follows here is a write-up on how to create everything from scratch, but you can of course upgrade existing applications.

Setting up the app and policy

Step one to get started is to create a new Azure AD App registration. In our demo scenario I want to use a Logic App to read the mailbox of a specific user. I use the CLI for Microsoft 365 to generate the app using the following command: m365 aad app add --name 'MailTest' --withSecret --apisApplication 'https://graph.microsoft.com/Mail.Read'. Don’t forget to grand access to the permissions after creating the app. When executing the command, you are presented with something that looks like this:

{
  "appId": "GUID",
  "objectId": "GUID",
  "tenantId": "GUID",
  "secret": "SECRET"
}

Those values are required in next steps so make sure to write them down before moving on. The next step is to create an Application Access Policy. Make sure you have the Exchange Online Management shell Install-Module -Name ExchangeOnlineManagement -Scope AllUsers and connect Connect-ExchangeOnline -UserPrincipalName admin@contoso.com. To create a the access policy you can use the following:

$appId = "YourAzureADAppRegId"
$mailbox = "user@contoso.com"
New-ApplicationAccessPolicy -AppId $appId -PolicyScopeGroupId $ mailbox -AccessRight RestrictAccess -Description "Restrict this app to a specific mailbox"

Changes to application access policies can take longer than 1 hour to take effect in Microsoft Graph REST API calls, even when Test-ApplicationAccessPolicy shows positive results.

With the access policy in place, it is time to test our App Registration πŸš€.

Testing our App and Policy

Since we have an app registration with a client id and secret, we can call the Microsoft Graph using a Logic App. If you never done that you can following along with How to call a Microsoft Graph API from Azure Logic App. If you would call the Graph with an HTTP action that calls our user@contoso.com you can expect the following result, a nice 200 response with the content we requested:

Succesfull Graph Call with the e-mails we are requesting

However if you call any other e-mail account with the same credentials, eventhough you do have (delegated) permissions the policy will kick in and will let you know that you cannot access the contents.

Shuffle array flow

If you are building automations in the cloud or your customer want to make sure you do not have permissions on all e-mails I can highly recommend to adopt this as a best practice. Even if your client secret would be somehow compromised you can guarantee that it can only use a single e-mailaddress to interact with πŸ”.

Loading comments…