Maximum number of API permissions for an Azure AD integrated app

While doing my monthly sweep over the various changelogs Microsoft publishes, the following item caught my attention:

Limits on the number of configured API permissions for an application registration will be enforced starting in October 2021

Type: Plan for change
Service category: Other
Product capability: Developer Experience

Occasionally, application developers configure their apps to require more permissions than it’s possible to grant. To prevent this from happening, we’re enforcing a limit on the total number of required permissions which can be configured for an app registration.

The total number of required permissions for any single application registration must not exceed 400 permissions, across all APIs. The change to enforce this limit will begin rolling out no sooner than mid-October 2021. Applications exceeding the limit can’t increase the number of permissions they’re configured for. The existing limit on the number of distinct APIs for which permissions are required remains unchanged and can’t exceed 50 APIs.

In the Azure portal, the required permissions are listed under Azure Active Directory > Application registrations > (select an application) > API permissions. Using Microsoft Graph or Microsoft Graph PowerShell, the required permissions are listed in the requiredResourceAccess property of an application entity. Learn more.

As this limit doesn’t seem to be referenced in the generic documentation just yet, I figured I’d put a quick article around it. For example, none of the articles that explain how to add permissions via the Azure AD blade seem to reference the changes. Apart from the aforementioned changelog page, you can find these limits in the description of the requiredResourceAccess property  of the application resource type page:

requiredResourceAccess requiredResourceAccess collection Specifies the resources that the application needs to access. This property also specifies the set of delegated permissions and application roles that it needs for each of those resources. This configuration of access to the required resources drives the consent experience. No more than 50 resource services (APIs) can be configured. Beginning mid-October 2021, the total number of required permissions must not exceed 400. Not nullable.

Supports $filter (eq, NOT, ge, le).

That should be sufficient evidence. As to why would anyone need that many permissions on a single app – it can happen. Sure, it’s far from a best practice, but given the number of entries you can currently select from across just the Graph API (285 + 225 at the time of writing), and the number of new permissions Microsoft continues to add, hitting the 400 mark is feasible. Plus, the 400 limit is cumulative across all the different APIs exposed.

If you still think 400 is too much, think of applications such as the Graph API explorer or the Microsoft Graph PowerShell module. Every time you use those for a quick test or a new task, chances are you’ll need to consent to yet another scope, and it quickly adds up. Remember that even with incremental consent, the token you get always contains all the permissions you’ve consented to. As the the total number of requested/consented permissions only grows over time, so will the number of effective permissions “contained” within a token. The only way to perform a “cleanup” of sorts is by manually removing grants, or scrapping the entire app/service principal object altogether.

And just in case you’re wondering how did I come up with the 285 number above – this represents the current number of entries found under the Oauth2Permissions property for the Graph API application within your tenant. So it’s not even all the permissions you can add, just the Delegate permission entries. Looking at the Application permission entries, 225 more can be found:

(Get-AzureADServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'").Oauth2Permissions | measure

(Get-AzureADServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'").AppRoles | measure

There’s nothing stopping you from adding both sets in their entirety, and thus hitting the 400 mark. Well, there is now 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.