The objective of this post is to detail the steps required to configure Exchange Online RBAC for Applications so that an Azure Function using a system‑assigned managed identity can perform Calendars.ReadWrite operations only on one specific shared mailbox. All other mailbox scopes must return AccessDenied.
Content
Prerequisites
Azure
- Azure Function with system‑assigned managed identity
- Application ID:
458f1d57-9413-4824-b9d7-abed2934c819 - Object ID:
74fac675-00ea-4f7f-a3e6-88ce3e4478c2
- Application ID:
Exchange Online / Microsoft 365
- Shared mailbox: rbac_shared@tenant.onmicrosoft.com
- Other mailbox used for denial example: other_mailbox@tenant.onmicrosoft.com
Tools
- ExchangeOnlineManagement v3+ PowerShell module
Connect to Exchange Online PowerShell
To configure Application RBAC, connect with appropriate admin privileges:
Connect-ExchangeOnlineThis session is required to create the management scope, register the service principal, and assign the built‑in role.
Enable Organization Customization
Application RBAC requires that your tenant has organization customization enabled.
Enable-OrganizationCustomizationThis is a one‑time operation per tenant.
Create a Recipient‑Restricted Management Scope
Select RecipientRestrictionFilter to ensure the role assignment applies only to the shared mailbox.
Create the scope
New-ManagementScope `
-Name "RBAC_SingleMailboxScope" `
-RecipientRestrictionFilter "PrimarySmtpAddress -eq 'rbac_shared@tenat.onmicrosoft.com'"Why this matters
This restricts the managed identity’s RBAC role so it only applies to this one mailbox. Even though the Graph permission is broad (Calendars.ReadWrite application permission), RBAC restricts its effective reach.
Register the Service Principal in Exchange Online
This step brings the Entra ID service principal into Exchange Online’s RBAC system.
New-ServicePrincipal `
-AppId '458f1d57-9413-4824-b9d7-abed2934c819' `
-SerivceId '74fac675-00ea-4f7f-a3e6-88ce3e4478c2' `
-DisplayName 'AzureFunctionMI'The SerivceId for a system‑assigned identity is the Object ID of the managed identity, AppId is the Application ID (managed identity Application ID can be found in Entra ID.
Role Assignment
Assign a built-in role (Application Calendars.ReadWrite) to the service principal.
You can find other supported roles here: Supported Application Roles
New-ManagementRoleAssignment `
-App "458f1d57-9413-4824-b9d7-abed2934c819" `
-Role "Application Calendars.ReadWrite" `
-CustomResourceScope "RBAC_SingleMailboxScope"This assignment grants permission only to the mailbox permitted by the custom scope created earlier.
Test RBAC Authorization
Before testing you requests on the Azure function, you can first directly test the serivce principal access using Test-ServicePrincipalAuthorization.
Allowed mailbox test
Test-ServicePrincipalAuthorization `
-Identity "458f1d57-9413-4824-b9d7-abed2934c819" `
-Resource "rbac_shared@tenant.onmicrosoft.com"You should get the following as a result:
RoleName : Application Calendars.ReadWrite
GrantedPermissions : Calendars.ReadWrite
AllowedResourceScope : RBAC_SingleMailboxScope
ScopeType : CustomRecipientScope
InScope : True
Identity : 74fac675-00ea-4f7f-a3e6-88ce3e4478c2
IsValid : True
ObjectState : NewValidate with Microsoft Graph API
Your Azure function will call the endpoint:
/users/{id}/eventsUsing the shared mailbox’s UPN.
Allowed request:
Request
GET https://graph.microsoft.com/v1.0/users/rbac_shared@tenant.onmicrosoft.com/eventsExample JSON response body (success)
[
{
"Id": "AAMkAGE2...",
"Subject": "This is a test meeting",
"Start": "2026-02-05T14:00:00.0000000",
"StartTz": "Europe/Paris",
"End": "2026-02-05T14:30:00.0000000",
"EndTz": "Europe/Paris",
"Location": "Microsoft Teams Meeting",
"Organizer": "rbac_shared@tenant.onmicrosoft.com",
"IsAllDay": false,
"WebLink": "https://outlook.office365.com/owa/?itemid..."
}
]Denied request:
Request
GET https://graph.microsoft.com/v1.0/users/other_mailbox@tenant.onmicrosoft.com/eventsExample JSON response body (denied)
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again."
}
}This confirms the RBAC enforcement is working as expected:
Only the permitted shared mailbox is accessible.
Summary
Exchange Online RBAC allows you to restrict your Azure function’s Microsoft Graph API access to a single mailbox.