Managing OAuth Permission Grants
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
✦ Skip the page breaks and see fewer ads — read each lesson on a single page with Pro
Managing OAuth Permission Grants in Microsoft Entra ID
In the modern cloud ecosystem, identity is the new security perimeter. When we talk about securing applications, we are no longer just talking about firewalls and IP addresses; we are talking about who—or what—has the authority to access specific data. Microsoft Entra ID (formerly Azure Active Directory) uses the OAuth 2.0 and OpenID Connect (OIDC) protocols to manage this authority. At the heart of this system lies the concept of permission grants. Whether it is a mobile app reading a user’s calendar or a background service migrating thousands of files, every action is governed by a specific permission grant.
Understanding how to manage these grants is a critical skill for any identity architect or security administrator. If you grant too much access, you create a massive security hole; if you grant too little, your applications stop working. This lesson will dive deep into the mechanics of OAuth permission grants, how to manage them through the Entra portal and automation, and the best practices you need to follow to keep your environment secure while remaining functional.
The Foundation: Understanding Permission Types
Before we can manage grants, we have to understand what we are actually granting. In Microsoft Entra ID, permissions are categorized into two primary types: Delegated permissions and Application permissions. Choosing the wrong one is a common mistake that can lead to either broken functionality or excessive risk.
Delegated Permissions
Delegated permissions are used when a user is present. In this scenario, the application acts on behalf of the signed-in user. For example, if you use a third-party task management app, that app might ask for the "Read your mail" permission. When you sign in, the app can only see the emails that you have access to. It cannot see another user's email unless that user also signs in and grants permission.
The effective permissions of the application are the intersection of the permissions granted to the application and the permissions the user actually has. If an app has the delegated permission to delete files, but the user is a "Read-only" user in SharePoint, the app will not be able to delete files. This "least privilege" by design is a core strength of delegated permissions.
Application Permissions
Application permissions (sometimes called "App-only" or "Roles") are used by applications that run without a signed-in user. These are typically background services, daemons, or scheduled scripts. Because there is no user to provide a context, the application has access to all the data the permission implies across the entire organization (tenant).
For instance, if a backup service is granted the Mail.Read application permission, it can read every single mailbox in the entire company. Because of this broad reach, application permissions almost always require a "Global Administrator" or a "Privileged Role Administrator" to grant consent. They are powerful and potentially dangerous if mismanaged.
Callout: Delegated vs. Application Permissions
Feature Delegated Permissions Application Permissions User Presence User must be signed in. No user present (background service). Effective Access Intersection of user rights and app scopes. Full scope of the permission across the tenant. Common Use Case Mobile apps, Web front-ends. Sync engines, Backup tools, Daemons. Consent Requirement Often the user, sometimes an admin. Always requires an administrator.
The Consent Framework
Permission grants are realized through a process called "Consent." Consent is the act of a user or administrator authorizing an application to access protected resources. Microsoft Entra ID provides a sophisticated framework to manage how this consent is given and who is allowed to give it.
User Consent
By default, in many older or less restricted tenants, users can grant consent to applications for permissions that only affect their own data. For example, a user might allow an app to read their basic profile or their own calendar. However, allowing users to grant consent to any application is increasingly viewed as a security risk. Malicious actors use "Consent Phishing" to trick users into granting access to their data.
Admin Consent
Admin consent is a mechanism where a high-privileged user grants permission on behalf of the entire organization. When an admin grants consent, the application no longer asks individual users for permission when they sign in. This is required for all Application permissions and for sensitive Delegated permissions (like those that allow an app to read the full directory).
As an administrator, you can grant consent through the Azure Portal by navigating to the "API Permissions" blade of an application registration and clicking the "Grant admin consent for [Tenant Name]" button. This action creates an oauth2PermissionGrant or an appRoleAssignment object in the background, which the Entra ID security token service (STS) checks whenever the app requests a token.
Note: Granting admin consent is a "set and forget" action for many, but it should be treated with the same gravity as adding a user to a highly privileged group. Always verify the application's publisher and the specific scopes requested before clicking that button.
Configuring User Consent Settings
Because of the risks associated with consent phishing, most organizations should move away from allowing unrestricted user consent. Entra ID provides three main postures for user consent:
- Allow user consent for all apps: This is the least secure setting. Any user can grant any permission that doesn't require an admin to any app.
- Allow user consent for apps from verified publishers: This is a middle-ground approach. Users can only consent to apps if the developer has been verified by Microsoft. This reduces the risk of "shadow IT" apps created by unknown entities.
- Do not allow user consent: This is the most secure posture. Users cannot grant any permissions. Instead, they must request access, and an administrator must approve it.
The Admin Consent Workflow
If you disable user consent, you should enable the "Admin Consent Workflow." This provides a structured way for users to request access to an app they need. When a user tries to sign in to an app that hasn't been approved, they see a form where they can enter a justification for the request. Admins receive an email and can approve or deny the request directly from the Entra portal. This keeps the business moving while ensuring security oversight.
Managing Scopes and Roles in the App Manifest
To manage grants effectively, you need to understand how they are defined. Permissions are defined in the Application Registration, specifically within the "App Manifest."
Scopes (Delegated)
Scopes are the permissions that an API (like Microsoft Graph) exposes to client applications. In the manifest, these are listed under oauth2Permissions. Each scope has a value (like User.Read), a displayName, and a description. When you manage grants, you are essentially mapping a client application to these specific values.
App Roles (Application)
App Roles are used for application permissions. In the manifest, these are found in the appRoles collection. Unlike scopes, which are about "what a user can do," roles are often about "what the application itself is allowed to do." When you grant an application permission, you are assigning the service principal of the client app to a specific role defined in the resource app (the API).
Practical Example: Granting Permissions via PowerShell
While the portal is great for one-off tasks, managing permissions at scale requires automation. The Microsoft Graph PowerShell SDK is the primary tool for this. Let's look at how to grant a delegated permission and an application permission using code.
Granting Delegated Permissions
To grant a delegated permission, we create an oAuth2PermissionGrant. This links a service principal (the app) to a resource (like Microsoft Graph) for a specific set of scopes.
# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Directory.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All"
# Define the IDs
$clientServicePrincipalId = "00000000-0000-0000-0000-000000000000" # The ID of your app's Service Principal
$graphServicePrincipalId = (Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'").Id # Microsoft Graph ID
# Create the grant
$params = @{
ClientId = $clientServicePrincipalId
ConsentType = "AllPrincipals" # This means Admin Consent for the whole tenant
ResourceId = $graphServicePrincipalId
Scope = "User.Read.All Group.Read.All"
StartTime = [System.DateTime]::Now
ExpiryTime = [System.DateTime]::Now.AddYears(10)
}
New-MgOAuth2PermissionGrant -BodyParameter $params
In this script, we use ConsentType = "AllPrincipals". This is the programmatic equivalent of clicking the "Grant Admin Consent" button in the portal. If you wanted to grant consent for only a single user, you would set ConsentType = "Principal" and provide that user's ID in a PrincipalId field.
Granting Application Permissions
Application permissions are handled differently. Instead of an oAuth2PermissionGrant, we use an AppRoleAssignment.
# Get the Service Principal of the client app
$app = Get-MgServicePrincipal -Filter "DisplayName eq 'MyBackgroundService'"
# Get the Microsoft Graph Service Principal
$graph = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
# Find the ID of the "Directory.Read.All" role in Microsoft Graph
$role = $graph.AppRoles | Where-Object { $_.Value -eq "Directory.Read.All" }
# Assign the role
New-MgServicePrincipalAppRoleAssignment `
-ServicePrincipalId $app.Id `
-PrincipalId $app.Id `
-ResourceId $graph.Id `
-AppRoleId $role.Id
This code is a bit more complex because it requires looking up the specific ID of the role within the target API. This is a crucial step because role IDs are unique GUIDs, not just strings like "Directory.Read.All".
Warning: When running scripts that grant permissions, always include logging and approval steps in your automation pipeline. A script that accidentally grants
Directory.ReadWrite.Allto a public-facing application can lead to a total tenant compromise.
Managed Identities and OAuth Grants
Managed Identities are a specialized type of service principal that eliminates the need for developers to manage credentials (secrets or certificates). However, many people forget that Managed Identities still need OAuth permission grants.
When you enable a System-Assigned Managed Identity on an Azure Function or a VM, Microsoft Entra ID creates a Service Principal for that resource. To allow that Function to read from Microsoft Graph or access an Azure Key Vault, you must grant it permissions exactly like you would for a standard application registration.
The beauty of Managed Identities is that while the granting of permissions is the same, the acquisition of the token is handled by the Azure platform. This removes the risk of credentials being leaked from configuration files or environment variables.
Step-by-Step: Auditing Existing Permission Grants
One of the most important tasks for an administrator is auditing. You need to know which applications have been granted high-privilege access to your data.
- Open the Entra Portal: Navigate to "Identity" > "Applications" > "Enterprise applications."
- Filter by Permissions: You can't filter the main list by permission, but you can inspect individual apps. However, for a tenant-wide view, use the "Permissions" blade under "Security."
- Review Admin-Consented Apps: Look for apps with "Application" permissions. These are your highest risk.
- Check for "Illlicit Consent Grant" patterns: Look for unfamiliar apps with names like "Upgrade," "Maintenance," or "Enable Security" that have been granted permissions like
Mail.ReadorNotes.Read. - Use PowerShell for a full report: The following script helps identify all apps with Application permissions:
$allApps = Get-MgServicePrincipal -All
foreach ($app in $allApps) {
$assignments = Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $app.Id
foreach ($assign in $assignments) {
# Look up the resource name (e.g., Microsoft Graph)
$resource = Get-MgServicePrincipal -ServicePrincipalId $assign.ResourceId
$role = $resource.AppRoles | Where-Object { $_.Id -eq $assign.AppRoleId }
[PSCustomObject]@{
AppDisplayName = $app.DisplayName
ResourceName = $resource.DisplayName
Permission = $role.Value
}
}
}
This script provides a clear list of every service-to-service permission grant in your environment, allowing you to identify and revoke unnecessary access.
Best Practices for Managing Grants
Managing OAuth permissions isn't just about knowing which buttons to click; it's about establishing a lifecycle of security.
1. Principle of Least Privilege (PoLP)
Never grant Directory.ReadWrite.All if User.Read.All is sufficient. If an application only needs to read files from a specific SharePoint site, don't give it Files.Read.All (which covers the whole tenant). Instead, use "Sites.Selected" and then use the Graph API to grant the app access to only that specific site.
2. Prefer Delegated over Application Permissions
Whenever possible, use delegated permissions. This ensures that the application's access is restricted by the permissions of the user. It provides a natural "check and balance" that application permissions lack.
3. Regularly Review and Revoke
Permissions tend to accumulate over time—a phenomenon known as "permission creep." Conduct quarterly reviews of all admin-consented applications. If an application is no longer in use, delete its service principal and revoke its grants.
4. Require Verified Publishers
Configure your user consent settings to only allow consent for apps from verified publishers. This ensures that the organization behind the app has a verified relationship with Microsoft, adding a layer of accountability.
5. Use Conditional Access
You can apply Conditional Access policies to service principals. Even if an app has a permission grant, you can require that the request comes from a specific IP range or a managed device, providing "defense in depth."
Callout: The "Sites.Selected" Pattern
For years, the only way to give an app access to SharePoint was the
Files.Read.Allpermission, which was often too broad. Microsoft introducedSites.Selected. When an app has this permission, it can't see anything by default. An administrator must then use a specific Graph API call to "invite" the app to a specific SharePoint site. This is the gold standard for granular OAuth management.
Common Pitfalls and How to Avoid Them
Even experienced admins can run into trouble with OAuth grants. Here are some common mistakes and the strategies to avoid them.
The "Consent Loop"
Sometimes, users get stuck in a loop where the app keeps asking for consent even after they've granted it. This usually happens when the app is requesting a scope that isn't defined in the app registration or when the "Admin Consent" was granted but hasn't propagated through the global system yet (which can take a few minutes).
- Fix: Ensure the
scopesparameter in your authentication code matches exactly what is listed in the Entra portal.
Confusing App Registrations with Service Principals
An "App Registration" is the global definition of the app (the blueprint). A "Service Principal" is the local instance of that app in your specific tenant (the actual object that holds the permissions).
- Fix: When granting permissions via PowerShell, always use the ID of the Service Principal, not the App Registration.
Over-Reliance on "All" Scopes
Scopes like User.Read.All or Mail.Read.All are often used because they are easy. However, they are high-value targets for attackers.
- Fix: Investigate if there are more specific scopes available. For example, use
Mail.ReadBasicinstead ofMail.Readif the app only needs to see metadata like the subject line and sender, rather than the body of the email.
Forgetting the "Resource" in the Grant
An OAuth grant is a three-way relationship: Client -> Permission -> Resource. People often forget the resource. You aren't just granting Read, you are granting Read on Microsoft Graph or Read on your custom API.
- Fix: Always verify the
AppIdof the resource you are granting access to. The AppId for Microsoft Graph is always00000003-0000-0000-c000-000000000000.
Comparison of Consent Methods
| Method | Best For | Security Level | Admin Effort |
|---|---|---|---|
| Individual User Consent | Low-risk apps, personal productivity. | Low | Minimal |
| Verified Publisher Consent | Trusted third-party SaaS tools. | Medium | Minimal |
| Admin Consent Workflow | Standard corporate posture. | High | Moderate (Approval required) |
| Manual Admin Consent | Background services, high-privilege apps. | Very High | High |
Troubleshooting Permission Issues
When an application fails with a 403 Forbidden error despite having the correct permissions, follow this checklist:
- Check the Token: Use a tool like
jwt.msto inspect the access token the app is using. Look for thescp(scopes) orrolesclaim. If the permission isn't in the token, the grant isn't working. - Check for "Effective Permissions": Remember that for delegated permissions, the user must also have access to the data. If the user isn't an owner of the file, the app can't read it, even with
Files.Read.All. - Check for Policy Restrictions: Is there a Conditional Access policy blocking the app? Is there a SharePoint-specific policy preventing access from unmanaged devices?
- Check Service Principal Status: Ensure the service principal is enabled for sign-in. If the "Assignment required?" flag is set to "Yes," the user must be explicitly assigned to the app in the "Users and groups" blade.
Key Takeaways
- Distinguish between Delegated and Application permissions: Delegated permissions act on behalf of a user, while Application permissions act as a background service with broad tenant-wide access.
- Prioritize Admin Consent for Security: Disable general user consent and implement the Admin Consent Workflow to ensure every application in your tenant is vetted by a security professional.
- Use the Principle of Least Privilege: Always choose the most granular scope possible. Avoid "All" permissions whenever a specific or "Basic" permission exists.
- Automate Auditing: Use the Microsoft Graph PowerShell SDK to regularly export and review permission grants. Look for high-privilege roles assigned to unknown or unverified applications.
- Understand Managed Identities: Remember that Managed Identities require the same permission grants as standard applications; they only simplify the credential management part of the process.
- Monitor the App Manifest: Be familiar with how
oauth2PermissionsandappRolesare defined in the JSON manifest. This is the source of truth for what an API allows. - Verify Publishers: Use the "Verified Publisher" requirement as a simple but effective filter to prevent low-quality or malicious applications from entering your environment.
By mastering OAuth permission grants, you move from simply "making things work" to "making things work securely." In an era where data breaches often stem from over-privileged applications, the ability to precisely control and audit these grants is one of the most valuable skills in the identity and access management toolkit.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons