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.
  • 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:

  1. Connect to Exchange Online PowerShell.
  2. Create a Service Principal in Exchange Online.
  3. Create a Management scope for custodians.
  4. Assign permissions to custodians.
  5. 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:

  1. Start PowerShell:
    Copy
    pwsh
  2. Import the module:
    Copy
    Import-Module ExchangeOnlineManagement

  3. Connect using device authentication (recommended):
    Copy
    Connect-ExchangeOnline -Device
  4. Complete sign-in at https://login.microsoft.com/device and then verify:
    Copy
    Get-OrganizationConfig

Windows

  1. PowerShell and import the module (if needed):
    Copy
    Import-Module ExchangeOnlineManagement
  2. 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.

Copy
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):

Copy
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:

  1. Navigate to Azure Active Directory > Enterprise Applications > [your app].
  2. The Object ID shown here is the Service Principal Object ID.
  3. 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.

Copy
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:

Copy
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:

Copy
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:

Copy
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.

Return to top of the page
Feedback