Auditing the OAuth permissions already granted in Entra ID
Restricting user consent protects the future. But permissions granted over the years, sometimes by users who have long since left, remain valid until someone revokes them. An audit of existing permissions almost always turns up surprises.
Two types of permission, two objects
In Entra ID, the rights granted to an application on an API such as Microsoft Graph come in two forms, stored in two different objects:
| Type | Object | Reach |
|---|---|---|
| Delegated permissions | OAuth2 permission grant (oauth2PermissionGrant) | The application acts on behalf of a signed-in user, within that user's own rights. |
| Application permissions | App role assignment (appRoleAssignment) | The application acts as itself, with no user, often across the whole tenant. |
Application permissions are usually the most powerful: Mail.Read as an application permission gives access to every mailbox in the organisation, unless explicitly restricted on the Exchange Online side.
Individual or organisation-wide consent
A delegated grant has a consent type. Principal means a user consented for themselves. AllPrincipals means an administrator consented on behalf of all users: the application can then act on behalf of any member of the tenant who signs in to it. These grants should be reviewed first.
The inventory is done with Microsoft Graph PowerShell, for example Get-MgOauth2PermissionGrant -All for delegated permissions and Get-MgServicePrincipalAppRoleAssignment for each service principal's application permissions. The portal shows the same information one application at a time, which quickly becomes tedious.
Spotting risky applications
Rank the results against a few criteria:
- Sensitive permissions: reading or writing mail, tenant-wide files, the directory, and above all permissions that manage roles or grant further permissions, such as
RoleManagement.ReadWrite.DirectoryorAppRoleAssignment.ReadWrite.All; - Publisher: internal application, verified publisher or unknown multi-tenant application;
- Activity: an application that has not signed in for months has no reason to keep its rights;
- Owner: an application with no identified owner will never be reviewed;
offline_access: combined with other permissions, it lets the application keep access without the user signing in again.
Illicit consent. An application with a misleading name, from an unknown publisher, holding mail read permissions consented by just a few users, should be handled as a potential incident rather than a simple hygiene issue.
Cleaning up
Removing permissions abruptly can break a business process. A gradual approach limits the risk:
- Identify the business owner and confirm the application is in use.
- For a suspicious application, first disable sign-in for the service principal: the change is reversible and quickly reveals dependencies.
- Remove unnecessary grants or assignments, for example with
Remove-MgOauth2PermissionGrant, then re-grant only what is needed. - If compromise is suspected, also revoke the affected users' sessions, since refresh tokens may still be valid.
- Delete applications with no use and no owner.
Keeping the problem from coming back
Restrict user consent to verified publishers and low-impact permissions, or turn it off, and enable the admin consent request workflow so that legitimate needs are handled. Then schedule a regular review, because new permissions appear with every integration.
What an audit checks
- A complete inventory of delegated and application permissions granted.
AllPrincipalsgrants and sensitive application permissions.- Third-party applications that are inactive, ownerless or from unverified publishers.
- User consent settings and the admin consent workflow.
- A periodic review and an alert on new consents.