Last date modified: 2026-Apr-24
Role-based access control
Use role-based access control (RBAC) in Microsoft 365 Exchange Online to restrict your Azure Application Registration to access only specific mailboxes. This is important for workflows where your application needs mail access, and still want to limit that access to a defined set of custodians rather than all users in your organization.
Azure application permissions
Azure application permissions are always-on by default.
When an application token is generated, it carries all permissions assigned to the app, regardless of any user-level RBAC assignments. This means you must carefully manage which permissions are assigned directly to the application versus which are scoped with RBAC.
The approach in this guide deliberately splits permissions between these two methods to achieve mailbox-level restriction.
Prerequisites
Before you begin, ensure you have the following in place:
- An Azure Application Registration already created for your application.
- The Application (Client) ID and the Service Principal Object ID for your app.
- Make sure you are copying the Object ID from the Service Principal entry when looking up your app in Azure.
- Do not copy from the Application Registration entry.
- These are different objects in Azure AD and have different Object IDs.
- Using the wrong one will cause the PowerShell commands to fail silently or produce unexpected results.
- Make sure you are copying the Object ID from the Service Principal entry when looking up your app in Azure.
- Exchange Online PowerShell module installed and connected with appropriate admin privileges.
- The email addresses of the custodian mailboxes you want to grant access to.
Permission architecture
RBAC in Exchange Online has fewer granular permission options than Azure AD directly. As a result, some permissions must be assigned directly to the application, while the sensitive mail-access permissions are controlled through RBAC scoping.
Exchange Online has fewer permission options than Azure AD. Because of this, some permissions must be given directly to the app, while sensitive email access is controlled using RBAC limits.
Permissions assigned directly to the Azure App
Assign only the following permissions directly to your Azure Application Registration. These are needed for general user/file access and cannot be scoped with RBAC:
| Permission Name | Purpose |
|---|---|
| Files.Read.All | Read files across SharePoint and OneDrive |
| Sites.Read.All | Read SharePoint site content |
| User.Read.All | Read user profile information across the tenant |
Permissions assigned with RBAC (Mailbox-Scoped)
The following permissions should not be assigned directly to the app. Instead, they will be granted to specific mailboxes only through the RBAC steps in this guide:
For standard Outlook mailboxes:
| Permission Name | Purpose |
|---|---|
| Application Mail.Read | Read mail from scoped mailboxes only |
| Application Calendars.Read | Read calendar events from scoped mailboxes only |
| Application Contacts.Read | Read contacts from scoped mailboxes only |
For archived mailboxes:
| Permission Name | Purpose |
|---|---|
| Application EWS.AccessAsApp | Access archived mailbox data through Exchange Web Services |
Configuration steps
The following five steps must be performed in order using Exchange Online PowerShell. Replace the example values, such as App IDs, email addresses, names, with your own.
To complete RBAC configurations, you must complete the following steps:
- Connect to Exchange Online PowerShell.
- Create a Service Principal in Exchange Online.
- Create a Management scope for custodians.
- Assign permissions to custodians.
- Verify the configuration.
Connect to Exchange Online PowerShell
Run all Exchange commands inside PowerShell. On macOS/Linux, you must start PowerShell (pwsh) first; running these commands in zsh/bash will fail.
macOS / Linux:
- Start PowerShell:
Copy
pwsh - Import the module:Copy
Import-Module ExchangeOnlineManagement - Connect using device authentication (recommended):Copy
Connect-ExchangeOnline -Device - Complete sign-in at https://login.microsoft.com/device and then verify:Copy
Get-OrganizationConfig
Windows
- PowerShell and import the module (if needed):Copy
Import-Module ExchangeOnlineManagement - Connect:Copy
Connect-ExchangeOnline
Create a Service Principal in Exchange Online
Register your Azure application as a Service Principal within Exchange Online. This links your Azure app to Exchange so that RBAC assignments can be applied to it.
New-ServicePrincipal \
-AppId <Your-Application-Client-ID> \
-ObjectId <Your-Service-Principal-Object-ID> \
-DisplayName <FriendlyNameForYourApp>
Example:
New-ServicePrincipal
-AppId 2609b7e1-3b41-4e57-aa12-03bccbed8534 \
-ObjectId 57b270fd-8b3f-47c3-9a12-29083613dff1 \
-DisplayName FilteredMailboxApp
Verify (recommended):
Get-ServicePrincipal | Where-Object AppId -eq "APP_ID"
If New-ServicePrincipal indicates the AppId/ObjectId is already used, the Exchange service principal already exists and you can proceed.
Find the AppID and Object ID values
Find these values in the Azure Portal:
- Navigate to Azure Active Directory > Enterprise Applications > [your app].
- The Object ID shown here is the Service Principal Object ID.
- The Application (Client) ID is found under Azure Active Directory > App Registrations > [your app] > Overview.
Create a Management scope for custodians
A Management Scope defines which mailbox a permission applies to. You must create one scope per custodian (user). The scope Name you set here will be used as the CustomResourceScope in Step 4.
New-ManagementScope \
-Name "<ScopeName>" \
-RecipientRestrictionFilter "PrimarySmtpAddress -eq '<user@yourdomain.com>'"
Example. Repeat for each custodian:
New-ManagementScope -Name "Jane" -RecipientRestrictionFilter "PrimarySmtpAddress -eq 'jane.doe@contoso.com'"
New-ManagementScope -Name "John" -RecipientRestrictionFilter "PrimarySmtpAddress -eq 'john.smith@contoso.com'"
Assign permissions to custodians
Now assign each required permission to each custodian by creating a Management Role Assignment.
Each permission requires a separate assignment entry, but all assignments for the same user should share the same CustomResourceScope name. The scope name from Create a Management scope for custodians.
For archived mailbox access. One entry per custodian:
New-ManagementRoleAssignment \
-Name "<UniqueAssignmentName>" \
-Role "Application EWS.AccessAsApp" \
-App <Your-Service-Principal-Object-ID> \
-CustomResourceScope "<ScopeName>"
For standard Outlook mailbox access. Three entries per custodian, one per permission:
New-ManagementRoleAssignment -Name "<Name>_Mail" -Role "Application Mail.Read" -App <ObjectId> -CustomResourceScope "<ScopeName>"
New-ManagementRoleAssignment -Name "<Name>_Cal" -Role "Application Calendars.Read" -App <ObjectId> -CustomResourceScope "<ScopeName>"
New-ManagementRoleAssignment -Name "<Name>_Contacts" -Role "Application Contacts.Read" -App <ObjectId> -CustomResourceScope "<ScopeName>"
Example for two custodians with archived mailbox access:
New-ManagementRoleAssignment -Name "Jane_EWS" -Role "Application EWS.AccessAsApp" \
-App 57b270fd-8b3f-47c3-9a12-29083613dff1 -CustomResourceScope "Jane"
New-ManagementRoleAssignment -Name "John_EWS" -Role "Application EWS.AccessAsApp" \
-App 57b270fd-8b3f-47c3-9a12-29083613dff1 -CustomResourceScope "John"
Naming tip
The -Name parameter must be unique across all role assignments.
The -CustomResourceScope must exactly match the -Name you used in New-ManagementScope for that user. For example, all of Jane's assignments should use -CustomResourceScope "Jane" regardless of how you name the individual assignments.
Verify the configuration
After completing the above steps, use the following command to verify that the correct permissions are applied to a specific mailbox:
Test-ServicePrincipalAuthorization \
-Identity <FriendlyNameForYourApp> \
-Resource <user@yourdomain.com> | Format-Table
Example:
Test-ServicePrincipalAuthorization -Identity FilteredMailboxApp -Resource jane.doe@contoso.com | Format-Table
The output will list the permissions that your application has been granted for that specific mailbox. If a permission does not appear, verify that the Management Scope name and CustomResourceScope match exactly, and that the Service Principal Object ID was used. Not the Application Object ID.
Troubleshooting
This section covers common issues you may encounter when configuring or validating mailbox access and RBAC scoping.
Use the scenarios below to quickly identify misconfigurations, permission assignment problems, or command‑line errors before continuing with setup.
Application can still access unscoped mailboxes
Verify that the mail-access permissions (Mail.Read, Calendars.Read, Contacts.Read, EWS.AccessAsApp) are not assigned directly on the Azure Application Registration. Any permission assigned directly to the app bypasses RBAC scoping entirely.
Test-ServicePrincipalAuthorization shows no permissions
Confirm the -Identity value matches the DisplayName used in New-ServicePrincipal
Confirm the CustomResourceScope in New-ManagementRoleAssignment exactly matches the Name used in New-ManagementScope
Confirm you used the Service Principal Object ID from Enterprise Applications and not the Application Object ID from App Registrations.
PowerShell commands return an error or unexpected results
Ensure you are connected to Exchange Online PowerShell with a global admin or Exchange admin account
Re-run Get-ServicePrincipal to confirm the Service Principal was created successfully before proceeding to later steps
macOS: zsh: command not found
You are running commands in zsh instead of PowerShell. Start PowerShell with pwsh and run the cmdlets in the PS prompt.