In Microsoft Entra ID, custom applications often interact with Microsoft Graph and other services using API permissions. While these permissions enable powerful integrations, some of them are considered high-risk because they grant extensive access to directory data, users, groups, and files.
Examples of such permissions include: i) Directory.ReadWrite.All, ii) User.ReadWrite.All, iii) Group.ReadWrite.All. Identifying custom (non-template) Entra apps with high-risk permissions is critical for: i) Security audits, ii) Compliance enforcement, iii) Least privilege validation and iv)Threat detection.
Using Microsoft Graph PowerShell, administrators can scan all applications, detect high-risk permissions, and export a detailed report for analysis.
Download this script from our M365Corner GitHub Repo: https://github.com/m365corner/M365Corner-Scripts/tree/main/Entra-Apps-Related-Scripts/List-Custom-Entra-Apps-With-High-Risk-PermissionsTry the M365Corner Microsoft 365 Reporting Tool â your DIY pack with 20+ out-of-the-box M365 reports for Users, Groups, and Teams.
# Connect to Microsoft Graph
Connect-MgGraph -Scopes Application.Read.All
Write-Host "Scanning custom applications with high-risk permissions..." -ForegroundColor Cyan
# Define high-risk permissions
$HighRiskPermissions = @(
"Directory.ReadWrite.All",
"User.ReadWrite.All",
"Application.ReadWrite.All",
"RoleManagement.ReadWrite.Directory",
"Group.ReadWrite.All",
"Mail.ReadWrite",
"Files.ReadWrite.All"
)
# Get applications
$Applications = Get-MgApplication -All -Property Id,DisplayName,AppId,CreatedDateTime,Description,ApplicationTemplateId,RequiredResourceAccess
$Results = @()
foreach ($App in $Applications) {
# Only process custom (non-template) apps
if ($App.ApplicationTemplateId) {
continue
}
$MatchedPermissions = @()
foreach ($Resource in $App.RequiredResourceAccess) {
foreach ($Access in $Resource.ResourceAccess) {
$PermissionId = $Access.Id
# Resolve permission name
$ServicePrincipal = Get-MgServicePrincipal -Filter "appId eq '$($Resource.ResourceAppId)'" -Property AppRoles,Oauth2PermissionScopes
$PermissionName = ($ServicePrincipal.AppRoles + $ServicePrincipal.Oauth2PermissionScopes | Where-Object {$_.Id -eq $PermissionId}).Value
if ($HighRiskPermissions -contains $PermissionName) {
$MatchedPermissions += $PermissionName
}
}
}
if ($MatchedPermissions.Count -gt 0) {
# Console output (minimal)
Write-Host "$($App.DisplayName) | $($App.AppId)" -ForegroundColor Red
# Export object (detailed)
$Results += [PSCustomObject]@{
ApplicationName = $App.DisplayName
ApplicationId = $App.Id
ClientId = $App.AppId
CreatedDate = $App.CreatedDateTime
Description = $App.Description
AppType = "Custom (Non-Template)"
HighRiskPermissions = ($MatchedPermissions -join ", ")
RiskLevel = "High"
}
}
}
# Export results
$ExportPath = "D:\CustomApps_HighRiskPermissions_Report.csv"
$Results | Export-Csv $ExportPath -NoTypeInformation
Write-Host "Report exported to $ExportPath" -ForegroundColor Cyan
| Step | Description |
|---|---|
| Connect to Graph | Authenticates using Application.Read.All permission |
| Define High-Risk Permissions | Creates a predefined list of sensitive Graph permissions |
| Retrieve Applications | Uses Get-MgApplication -All to fetch all applications with required properties |
| Filter Custom Apps | Skips template-based apps that contain ApplicationTemplateId value |
| Extract Permissions | Iterates through RequiredResourceAccess to identify assigned permissions |
| Resolve Permission Names | Maps permission IDs to readable names using Get-MgServicePrincipal |
| Match High-Risk Permissions | Compares permissions against predefined high-risk list |
| Build Report | Stores apps with matched permissions in a structured object |
| Export Results | Outputs data to a CSV report |
| Enhancement | Description |
|---|---|
| Include Owner Details | Add Get-MgApplicationOwner to identify responsible users |
| Add Permission Type | Differentiate between delegated and application permissions |
| Risk Categorization | Categorize permissions into Medium / High / Critical |
| Include Last Sign-In | Combine with sign-in logs to detect inactive risky apps |
| Alerting Mechanism | Send alerts when new high-risk apps are detected |
| Question | Answer |
|---|---|
| What are high-risk entra app permissions? | Permissions that grant extensive access to directory, users, or data |
| Why focus on custom entra apps? | Custom entra apps often bypass standard governance controls |
| How are permissions identified? | By mapping permission IDs to permission names via service principals |
| Can template based entra apps also have high-risk permissions? | Yes, but this script intentionally excludes them |
| Is this script suitable for large tenants? | Yes, but performance can be improved with filtering |
| Use Case | Description |
|---|---|
| Security Audit | Identify apps with excessive permissions |
| Compliance Checks | Ensure apps follow least privilege principles |
| Threat Detection | Detect potentially malicious or over-permissioned apps |
| Governance Reporting | Maintain visibility over sensitive application access |
| App Review Process | Validate permissions before approving applications |
| Error | Cause | Solution |
|---|---|---|
| Insufficient privileges | Missing Graph permissions | Use Application.Read.All with admin consent |
| Slow execution | Large number of apps | Optimize by filtering or batching requests |
| Cmdlet not recognized | Graph module not installed | Install using Install-Module Microsoft.Graph |
| Access token expired | Session timeout | Reconnect using Connect-MgGraph |
| Empty results | No high-risk apps found | Validate permission list and tenant data |
Custom Entra applications with high-risk permissions can pose significant security risks if not properly monitored. These permissions often grant deep access to sensitive data and directory operations, making them a critical focus area for administrators
This Microsoft Graph PowerShell script provides a powerful way to identify, analyze, and report custom applications with high-risk permissions, enabling better governance and proactive security management.
By incorporating this script into regular audits and automation workflows, organizations can strengthen their security posture, enforce least privilege principles, and reduce potential attack surfaces in their Entra ID environment.
© Created and Maintained by LEARNIT WELL SOLUTIONS. All Rights Reserved.