ENow | AppGov Blog

How to Use Role-Based Access Control (RBAC) for Applications

Written by Louis Mastelinck | Mar 19, 2026 4:01:06 PM

In a previous blog post, 'How to Restrict Microsoft Graph API Access to Mailboxes,' we explained why scoping your app registration permissions in Microsoft Graph is critical. One approach we covered was Application Access Policies, but this method is now considered legacy. There's a better, modern alternative!

Role-Based Access Control (RBAC) for applications is now the preferred method to ensure Graph API permissions are properly scoped to only the resources your app needs.

Why Scope App Registration Permissions?

Without scoping, permissions granted to your app registration apply across your entire tenant by default. For example, assigning Calendars.Read would let your app read calendars from every user in your organization.

RBAC for applications lets you precisely limit these permissions to match your specific use case, whether that's a single department, meeting room accounts, or users within an Administrative Unit. This follows the principle of least privilege while maintaining full functionality.

The table below summarizes all permissions that can be scoped using Role-Based Access Control (RBAC) for applications.

Official Role Name

Graph Permissions

Description (summary)

Application Mail.Read

Mail.Read

Read email in all mailboxes

Application Mail.ReadBasic

Mail.ReadBasic

Read email metadata in all mailboxes

Application Mail.ReadWrite

Mail.ReadWrite

CRUD email in all mailboxes

Application Mail.Send

Mail.Send

Send mail as any user

Application MailboxSettings.Read

MailboxSettings.Read

Read mailbox settings

Application MailboxSettings.ReadWrite

MailboxSettings.ReadWrite

CRUD mailbox settings

Application Calendars.Read

Calendars.Read

Read all calendars

Application Calendars.ReadWrite

Calendars.ReadWrite

CRUD all calendars

Application Contacts.Read

Contacts.Read

Read all contacts

Application Contacts.ReadWrite

Contacts.ReadWrite

CRUD all contacts

Application MailboxFolder.Read

MailboxFolder.Read.All

Read all mailbox folders

Application MailboxFolder.ReadWrite

MailboxFolder.ReadWrite.All

Read/write all mailbox folders

Application MailboxItem.Read

MailboxItem.Read.All

Read all mailbox items

Application MailboxItem.ImportExport

MailboxItem.ImportExport.All

Import/export all mailbox items

Application Mail Full Access

Mail.ReadWrite, Mail.Send

Full mail access + send

Application Exchange Full Access

Multiple (mail, settings, calendars, contacts)

Full Exchange access learn.microsoft

 

How Does It Work?

Let's say we want to create an application that fully manages a meeting room's calendar, accepts booking invitations, and sends information to users from a specific mailbox.

To accomplish this, we need to grant the following permissions:

  • Mail.Send
  • Mail.ReadWrite
  • Calendars.ReadWrite

Creating the Service Principal

We'll start with the Enterprise Application that represents the app managing our meeting rooms. And noting down its appliation ID & Object ID.


Figure 1: screenshot of Enterprise app that will be used

Important: No Graph API permissions should be configured on the app registration itself. Permission handling happens later via Exchange Online RBAC—no Graph API permissions are needed during registration.

Now let's connect to Exchange Online and create a new service principal reference. This is needed because Exchange Online requires its own reference that points to our service principal in Entra ID.

New-ServicePrincipal -AppId "<Client Application ID in AAD #1>" -ObjectId "<Service Principal Object ID in AAD #2>" -DisplayName "<name>"

In my tenant, the commands looks like the following:
New-ServicePrincipal -AppId "655b8bb7-f1b8-4c8a-a6e7-d2db3b13976e" ObjectId "448c27e3-36c0-4685-826b-f9767ceaecf6" -DisplayName "Lousec-Enow-RBACdemo"


Figure 2: screenshot that shows successful creation of Service Principle

Who do we apply the permissions to?

In this step, we define which accounts our application will have permissions over. There are two common ways to achieve this:

Management scopes:

These allow you to define permissions based on object attributes such as region, department, or other organizational properties. This enables you to dynamically control access based on user or device characteristics.

Administrative units:

Think of these as logical containers within Microsoft Entra ID. By assigning users or groups to an administrative unit (AU), you can scope your application’s permissions specifically to that unit, creating a clear and manageable boundary for delegated access.

In this example, I’ll base the configuration on an administrative unit. I created an administrative unit and added a single user object representing the meeting room account that my application will have permissions on.

Figure 3: screenshot of Adminstrative Unit used for scoping the permissions

Before we can scope our management role to this administrative unit, we need to know its ID. There are two ways to find it, one is by checking the Properties view of your administrative unit in the Entra portal.


Figure 4: screenshot of where to find the AU object id in the portal

Or if you run Get-AdministrativeUnite and look for the AU that you created.


Figure 5: Figure 4: screenshot of where to find the AU object id via powershell

Now we’re going to assign the management role and its associated permissions to our Administrative Unit. The basic structure of a management role assignment command is as follows:

New-ManagementRoleAssignment `

-Name "<Name>" `
-App "<AppID>" `
-Role "<RoleName>" `
-RecipientAdministrativeUnitScope "<AdministrativeUnitID>"

Let’s break down each parameter:

  • Name: A descriptive name for the management role assignment. This helps identify the purpose or linked application (e.g., 'Lousec-Enow-RBACdemo-MailSend').
  • App: The Application (Client) ID of the registered app to which you’re assigning the role.
  • Role: The specific permission or management role the app will receive — in this case, 'Application Mail.Send'.
  • RecipientAdministrativeUnitScope: Defines the scope of the role assignment by linking it to a specific Administrative Unit ID. This ensures the app’s permissions apply only within that unit.

Putting it together, the command looks as following:

New-ManagementRoleAssignment `

-Name 'Lousec-Enow-RBACdemo-MailSend' `

-App '448c27e3-36c0-4685-826b-f9767ceaecf6' `

-Role 'Application Mail.Send' `

-RecipientAdministrativeUnitScope 'f559b0aa-0753-4b56-93d1-fc615763bea7'

It’s important to note that you can only add one permission at a time. This means that if you want to assign both Mail.ReadWrite and Calendars.ReadWrite, you’ll need to run the command separately for each permission.

For Mail.readWrite we execute:

New-ManagementRoleAssignment -Name 'Lousec-Enow-RBACdemo-MailReadWrite' -App '448c27e3-36c0-4685-826b-f9767ceaecf6' -Role 'Application Mail.ReadWrite' -RecipientAdministrativeUnitScope 'f559b0aa-0753-4b56-93d1-fc615763bea7'

 

And for Calanders.ReadWrite we execute:

New-ManagementRoleAssignment -Name 'Lousec-Enow-RBACdemo-CalendarsReadWrite' -App '448c27e3-36c0-4685-826b-f9767ceaecf6' -Role 'Application Calendars.ReadWrite' -RecipientAdministrativeUnitScope 'f559b0aa-0753-4b56-93d1-fc615763bea7'

 

If we now want to see which permissions have been granted, we can summarize them using the following command:

Get-ManagementRoleAssignment -RoleAssignee "Lousec-Enow-RBACdemo" | Select-Object Role, RoleAssignee, RecipientWriteScope, CustomResourceScope | Format-Table –AutoSize

 


Figure 6: Screenshot of command that shows all applied permissions

Summarizing the steps

Using role-based access control (RBAC) for applications is now the recommended approach for scoping Graph API permissions to only the specific resources your application needs access to. In order to achieve these, we have followed these steps:

  1. Identify the Enterprise Application representing your application that will execute tasks. Note down its Application ID (AppId) and Object ID (service principal Object ID).
  2. Connect to Exchange Online PowerShell and create a reference service principal that points to your Enterprise Application
  3. Choose your scoping method:
    1. Management scopes filter permissions based on object attributes (region, department, etc.)
    2. Administrative Units (AUs) act as containers where you add specific objects (users, groups) to scope access, we used this method in this blog post.
  4. Assign management roles per permission to your service principal using New-ManagementRoleAssignment, scoped to your AU per permission or management scope.
  5. It's always good to verify that all role assignments were created successfully. This will also come in handy later when you need to revisit this setup.

Using these steps, you ensure that tenant-wide permissions are properly scoped to only the resources your application actually needs access to.

Even with RBAC in place  for applications, many Entra ID environments still lack clear visibility into how broadly permissions are actually scoped, or how many applications remain overprivileged.

 

That gap becomes more obvious in larger tenants, where hundreds of enterprise applications and service principals accumulate over time, often without consistent ownership or periodic review.

 

ENow’s App Governance Accelerator Platform helps you quickly assess how well your Entra ID environment aligns with least privilege principles, highlighting risky permissions, unused applications, and governance gaps that are easy to miss during manual reviews.

 

Start by measuring where you stand for free with AppGov Score, then prioritize the changes that reduce risk and improve control.