DEV Community

Kinga
Kinga

Posted on • Edited on

RBAC for Exchange Online Mailboxes

If you are writing solutions that target Microsoft 365 services, you need to plan for permissions that your application will have to these resources.

It doesn't really matter if you are using Azure Services with Managed Identity, or a custom application with Service Principal. You have to set API permissions.

Architecture design

Let's imagine a "daemon" application (a software that runs in the background without user interaction) that needs to synchronize information between "Events" SharePoint Online list and an Exchange Online mailbox belonging to a group responsible for organizing these events. Invitations are sent to members of the group and replies need to be recorder in the list.

This means that the application needs to Read and Write to both: the SharePoint list and the Exchange calendar:

Logical Design

The business logic is implemented using Azure Function, with System-Managed Identity.
Some tests are performed using Postman, with a Service Principal.

API Permissions

I'm a staunch believer in a minimum-required permissions and would never implement an application that has indiscriminate access to all resources using Graph API (unless specifically required, that is).

SharePoint offers Sites.Selected Application API permissions that together with Grant-PnPAzureADAppSitePermission allow granting Read/Write or FullControl (with Set-PnPAzureADAppSitePermission) permissions to the application identity.

But what about the mailboxes? The API permissions for Calendars grant access to all the mailboxes. That's a bit of overreach, innit?

API permissions

Luckily there's a way to set granular access rights on the Exchange Online mailboxes as well!

There are two ways to do it:

However, "App Access Policies will soon be replaced by Role Based Access Control for Applications." New-ApplicationAccessPolicy (ExchangePowerShell)

Setting RBAC

The procedure requires Exchange Online PowerShell

Let's use the Service Principal created for Postman.

In order to retrieve the information required for setting RBAC, you need to find out the Object and Application IDs belonging to the Enterprise Application and not the App Registration. Click on the App name under "Managed application in local directory"

Image description

You will be redirected to "Enterprise Application" page displaying the IDs you need to use:

Image description

Exchange Online Service Principal

Next, we need to create a Service Principal. Why?

In Exchange Online, service principals are references to the service principals in Azure AD. To assign Exchange Online role-based access control (RBAC) roles to service principals in Azure AD, you use the service principal references in Exchange Online.

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName

New-ServicePrincipal `
    -AppId f3776ca2-2d7c-48f8-9e3c-7xxxxxxxxxxx `
    -ObjectId b7cb2398-1e91-4a8b-95b8-xxxxxxxxxxxxx `
    -DisplayName "Postman"
Enter fullscreen mode Exit fullscreen mode

Exchange Online Management Scope

The Role Based Access Control for Applications in Exchange Online proposes two resource scopes for defining who has the RBAC:

  • Management Scopes and
  • Administrative Units

You have to go with Management Scopes to use the Managed Identity/Service Principals. Administrative units don't allow these.

New-ManagementScope `
    -Name "My Scope" `
    -RecipientRestrictionFilter "Alias -eq 'mailboxname' "
Enter fullscreen mode Exit fullscreen mode

Exchange Online Management Role Assignment

And now we can grant the Service Principal the RBAC to the mailbox:

New-ManagementRoleAssignment `
    -App "f3776ca2-2d7c-48f8-9e3c-7xxxxxxxxxxx" `
    -Role "Application Calendars.ReadWrite" `
    -CustomResourceScope  "My Scope"
Enter fullscreen mode Exit fullscreen mode

Did it work?

Test-ServicePrincipalAuthorization `
    -Identity "f3776ca2-2d7c-48f8-9e3c-7xxxxxxxxxxx" `
    -Resource mailboxname@tenantname.onmicrosoft.com
Enter fullscreen mode Exit fullscreen mode

Did you know? You don't have to build the Graph API requests in Postman yourself. You can fork the Microsoft Graph collection and focus on the fun stuff.
Use Postman with the Microsoft Graph API

Limitations

  • Applications can't become member of a Role Group.
  • Application roles can only be assigned to Service Principals.
  • Application roles can't be copied or derived.
  • Exclusive management scopes don't restrict app access.
  • Changes to app permissions are subject to cache maintenance that varies** between 30 minutes and 2 hours **depending on the app's recent usage. When testing configurations, the test command bypasses this cache. An app with no inbound calls to APIs will have its cache reset in 30 minutes, whereas an actively used app will keep its cache alive for up to 2 hours.

Full script

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName

$scopeName=""
$mailboxName=""
$tenantName=""
$appName=""
$appId=""
$objId=""

New-ServicePrincipal -AppId $appId -ObjectId $objId -DisplayName $appName
New-ManagementScope -Name $scopeName -RecipientRestrictionFilter "Alias -eq $mailboxName "
New-ManagementRoleAssignment -App $appId -Role "Application Calendars.ReadWrite" -CustomResourceScope $scopeName

Test-ServicePrincipalAuthorization -Identity $appId  -Resource "$mailboxName@$tenantName.onmicrosoft.com"

Enter fullscreen mode Exit fullscreen mode

Find the permissions required to run any Exchange cmdlet

Top comments (0)