RBAC for Applications – Least Privilege When Sending Email via the Graph API

A while ago I received a question from a Power Platform team. They were building a Power App and wanted to add email functionality to it. To send emails from the app, they wanted to call the Microsoft Graph API. For this purpose, they had created an App Registration in Entra ID. The question was simple: what permissions do we need to assign to this App Registration?

At first glance, this seems like a straightforward question, but from a security perspective this is exactly the moment where you need to pause and think. In practice, I regularly see overly broad permissions being granted, simply because it’s “easier” or because it just works. And that is exactly where things go wrong.

What is RBAC?

RBAC stands for Role-Based Access Control. The principle is simple: you assign permissions based on the role that a user or application has, and nothing more than strictly necessary. Instead of assigning permissions directly to individual users or applications, rights are bundled into roles. You then assign the appropriate role to the appropriate identity.

This principle has been around for a long time in the world of user management — think of roles in Entra ID like Global Administrator or Security Reader. But RBAC is not only applicable to users. Applications also have an identity, and for applications the same applies: you need to think carefully about what permissions you grant.

And that is exactly where things often go wrong in practice. An application that performs one specific task — such as sending an email — has no need for broad permissions. Yet in practice this is regularly configured that way, simply because it “works” or because it’s faster to set up. The question from the Power Platform team is a perfect example of this.

Two Types of Permissions in the Graph API

Before we dive into the solution, it’s important to understand the distinction between the two types of permissions in the Microsoft Graph API.

Delegated permissions – The application acts on behalf of a signed-in user. The effective permissions are the combination of the app’s permissions and the user’s permissions. This is suitable for scenarios where a user is actively involved.

Application permissions – The application acts without a user being involved. The app has the permissions you grant, regardless of which user may be interacting with it. This is the scenario that applies to the Power App.

For sending email via Application permissions, the Graph API has the Mail.Send permission. Sounds like exactly what you need — but this is where the catch lies. With Mail.Send as an Application permission, the application can send emails on behalf of any user in the entire tenant. That is an enormous attack surface for an app that only needs to send from a single mailbox.

The Recommended Approach: RBAC for Applications in Exchange Online

Microsoft has a more elegant and secure solution for this: RBAC for Applications in Exchange Online. This is the newest and most secure way to grant an application least privilege access to a mailbox. Instead of a broad Graph API permission in Entra ID, you grant the app access via Exchange Online to one specific mailbox — nothing more.

The key benefit: the app does not receive a tenant-wide Mail.Send permission in Entra ID. Access is fully scoped to the mailbox you specify.

For this use case, a dedicated shared mailbox — such as noreply@yourorganisation.com — is the recommended choice. A shared mailbox requires no Exchange license, has no interactive sign-in, and keeps the attack surface as small as possible. It is purpose-built for exactly this kind of automated sending scenario.

Before running the script below, make sure the account performing the configuration has the Organization Management role group in Exchange Online, or the Exchange Administrator role in Entra ID. Without these permissions, the New-ServicePrincipal step will fail.

Import-Module ExchangeOnlineManagement
Connect-MgGraph -Scopes 'Application.Read.All'
Connect-ExchangeOnline
# Find the Service Principal of your App Registration
$entraSP = Get-MgServicePrincipal -Filter "DisplayName eq 'YourAppName'"
# Register the Service Principal in Exchange Online
New-ServicePrincipal -AppId $entraSP.AppId -ObjectId $entraSP.Id -DisplayName $entraSP.DisplayName
# Find the mailbox you want to use (or create a new shared mailbox)
$mailbox = Get-Mailbox noreply@yourorganisation.com
# Create an RBAC scope referencing only this mailbox
New-ManagementScope -Name "rbac_YourApp" -RecipientRestrictionFilter "GUID -eq '$($mailbox.GUID)'"
# Assign the Mail.Send role, scoped to only this mailbox
New-ManagementRoleAssignment -App $entraSP.AppId -Role "Application Mail.Send" -CustomResourceScope "rbac_YourApp" -Name "YourApp Send Mail RBAC"
# Verify that access is configured correctly
Test-ServicePrincipalAuthorization $entraSP.AppId -Resource $mailbox

Important: Make sure the App Registration in Entra ID has not been granted the Mail.Send Application permission. RBAC and Graph permissions coexist side by side. If you have both configured, the app will still have tenant-wide access through the Graph permission — and that is exactly what you want to prevent.

A Note on Managed Identity

For Power Platform scenarios specifically, it is worth considering a Managed Identity instead of an App Registration with a client secret. RBAC for Applications works with Managed Identities just as well as with App Registrations — and the key advantage is that there is no client secret involved at all. No secret means no secret that can leak, expire, or be forgotten in a pipeline.

Whether a Managed Identity is feasible depends on how your Power App calls the Graph API — for example via an Azure Function or a custom connector. But if it is an option in your architecture, it is the cleaner choice from a least privilege and secrets management perspective.

What About Application Access Policy?

You may have come across Application Access Policy in Exchange Online as a way to restrict the scope of a Mail.Send Graph permission to a specific mailbox. This approach works, and it is better than leaving the permission unrestricted — but it is important to know that Microsoft has positioned this feature as legacy.

Application Access Policies have been superseded by RBAC for Applications, and Microsoft has indicated that a deprecation announcement is coming that will require migration. If you have existing configurations based on Application Access Policies, now is a good time to plan the migration to RBAC for Applications. For new configurations, RBAC for Applications is the only recommended path.

Least Privilege in Practice

Both methods illustrate the same principle: Least Privilege. Never grant an application more permissions than strictly necessary for the function it needs to perform.

A few practical takeaways to close with:

Use RBAC for Applications in Exchange Online when you want to give an application scoped access to a mailbox — this is the most secure and recommended approach. Use a dedicated shared mailbox as the sending identity to keep the scope clean and avoid licensing overhead. Consider a Managed Identity where your architecture allows it, to eliminate client secret risk entirely. If you have existing configurations using an Application Access Policy, plan a migration to RBAC for Applications before deprecation is enforced. Periodically review the API permissions of your App Registrations in Entra ID and remove permissions that are no longer needed. And document why certain permissions were granted, so that future reviews are easier.

The question from the Power Platform team was a good reminder: the choice of which permissions you assign to an App Registration has a direct impact on the security of your environment. By consciously choosing the most restricted option — and understanding which features are current versus legacy — you significantly reduce the risk in the event of misuse or a leaked client secret.

Comments

Leave a Reply

Discover more from Something Technical

Subscribe now to keep reading and get access to the full archive.

Continue reading