How to find apps with high-privilege Graph permissions

Review every high-privilege application grant, remove what is unused and scope the rest.

Every Microsoft 365 security check · Privileged Access · NL-ACC-007

What this check looks at

Lists service principals granted application permissions that allow tenant-wide data access or privilege escalation.

Apps reach Microsoft 365 data in two ways. Delegated permissions act on behalf of a signed-in user and are limited to what that user can do. Application permissions let the app sign in as itself with a client secret or certificate and act across the whole tenant with nobody signed in. An app holding Mail.ReadWrite as an application permission can read and change every mailbox; Sites.FullControl.All covers every SharePoint site; RoleManagement.ReadWrite.Directory lets the app make itself, or anyone, a Global Administrator.

This check lists app registrations and service principals (other than this service’s own) holding a high-privilege application permission: Directory.ReadWrite.All, RoleManagement.ReadWrite.Directory, Application.ReadWrite.All, AppRoleAssignment.ReadWrite.All, Mail.ReadWrite, Mail.Send, Files.ReadWrite.All, Sites.FullControl.All, User.ReadWrite.All, Group.ReadWrite.All, Policy.ReadWrite.ConditionalAccess, PrivilegedAccess.ReadWrite.AzureAD, or Exchange’s full_access_as_app. Apps blocked from signing in are left out. The check fails when any app that can sign in holds one, and is critical when one can escalate to Global Administrator.

Application permissions sit outside the controls built for people: no MFA, no Conditional Access without Workload Identities licences, and no prompt anyone sees. Whoever obtains the app’s client secret, from a developer’s laptop, a script on a file share, a code repository or a breached vendor, can use those permissions from anywhere until the secret is removed. Attackers with admin rights also add their own secret to an existing trusted app to keep access after passwords are reset.

Why it matters

An application permission is standing, non-interactive access that no Conditional Access policy constrains. A single leaked client secret on an app holding Mail.ReadWrite reads every mailbox in the organisation, silently.

A typical case: a 90-person estate agency installed a CRM integration years ago that was granted Mail.ReadWrite and Mail.Send as application permissions, with a client secret kept in a configuration file on the vendor’s server. The vendor is breached; the attacker uses the secret to read every mailbox, including the conveyancing team’s, and sends convincing completion-funds emails from inside the firm. No sign-in alert fires, because no user signed in.

Narrowing access is usually simple: most integrations need one mailbox or a few sites, not the whole tenant. Exchange Online can restrict application permissions to named mailboxes, SharePoint offers Sites.Selected for named sites, and vendors usually document which permissions they really use.

CIS Controls v8 safeguard 5.5 asks for an inventory of service accounts, which in Microsoft 365 includes apps acting as themselves. ISO 27001 A.8.2 and A.5.15, the NCSC 10 Steps on identity and access management and on supply chain security, and the NCSC CAF supply chain and privileged user management outcomes all expect non-human and third-party access to be known, owned and limited.

How to fix it

Where: Entra admin centre → Identity → Applications → Enterprise applications → Permissions

Before you start

  • Identify the owner and purpose of each app in the evidence, and check which permissions it really uses (the vendor documentation usually says).

Step by step

  1. List the apps and what they hold. Take the applications and permissions from the evidence. In the Microsoft Entra admin centre, go to Entra ID > Enterprise apps > All applications (clear the application type filter), open each app and select Permissions under Security. The Admin consent tab shows the application permissions granted, with who granted them and when.
  2. Find the owner and purpose of each app. For each app, record the business owner, the vendor or developer and what it does (backup, CRM sync, scan to mailbox, reporting). Check Entra ID > Monitoring & health > Sign-in logs > Service principal sign-ins, filtered on the app, to see whether it is still used and from which IP addresses.
  3. Block apps that nobody owns. For an app with no owner or no recent use, open Enterprise apps > the app > Properties, set Enabled for users to sign in? to No and select Save. This stops it getting tokens while keeping its configuration. If nobody objects within a month, delete the enterprise application and, for in-house apps, the app registration.
  4. Remove permissions the app does not need. Compare each app’s permissions with the vendor’s documentation. On the app’s Permissions page, select an unneeded permission and choose Revoke permission, or in Microsoft Graph PowerShell list them with Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId <object id> and remove one with Remove-MgServicePrincipalAppRoleAssignment -ServicePrincipalId <object id> -AppRoleAssignmentId <assignment id>. Test the integration with its owner afterwards.
  5. Limit Exchange access to the mailboxes needed. For an app that needs mail permissions on only some mailboxes, create a mail-enabled security group containing just those mailboxes, then in Exchange Online PowerShell run New-ApplicationAccessPolicy -AppId <app id> -PolicyScopeGroupId <group address> -AccessRight RestrictAccess -Description "Scanner mailbox only", and check it with Test-ApplicationAccessPolicy -Identity <mailbox> -AppId <app id>. For new set-ups Microsoft recommends RBAC for Applications (New-ManagementScope and New-ManagementRoleAssignment -App) instead.
  6. Limit SharePoint access to the sites needed. For an app holding Sites.ReadWrite.All or Sites.FullControl.All that only needs a few sites, ask the vendor whether it supports Sites.Selected. If it does, grant Sites.Selected, give the app access to the named sites only (Microsoft Graph POST /sites/{site-id}/permissions, or Grant-PnPAzureADAppSitePermission in PnP PowerShell), then revoke the tenant-wide permission.
  7. Replace client secrets with certificates. For in-house apps, open Entra ID > App registrations > the app > Certificates & secrets, upload a certificate, change the integration to use it, then delete the client secrets. Add at least two named owners on the app’s Owners page so someone is responsible for it.
  8. Confirm what remains is agreed. Reopen each app’s Permissions page: only permissions agreed with its owner should remain, and apps that should not run show Enabled for users to sign in: No. The finding stays open while any enabled app holds one of these permissions; where one is genuinely needed, record the owner and the reason against the finding.

With PowerShell

New-ApplicationAccessPolicy -AppId <appId> -PolicyScopeGroupId <group> -AccessRight RestrictAccess

What users will notice

An app that loses a permission it needs will stop working for that feature, so test with the owner.

How to confirm it worked

Enterprise applications, the app, Permissions: only the permissions agreed with its owner remain.

Frameworks and controls

This check maps to controls in 14 frameworks. Passing it is evidence that the setting is in place, not a certification against any of them.

The frameworks and controls NL-ACC-007 maps to
FrameworkControl
NCSC CAFB2.c Privileged user managementA4.a Supply chain
DSPTStandard 10: Accountable suppliers
DORAArt. 28 Management of ICT third-party risk
NIS2Art. 21(2)(d) Supply chain security
Microsoft Cloud Security BenchmarkPA-7 Follow just enough administration (least privilege)IM-3 Manage application identities securely and automatically
Zero TrustApplications
SOC 2CC6.3 Role-based access and least privilege
PCI DSS 4.0.17.2.5 Application and system accounts are managed with least privilege
NIST SP 800-1713.1.5 Employ the principle of least privilege
CMMC Level 2AC.L2-3.1.5 Least Privilege
ISO 27001:2022A.8.2 Privileged access rightsA.5.15 Access control
CIS Controls v8.15.5 Establish and maintain an inventory of service accounts (IG2)
NIST CSF 2.0PR.AA-05: Access permissions, entitlements, and authorizations are defined in a policy, managed, enforced, and reviewed, and incorporate the principles of least privilege and separation of duties
NCSC 10 StepsIdentity and access managementSupply chain security

The framework mappings were last checked against the published standards in October 2026.

Microsoft’s documentation

The full Microsoft 365 security checklist, worst first

Check this in every tenant.

ConfigCheckup runs this check on every tenant you connect. Its fix is an approved change started from the Apps page. You see a dry run of exactly what will change, approve it, and can roll it back.

14 days of daily monitoring and alerts, every finding with its fix guide, and reports on up to 3 tenants, from your first connected tenant. No card. Then choose the plan that fits.Where this check fits: Microsoft 365 security assessment for MSPs