By default every user in a Microsoft Entra ID tenant can grant a third-party application delegated access to their own data, and each grant becomes a service principal with tokens that outlive password resets. Restricting user consent is one of the few identity changes that removes a whole attack class, illicit consent grants, at the cost of a single policy setting. This runbook takes you through it in the order that avoids helpdesk pain: measure what users consent to today, classify low-impact permissions, switch the policy, give users an admin consent request path, then deal with the grants that already exist. It covers the admin centre, Microsoft Graph PowerShell and the Graph REST API, with rollback for each change. It is for Entra administrators and identity security teams. The attack itself is covered in the Consent Phishing and Illicit OAuth Grants Guide, and platform background in the Entra ID Applications and Consent Guide.
This is an independent guide from NHI Mgmt Group, based on Microsoft's public documentation as of November 2026. It is not sponsored or reviewed by Microsoft. Product features change, so confirm settings against Microsoft's current documentation.
Key takeaways
- The default is permissive. Microsoft documents that by default all users can consent to permissions that do not require administrator consent, for example an app reading their own mailbox, and recommends allowing user consent only for apps from verified publishers.
- One property controls it. User consent is governed by
permissionGrantPoliciesAssignedon the tenant authorisation policy. An entry of the formmanagePermissionGrantsForSelf.{id}allows consent under that policy; no such entry means user consent is off. - Classify before you switch. The built-in policy
microsoft-user-default-lowonly lets users consent to permissions you have classified as low impact, so an empty classification list makes it behave almost like "disabled". - Restriction needs a request path. Turn on the admin consent workflow at the same time, or users hit a dead end and look for workarounds.
- Old grants stay. Changing the policy only affects future consents. Existing delegated grants must be exported, reviewed and revoked separately, and revocation alone does not stop a user consenting again.
When you need this
- Tenant still on the legacy setting: the policy
microsoft-user-default-legacy("Allow user consent for apps") lets any user consent to any permission that does not need admin consent, for any application. - After a consent phishing incident or an alert on an unknown enterprise application holding mail or file permissions. Revoke the grant first, then fix the setting so it cannot recur.
- Shadow AI and SaaS sprawl: users connecting AI assistants, note takers and browser tools to mail, calendar and files. Every connection is a long-lived grant. See the SaaS and OAuth App Governance Guide.
- Audit findings: configuration benchmarks and assessments commonly flag unrestricted user consent as a finding against least privilege (NIST SP 800-53 AC-6).
Before you start
| Task | Role needed (per Microsoft Learn) | Graph scopes |
|---|---|---|
| Read current consent settings | Any reader of the policy | Policy.Read.All |
| Change user consent settings | Privileged Role Administrator (Global Administrator if using the admin centre) | Policy.ReadWrite.Authorization |
| Classify permissions | Cloud Application Administrator or Application Administrator | Policy.ReadWrite.PermissionGrant, Application.Read.All |
| Create custom app consent policies | Privileged Role Administrator or a custom role with consent policy permissions | Policy.ReadWrite.PermissionGrant |
| Enable admin consent workflow | Global Administrator | Graph adminConsentRequestPolicy update |
| Review and revoke existing grants | Cloud Application Administrator or Application Administrator | DelegatedPermissionGrant.ReadWrite.All, AppRoleAssignment.ReadWrite.All, Application.ReadWrite.All |
- Tooling: the Microsoft Graph PowerShell SDK (the consent policy cmdlets are in
Microsoft.Graph.Identity.SignIns) or Graph Explorer. Use a privileged access workstation and activate roles just in time where you have PIM. - Reviewers: agree a reviewer group for consent requests before the change. Reviewers must already hold rights to grant the consent they approve; being named a reviewer does not elevate anyone.
- Communication: tell users what will change: they will see a "request approval" prompt instead of an accept button for most apps.
- Baseline: you will save the current authorisation policy JSON in step 1. That file is your rollback.
Step-by-step
Steps 1 to 3 are read-only. Steps 4 to 7 change tenant configuration and are reversible. Step 8 revokes grants, which is reversible only by re-granting.
- Capture the current setting. Read the authorisation policy with Graph:
GET https://graph.microsoft.com/v1.0/policies/authorizationPolicy/authorizationPolicyand save the full response. Note every value indefaultUserRolePermissions.permissionGrantPoliciesAssigned. A value endingmicrosoft-user-default-legacymeans users can consent to any app;microsoft-user-default-lowmeans verified publishers and low-impact permissions only; nomanagePermissionGrantsForSelf.*entry means user consent is already disabled. Also record anymanagePermissionGrantsForOwnedResource.*entries such asManagePermissionGrantsForOwnedResource.DeveloperConsent: every update replaces the whole collection, so you must carry these forward. - Measure what users consent to today. Export all delegated grants with
Get-MgOauth2PermissionGrant -Alland group them byClientId(the app) and scope. Grants with consent typePrincipalwere given by an individual user;AllPrincipalsgrants were given by an administrator for everyone. The user-granted apps and scopes are what your new policy must either allow or route to review. Search the audit log for activityConsent to applicationover the last 30 to 90 days to see the rate of new consents and which users make them. - Check risk-based step-up consent is on. It is enabled by default and steps risky requests (Microsoft cites newly registered multitenant apps that are not publisher verified and ask for non-basic permissions) up to admin consent. It is controlled by
BlockUserConsentForRiskyAppsin the "Consent Policy Settings" directory setting; confirm nobody set it toFalse. Audit entries with status reasonRisky application detectedshow what it has caught. - Classify low-impact permissions. In the admin centre go to Entra ID > Enterprise apps > Consent and permissions > Permission classifications, choose the Low tab, select Add permissions, pick Microsoft Graph and add the minimum sign-in set Microsoft uses as its example:
openid,profile,emailandoffline_access. AddUser.Readonly if you accept apps reading the signed-in user's profile. With PowerShell, find the Microsoft Graph service principal (Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'"), pick the scope fromOauth2PermissionScopes, and callNew-MgServicePrincipalDelegatedPermissionClassificationwithPermissionId,PermissionNameandClassification = "Low". Only delegated permissions that do not require admin consent can be classified. Keep mail, files, calendar, chat and anything ending in.Allout of the low list. - Turn on the admin consent workflow. Go to Enterprise apps > Consent and permissions > Admin consent settings, set "Users can request admin consent to apps they are unable to consent to" to Yes, choose reviewers (a group or role), enable email notifications and expiry reminders, and set "Consent request expires after (days)". Save. Microsoft notes the workflow can take up to an hour to become active, so do this before step 6.
- Restrict user consent. Choose one of three end states (see the decision table below). In the admin centre: Enterprise apps > Consent and permissions > User consent settings, select the option and Save. With Graph PowerShell, connect with
Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"and callUpdate-MgPolicyAuthorizationPolicy -BodyParameter $body, where$bodysetspermissionGrantPolicyIdsAssignedToDefaultUserRoletomanagePermissionGrantsForSelf.microsoft-user-default-lowplus themanagePermissionGrantsForOwnedResource.*values you captured. To disable user consent entirely, send only themanagePermissionGrantsForOwnedResource.*values. The REST equivalent isPATCH https://graph.microsoft.com/v1.0/policies/authorizationPolicywithdefaultUserRolePermissions.permissionGrantPoliciesAssignedset the same way. - Optional: build a custom app consent policy. If the built-in low policy is too broad or too narrow, create one with
New-MgPolicyPermissionGrantPolicy, add an include set withNew-MgPolicyPermissionGrantPolicyInclude -PermissionType "delegated" -PermissionClassification "low" -ClientApplicationsFromVerifiedPublisherOnly, and add exclude sets, for example for a resource API withNew-MgPolicyPermissionGrantPolicyExclude -ResourceApplication <appId>. A request is approved only if it matches at least one include set and no exclude set. Assign it withmanagePermissionGrantsForSelf.<your-policy-id>in step 6. - Review existing grants and revoke what you would not approve today. Using the export from step 2, list apps with user grants for high-impact scopes. For each app to remove: in the admin centre, Enterprise apps > All applications > app > Permissions shows admin and user consent tabs, but user consent grants cannot be revoked in the portal. Use
Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId <id>for delegated grants and remove application permissions via the app role assignment cmdlets. Then disable sign-in for the enterprise app or set it to require user assignment, because revoking grants does not stop a user consenting again if policy still allows it.
Which end state to choose
| Setting | Policy ID assigned | What users can do | Fits | Trade-off |
|---|---|---|---|---|
| Allow user consent for apps (legacy) | managePermissionGrantsForSelf.microsoft-user-default-legacy | Consent to any permission not requiring admin consent, for any app | Nowhere you care about data in mailboxes or files | Every user can create a durable grant to an unknown publisher |
| Verified publishers or your organisation, for selected permissions | managePermissionGrantsForSelf.microsoft-user-default-low | Consent only to apps from verified publishers or your own tenant, and only to low-classified permissions | Most organisations; Microsoft's recommended direction | Only as tight as your classification list; publisher verification is not a security review |
| Custom app consent policy | managePermissionGrantsForSelf.<custom-id> | Whatever the include and exclude sets allow | Large tenants with specific APIs or app sets to exclude | More to maintain; deleted policies cannot be restored |
| Do not allow user consent | No managePermissionGrantsForSelf.* entry | Request approval through the admin consent workflow | Regulated environments, small tenants, executives' tenants | Request volume lands on reviewers; slow approval drives shadow IT |
Small versus large tenants: a tenant of a few hundred users with a short list of approved SaaS can usually disable user consent outright and pre-approve the known apps with admin consent, since the request queue stays small. A large enterprise with thousands of users and a long tail of productivity tools is better served by the low-impact policy plus the workflow, with a named reviewer rota and a service level (for example two working days) so requests do not pile up. In both cases, decide ownership of the queue before the change, not after the first complaint.
Verify it worked
- Policy state: re-run the GET from step 1.
permissionGrantPoliciesAssignedshould contain your chosenmanagePermissionGrantsForSelf.*value (or none) and the owned-resource values you carried over. - User test: with a pilot account, sign in to a test app that requests a scope outside the low list. The user should see a request-approval prompt if the workflow is on. Without the workflow Microsoft documents error
AADSTS90094("needs permission to access resources in your organization that only an admin can grant"). - Reviewer test: confirm the request appears for reviewers under My Pending and that approval and denial emails reach the requester.
- Audit trail: the change to the authorisation policy and every subsequent
Consent to applicationevent should be in your SIEM. Microsoft notes audit entries can take time to appear, so do not judge success by the portal view alone.
What to monitor afterwards
| Signal | Where | Why it matters |
|---|---|---|
Activity Consent to application with IsAdminConsent true | Entra audit log, category ApplicationManagement | Admin consents are now the main path; each should map to an approved request |
Status reason Risky application detected | Entra audit log | Users attempting consent to risky apps; candidates for blocking |
| Update to authorisation policy | Entra audit log, directory policy changes | Someone reverting consent settings is a high-severity change |
New Principal grants with high-impact scopes | Scheduled Get-MgOauth2PermissionGrant export | Should be zero after restriction; any appearance means a policy gap |
| Expired or denied consent requests | Admin consent requests view | A rising count signals reviewers are not keeping up |
Metrics that show it is working
- Share of user-consent grants (consent type Principal) issued under the new policy that contain only low-classified scopes: target 100%.
- Number of third-party apps holding user grants to mail, files or calendar scopes, month on month: falling.
- Median time from consent request to decision: within your agreed service level.
- Percentage of consent requests that expire unanswered: close to zero.
- Number of unauthorised changes to the authorisation policy: zero.
Rollback and common errors
- Rollback of the policy change: re-apply the
permissionGrantPoliciesAssignedvalues from the step 1 export with the same PATCH orUpdate-MgPolicyAuthorizationPolicycall. The change takes effect for new consents only; existing grants were never touched. - Rollback of a classification: remove it with
Remove-MgServicePrincipalDelegatedPermissionClassificationusing the classification's own ID, not the permission ID. - Rollback of a revocation: Microsoft documents a procedure to restore revoked permissions; otherwise an administrator grants consent again for the app.
- Error: dropping owned-resource policies. Sending only the new
managePermissionGrantsForSelfvalue removesManagePermissionGrantsForOwnedResource.*entries and changes what developers can do with their own apps. Always send the full collection. - Error: low policy with an empty classification list. Users then cannot consent to anything and every app goes to the workflow, which looks like a full block nobody planned for.
- Error: classifying broad scopes as low. Putting
Mail.ReadorFiles.Read.Allin the low list recreates the risk with extra steps. The low list is a security decision, not a convenience list. - Error: treating verified publisher as approval. Publisher verification confirms who registered the app, not what it does with data. Attackers have abused verified partner accounts before, so review high-impact requests whatever the badge says.
- Error: forgetting group and Teams consent. Group-specific consent is governed by separate settings (
EnableGroupSpecificConsentin the consent policy directory setting, and Teams resource-specific consent policies). Review them in the same change. - Error: no reviewer for application permissions. Only Global Administrators can approve requests for Microsoft Graph application permissions, so a reviewer group without one will block those requests indefinitely.
Hardening afterwards
- Require user assignment on sensitive enterprise apps so that even after tenant-wide admin consent only assigned users and groups can sign in.
- Restrict app registration: the same
defaultUserRolePermissionsobject holdsallowedToCreateApps("Users can register applications"). Setting it to false stops users creating app registrations that you then have to consent to and govern. - Review admin consents on a schedule: admin grants with consent type AllPrincipals cover every user's data. Review them quarterly with the app owner, and remove high-privilege Graph application permissions that are no longer needed. See How to find high-privilege Microsoft Graph application permissions.
- Clean up the long tail: apps with no sign-ins for 90 days should lose their grants and then be removed. See How to find and remove stale service principals in Entra ID.
- Cover mail-specific risk: apps holding mail permissions deserve their own review. See How to review Microsoft 365 app registrations with mail permissions.
Framework mapping
| Framework | Reference | How this runbook supports it |
|---|---|---|
| NIST CSF 2.0 | PR.AA-05 | Consent permissions defined in policy, enforced and reviewed with least privilege |
| NIST CSF 2.0 | DE.CM-03 | Monitoring consent activity and policy changes |
| NIST SP 800-53 Rev 5 | AC-6 Least Privilege; AC-2 Account Management | Users cannot grant broad delegated access; app identities are approved and reviewed |
| NIST SP 800-53 Rev 5 | CM-7 Least Functionality; AU-6 Audit Record Review | Unneeded consent capability removed; consent audit events reviewed |
| MITRE ATT&CK v20 | T1566.002 Spearphishing Link; T1528 Steal Application Access Token | Breaks the consent phishing chain at the grant |
| MITRE ATT&CK v20 | T1550.001 Application Access Token; T1098.003 Additional Cloud Roles | Fewer tokens to abuse; admin grants monitored for persistence |
Practitioner checklist
- Export the authorisation policy and record every
permissionGrantPoliciesAssignedvalue before any change. - Export all delegated grants and identify user-granted apps with high-impact scopes.
- Confirm risk-based step-up consent (
BlockUserConsentForRiskyApps) is still on. - Classify only the minimum sign-in scopes as low impact; document the list and its owner.
- Enable the admin consent workflow with a reviewer group that includes someone able to approve Graph application permissions.
- Switch to
microsoft-user-default-low, a custom policy, or disabled, carrying forward owned-resource policies. - Test with a pilot user and confirm the request reaches reviewers.
- Revoke grants you would not approve today, then block re-consent with user assignment or disabled sign-in.
- Alert on changes to the authorisation policy and on admin consents without a matching request.
- Restrict app registration by users if there is no business need.
Standards and references
- Microsoft Learn: Configure how users consent to applications
- Microsoft Learn: Configure permission classifications
- Microsoft Learn: Configure the admin consent workflow
- Microsoft Learn: Manage app consent policies
- Microsoft Learn: Review permissions granted to enterprise applications
- Microsoft Learn: Configure risk-based step-up consent
- Microsoft Graph: defaultUserRolePermissions resource type
- MITRE ATT&CK: T1528 Steal Application Access Token
Related NHI Mgmt Group resources: Consent Phishing and Illicit OAuth Grants Guide, Entra ID Applications and Consent Guide, SaaS and OAuth App Governance Guide, Entra ID Security Guide.