Security & identity

Stop illicit consent grants with user consent settings and admin approval

Restrict which apps users can consent to in Microsoft Entra ID, route everything else through the admin consent workflow, and find and revoke risky OAuth grants that already exist.

12 min read
On this page

To stop illicit consent grants in Microsoft Entra ID, restrict user consent under Enterprise apps > Consent and permissions > User consent settings so users can only approve low-impact permissions (or nothing at all), and turn on the admin consent workflow so every other request goes to a named reviewer. Then review the grants that already exist, because changing the setting does not remove consent that users have given in the past.

Who this is for and what you will have

This guide is for Microsoft Entra and Microsoft 365 administrators who want to close the OAuth consent phishing path: an attacker registers an app, sends users a link, and a user clicks Accept on a consent prompt that hands the app access to mail, files or contacts.

At the end you will have:

  • A user consent setting that matches your risk appetite, with the reasoning written down.
  • Permission classifications that define which delegated permissions count as low impact.
  • An admin consent workflow with reviewers, notifications and an expiry period.
  • A repeatable process for finding questionable consent grants and revoking them.

Consent control is one part of an identity-first security model; the zero trust remote access architecture describes how it fits with device and network controls. Apps your own developers register carry a different risk, which is covered in finding expiring app secrets and certificates.

Microsoft describes the attack in three steps. The attacker registers an application in Microsoft Entra ID that requests access to data such as contact information, email or documents. The attacker then uses phishing, or code injected into a trusted website, to get a user to consent. After consent, the app has account-level access to that user's data without needing an account in your organization.

The important consequence is that normal incident response does not work. Resetting the password or enforcing MFA does nothing, because the app is not signing in as the user with a password; it holds its own grant. The only fixes are to prevent the consent in the first place and to revoke grants that already exist.

Two permission types matter:

Permission typeWho can consentWhat the app can do
Delegated permissionA user (if policy allows) or an adminAct as the signed-in user, within that user's access
Application permission (app role)Admins onlyAct as itself, with no signed-in user, often across the whole tenant

Illicit consent attacks usually target delegated permissions, because those are the ones ordinary users can approve. Admin consent is the bigger prize, which is why the reviewer process below matters as much as the user setting.

Prerequisites

TaskMinimum role documented by Microsoft
Change user consent settingsPrivileged Role Administrator (Global Administrator when using the admin center)
Classify permissionsApplication Administrator or Cloud Application Administrator
Turn on the admin consent workflowGlobal Administrator
Review and revoke granted permissionsCloud Application Administrator or Application Administrator
Review admin consent requestsCloud Application Administrator who is a designated reviewer

For the PowerShell steps, install the Microsoft Graph PowerShell SDK. The consent cmdlets are in the Microsoft.Graph.Identity.SignIns module.

Sign in to the Microsoft Entra admin center and browse to Entra ID > Enterprise apps > Consent and permissions > User consent settings. Under User consent for applications, pick one of the options and select Save.

OptionWhat users can approveTrade-off
Do not allow user consentNothing new; only apps already consented to or approved by an adminHighest control, more admin workload
Allow user consent for apps from verified publishers, for selected permissionsApps from verified publishers or registered in your tenant, and only permissions you classify as low impactRequires you to maintain permission classifications
Let Microsoft manage your consent settingsAny user-consentable delegated permission except a Microsoft-maintained list of sensitive onesMicrosoft updates the rules over time; default for new tenants
Allow user consent for appsAny permission that doesn't need admin consent, for any appThe setting illicit consent attacks rely on

Microsoft's guidance is to allow user consent only for apps from verified publishers. The Microsoft-managed policy currently blocks user consent for Microsoft Graph permissions such as Files.Read.All, Sites.Read.All, Mail.Read, Mail.ReadWrite, Calendars.Read, Chat.Read and People.Read, plus the Exchange Online EWS.AccessAsUser.All, IMAP.AccessAsUser.All, POP.AccessAsUser.All and EAS.AccessAsUser.All permissions. A companion policy lets users consent to mail permissions for a short list of named mail clients.

One detail that surprises people: if an application requires user assignment, its permissions must be consented to by an administrator even when your user consent policy would otherwise allow it.

Set it with Microsoft Graph PowerShell

The setting lives in the tenant authorization policy, in defaultUserRolePermissions.permissionGrantPoliciesAssigned. Values use the format managePermissionGrantsForSelf.{policy-id}, and an empty list means user consent is disabled. Microsoft warns that the same collection can contain managePermissionGrantsForOwnedResource.* entries, which let developers manage consent for apps they own, so read the current value first and keep those entries.

Connect-MgGraph -Scopes "Policy.ReadWrite.Authorization"
 
# Read what is assigned today
$current = (Get-MgPolicyAuthorizationPolicy).DefaultUserRolePermissions.PermissionGrantPoliciesAssigned
$current
 
# Keep any owned-resource policies, replace the user consent policy
$keep = @($current | Where-Object { $_ -like 'managePermissionGrantsForOwnedResource.*' })
 
$body = @{
    defaultUserRolePermissions = @{
        permissionGrantPoliciesAssigned = @('managePermissionGrantsForSelf.microsoft-user-default-low') + $keep
    }
}
Update-MgPolicyAuthorizationPolicy -BodyParameter $body

To disable user consent entirely, assign only the $keep entries. To list the built-in and custom policies you can reference, run Get-MgPolicyPermissionGrantPolicy | Format-Table Id, DisplayName after connecting with the Policy.ReadWrite.PermissionGrant scope.

Step 2: Classify low-impact permissions

The verified-publisher option only lets users consent to permissions you classify as low impact. Microsoft supports Low, Medium (preview) and High (preview) classifications, and only delegated permissions that don't require admin consent can be classified.

In the admin center, browse to Entra ID > Enterprise apps > Consent and permissions > Permission classifications, choose the tab, select Add permissions, pick the API and select the delegated permissions. Microsoft lists openid, profile, email and offline_access as the minimum for basic sign-in, which makes them a sensible starting set.

Connect-MgGraph -Scopes "Policy.ReadWrite.PermissionGrant", "Application.Read.All"
 
$graph = Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'"
 
foreach ($name in 'openid', 'profile', 'email', 'offline_access') {
    $scope = $graph.Oauth2PermissionScopes | Where-Object { $_.Value -eq $name }
    $params = @{
        PermissionId   = $scope.Id
        PermissionName = $scope.Value
        Classification = 'Low'
    }
    New-MgServicePrincipalDelegatedPermissionClassification -ServicePrincipalId $graph.Id -BodyParameter $params
}
 
Get-MgServicePrincipalDelegatedPermissionClassification -ServicePrincipalId $graph.Id

Resist adding read access to mail, files or chat to the low list. Those are exactly the permissions consent phishing apps ask for.

Blocking consent without an approval path pushes users toward workarounds. The admin consent workflow replaces the dead end with an Approval required prompt where the user types a justification and selects Request approval.

  1. In the Microsoft Entra admin center, browse to Entra ID > Enterprise apps > Consent and permissions > Admin consent settings.
  2. Under Admin consent requests, set Users can request admin consent to apps they are unable to consent to to Yes.
  3. In Who can review admin consent requests, add users, groups or roles. Use a small group of people who actually hold an admin role that can grant consent.
  4. Turn on Selected users will receive email notifications for requests and Selected users will receive request expiration reminders.
  5. Set Consent request expires after (days).
  6. Select Save. Microsoft states it can take up to an hour for the workflow to become enabled.

Two documented limitations are worth knowing. Reviewers removed from the list can still review requests created while they were reviewers, and new reviewers are not assigned to requests created before they were added. If a user sends several requests for the same app, only the first is submitted.

Step 4: Review requests safely

Reviewers work from Entra ID > Enterprise apps > Activity > Admin consent requests, on the My Pending tab. The All (Preview) tab is history only.

For each request, open Review permissions and consent, the App details tab and the Requested by tab, then choose:

ActionEffect
ApproveGrants admin consent; every requester is notified and all users in the tenant can use the app unless you require user assignment
DenyRequires a justification that all requesters see; users can request again later
BlockRequires a justification; creates a disabled service principal for the app so users can't request it again

Before approving, check that you know who controls the app and why it needs each permission. Microsoft lists role management, full access to all mailboxes or all sites, and full user impersonation as examples of highly privileged operations that tenant-wide consent can unlock. If the app only needs a few users, approve it and then set Assignment required on the enterprise app so only assigned users can sign in.

Changing the settings protects you from now on. To find grants made before that, use three sources.

Audit log

In the Microsoft Defender portal, open Audit (https://security.microsoft.com/auditlogsearch), run a search for your date range, sort the Activity column and look for Consent to application. Open each entry and check whether IsAdminConsent is True; an unexpected True means someone with admin rights granted broad access. Microsoft notes that audit entries can take 30 minutes to 24 hours to appear, and suggests reviewing consent grants weekly in large tenants.

Grant inventory with PowerShell

The following lists every delegated grant with the client app name, so you can sort by consent type and scope. AllPrincipals grants cover every user in the tenant and deserve the closest look when the app isn't from Microsoft.

Connect-MgGraph -Scopes "Application.Read.All", "Directory.Read.All"
 
$grants = Get-MgOauth2PermissionGrant -All
$grants | ForEach-Object {
    $client = Get-MgServicePrincipal -ServicePrincipalId $_.ClientId -Property DisplayName, AppId, PublisherName
    [pscustomobject]@{
        App         = $client.DisplayName
        AppId       = $client.AppId
        Publisher   = $client.PublisherName
        ConsentType = $_.ConsentType
        PrincipalId = $_.PrincipalId
        Scope       = $_.Scope
    }
} | Sort-Object ConsentType, App | Export-Csv .\delegated-grants.csv -NoTypeInformation

Look for misspelled or generic app names, Read/Write/All scopes that don't fit the app's purpose, and grants by high-value users. Users can also review their own app access at https://myapps.microsoft.com.

Defender for Cloud Apps

If you license Microsoft Defender for Cloud Apps, go to Cloud Apps > OAuth apps in the Defender portal (or App governance, if it's turned on). Microsoft suggests filtering on Permission level high severity with Community use not common, and checking the saved query Apps authorized by external users. You can create an OAuth app policy under Cloud Apps > Policies > Policy management > Threat detection > Create policy > OAuth app policy to alert on, for example, high-permission apps authorized by many users. Built-in anomaly policies include Malicious OAuth app consent, Misleading OAuth app name and Misleading publisher name for an OAuth app.

Remediate a malicious app

When you confirm an app is illicit, revoke both kinds of grant. On the app's Permissions page you can revoke admin-consented permissions, but user-consented permissions can only be removed with Graph or PowerShell. The following script is based on Microsoft's revocation script. Application permissions are removed through the appRoleAssignedTo relationship of the resource service principal (the API, such as Microsoft Graph), which Microsoft recommends as the best practice, so the resource ID comes from each assignment:

Connect-MgGraph -Scopes "Application.ReadWrite.All", "Directory.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All", "AppRoleAssignment.ReadWrite.All"
 
$sp = Get-MgServicePrincipal -ServicePrincipalId "<service principal object ID>"
 
# Remove all delegated grants
Get-MgOauth2PermissionGrant -All | Where-Object { $_.ClientId -eq $sp.Id } | ForEach-Object {
    Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId $_.Id
}
 
# Remove all application permissions (app role assignments granted to the app)
Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $sp.Id -All |
    Where-Object { $_.PrincipalType -eq "ServicePrincipal" } | ForEach-Object {
        Remove-MgServicePrincipalAppRoleAssignedTo -ServicePrincipalId $_.ResourceId -AppRoleAssignmentId $_.Id
    }

Revoking a grant doesn't stop users consenting again, so either block the app through the admin consent workflow or keep user consent restricted. Then use the audit log to scope what the app accessed; Microsoft notes that this depends on mailbox auditing and activity auditing being on before the attack.

Verification

  • Sign in as a test user to an unverified multitenant test app that requests Mail.Read. The user should see Approval required instead of a consent prompt.
  • Confirm the request appears on My Pending for a reviewer, and that denying it notifies the requester.
  • Re-run Get-MgPolicyAuthorizationPolicy and confirm PermissionGrantPoliciesAssigned contains only the policies you intended.
  • Re-run the grant inventory a week later and compare.

Troubleshooting

AADSTS90094: Administrator consent is required. The app asks for permissions the user can't consent to under your policy and the admin consent workflow isn't on. Turn the workflow on, or grant consent as an admin after review.

AADSTS90095 (AdminConsentRequiredRequestAccess). This is the expected interrupt in the admin consent workflow that tells the user to ask an admin. It's working as designed.

AADSTS65001: The user or administrator hasn't consented to use the application. No consent record exists for the user and resource. If you disabled user consent, an admin must grant it.

A reviewer can't approve a request. Reviewers need a role that can grant the requested permissions. Requests for Microsoft Graph application permissions need a Global Administrator to approve.

Developers lost the ability to consent for their own apps. The managePermissionGrantsForOwnedResource.* entries were dropped when the authorization policy was updated. Add them back.

Checklist

  • User consent set to verified publishers with selected permissions, Microsoft-managed, or disabled.
  • Low-impact classification limited to sign-in permissions.
  • Admin consent workflow on, with reviewers who can actually approve.
  • Reviewers trained to use Block for untrusted apps.
  • Weekly review of Consent to application audit events.
  • Existing AllPrincipals and high-privilege grants inventoried and justified.
  • Removal script tested so revocation is fast during an incident.

References

Questions people ask

Does resetting the user's password remove an illicit consent grant?

No. Microsoft notes that password resets and MFA are not effective against this attack, because the malicious app holds its own OAuth grant and does not need the user's credentials. You have to revoke the app's delegated grants and app role assignments, and stop users from consenting to it again.

What is the default user consent setting for a new Microsoft Entra tenant?

Microsoft documents "Let Microsoft manage your consent settings" as the default for a new tenant. Users can consent to user-consentable delegated permissions, except a Microsoft-maintained list of sensitive permissions such as Files.Read.All, Sites.Read.All and most mail, calendar and chat permissions, which then need admin consent.

Can a reviewer in the admin consent workflow approve any request?

Only if they hold a role that can grant the requested consent. Being designated as a reviewer does not elevate privileges, and Microsoft states that only Global Administrators can approve requests for Microsoft Graph app roles (application permissions). Reviewers can still view, deny and block those requests.

Do new consent settings remove permissions users already granted?

No. Changes to user consent settings only affect future consent operations. Existing grants stay in place until you review and revoke them on the app's Permissions page or with Microsoft Graph PowerShell.

Microsoft Entra IDEnterprise applicationsMicrosoft GraphDefender for Cloud Apps
  1. Troubleshoot Conditional Access with the What If tool and sign-in logs

    Find out why a Conditional Access policy did or did not apply to a sign-in by reading the sign-in log, simulating it with What If, and querying results at scale.

  2. A Microsoft 365 tenant security baseline you can apply in a day

    Harden a new or existing Microsoft 365 tenant in one working day: emergency access, admin roles, MFA and legacy auth, app consent, email protection, external forwarding, audit logging and Secure Score.

  3. AADSTS50076, 50079 and 50158: fix Microsoft Entra MFA sign-in errors

    What AADSTS50076, AADSTS50079 and AADSTS50158 mean, how to find the policy that demanded MFA in the Entra sign-in logs, and how to fix each one for users, scripts and federated domains.