Scope App Permissions for Secure Automation using Microsoft Azure Active Directory

Marcus Carvalho

Service or daemon apps automate tasks, integrate systems, and secure interactions between apps. They’re used for batch processing, data integration, resource provisioning, and managing cloud-based resources at scale. In DevOps, they can deploy infrastructure as code, test and assure quality, and monitor system performance. This article will cover some of the best practices to implement least privilege principle for this type of apps using Microsoft Azure Active Directory.

Azure AD uses service principals to authenticate and access resources. Service principals enable an app to access specific resources in Azure, Microsoft Graph, or REST APIs. Over-permissioned service principals can lead to unauthorized access to resources. To avoid this, it’s important to configure them carefully with appropriate, minimum required permissions, so they don’t have too much access.

Application only access

An application in Azure AD represents a web API or web application that needs access to resources, while a service principal represents the identity of that application, which is used to authenticate and authorize the application to access those resources. By using service principals, developers can control the access to resources and ensure that only authorized applications have access. Service principals are visible in the Enterprise applications blade in the Microsoft Entra admin center.

Quickstart: Register an application with the Microsoft identity platform

Applications designed to run in the background without any user interaction, don’t carry user context. This means that they can perform tasks and automate processes without requiring any direct input from users. Instead, they operate based on a predefined set of rules and permissions.

The below graphic illustrates an application requesting and obtaining a token in order to access a secured resource.

app only permissions

Access tokens

In both OpenID Connect and OAuth2, an access token is issued by an authorization server, such as Azure AD, after the user has granted authorization to the application. The application can then use the access token to make requests to the protected resources until the token expires or is revoked.

Because the scenario does not involve user authentication or authorization, this type of application most likely uses the OAuth2 client credential flow. The application itself is authenticated and authorized to access protected resources. The access token represents the application’s credentials and is used to access protected resources that the application is authorized to access.

NOTE: In Azure AD, client credentials requests from your application must include scope={resource}/.default. Where {resource} is the web API that your app intends to call and wishes to obtain an access token for.

In this post we’ll use PowerShell MSAL.PS and the Microsoft Graph SDK, you can also use the Microsoft Authentication Library (MSAL) to acquire security tokens from the Microsoft identity platform, it supports many different platforms including .NET, Node.JS, Java and Python.

Go ahead, register a new application and add a new client secret to it. The following code sample requests an access token for Microsoft Graph:

Import-Module MSAL.PS

$tenantId = "<TenantId>"   # tenantID (Azure Directory ID) were AppSP resides
$clientId = "<ClientId>"   # AppID also ClientID for AppSP     
$clientSecret = (ConvertTo-SecureString "<ClientSecret>" -AsPlainText -Force)   # Client secret for AppSP 

$scopes = "https://graph.microsoft.com/.default"

$result = Get-MsalToken -ClientId $clientId `
             -ClientSecret $clientSecret `
             -TenantId $tenantId `
             -Scopes $scopes
$result.AccessToken

Permissions

In Azure AD, you can create app roles and give them to users and other apps. These roles decide what the users or apps can access in your app. When a user or app gets an access token, the token contains the roles that are assigned to them. If another app, like a web API, receives this access token, it can decide what actions are allowed based on the roles in the token.

There are scenarios where the resource app needs to decide and use application-specific permissions. This can be achieved using different methods like groups and custom data stores.

Microsoft Graph least privilege

Overly permissive permissions can also lead to privilege escalation attacks, allowing attackers to gain higher privileges than intended. Implementing proper RBAC and following the least privilege principle is crucial to mitigate this risk.

Microsoft Graph application permissions, also known as app roles, control what actions an app can perform when accessing Microsoft Graph resources. Because app permissions enable the app to access resources or perform operations, regardless of which user is currently logged to the app, always choose the least permissive permission required to perform the API calls your app needs.

Microsoft Graph permissions use the format Resource.Operation.Constraint, enabling the application to access any data that the permission is associated with. For example, an application granted the application permission User.ReadWrite.All will be able to write attributes for all users.

NOTE: For apps that access resources and APIs without a signed-in user, the application permissions need to be consented to by an administrator when the app is installed in the tenant or in the Azure portal.

This authorization method may not fit some scenarios, and may be seen as too permissive. Remember, apart from assigning app roles, an app may also be granted privileges under other conditions allowing more granular permissions. The applications behind Microsoft Graph implement additional methods that help to fine tune your app permissions.

Azure Active Directory permission scoping

When you register a new application in Azure AD, it won’t have any “app only permissions” configured by default. You can confirm that by checking the access token you requested in the previous code sample, decode it by pasting its content into jwt.ms – the role claim shouldn’t be present in the token.

Let’s try something using that access token. First find the object ID of your application and service principal (under Enterprise applications) using the Microsoft Entra admin center.

Connect-Graph -AccessToken $result.AccessToken

$appId = "<application object Id>"  
$principalId = "<service principal object Id>"  

Get-MgApplication –ApplicationId $appId
Get-MgServicePrincipal –ServicePrincipalId $principalId

# This one fails with "Insufficient privileges to complete the operation."
# The same happen with other Graph calls like Get-MgUser
Get-MgApplication

This reveals to us that the service principal already has a limited set of permissions. In fact, we can manage service principal permissions in Azure AD using other approaches:

Assign the service principal to the User Administrator role using the Microsoft Entra admin center and try it again.

$result = Get-MsalToken -ClientId $clientId `
              -ClientSecret $clientSecret `
              -TenantId $tenantId `
              -Scopes $scopes  `
              -ForceRefresh
Connect-Graph -AccessToken $result.AccessToken

# Which one these does work?
Get-MgApplication
Get-MgUser
Get-MgGroup

If you want to understand how these commands work, check the link above or look for the role Description inside the Microsoft Entra admin center. In case you need a custom set of permissions for your application, you can create custom administrative roles and if you want to restrict the permissions to a subset of directory objects, like users and groups, you can assign the role to an Administrative unit.

IMPORTANT: when using multiple authorization methods, the resulting set of permissions combines everything that is granted – the most permissive wins!

Exchange Online permission scoping

Exchange Online uses a mixed approach to scope the permissions to specific mailboxes. The Azure AD administrator still needs to grant application permissions using the app registration, then the Exchange Online administrator limits app access to specific mailboxes using an application access policy. The following Microsoft Graph permissions can be scoped:

  • Mail
  • MailboxSettings
  • Calendars
  • Contacts

Limiting application permissions to specific Exchange Online mailboxes

SharePoint Online permission scoping

For SharePoint Online, a special permission was added to Microsoft Graph, Sites.Selected allows the application to access a subset of site collections without a signed in user. Additionally, the administrator uses the site permissions endpoint to grant Read, Write, or Read and Write permissions to the application.

Controlling app access on a specific SharePoint site collections is now available in Microsoft Graph

Teams permission scoping

In Teams, scoping is based on the Resource-specific consent (RSC) authorization framework. It allows fine-grained data access to Teams, chats, and meetings. An authorized user can give app access to specific resources without doing it for the entire tenant.

Resource-specific consent for your Teams app

Summary

To mitigate app permission risks, it’s important to follow best practices for securing service principals, such as implementing proper RBAC, using least privilege principles, securely managing credentials, monitoring and auditing service principal activity, and regularly reviewing and revoking unnecessary service principals.

Additional references:

Understanding application-only access

Microsoft identity platform access tokens

Scopes and permissions in the Microsoft identity platform: The .default scope

0 comments

Discussion is closed.

Feedback usabilla icon