Grant Microsoft Graph permissions to the App Service¶
The App Service authenticates to Microsoft Graph using its system-assigned managed identity. Azure Portal does not have a UI for assigning Microsoft Graph application permissions to a managed identity, so this step is a single PowerShell snippet you run once against Microsoft Graph PowerShell. After it completes, the App Service can call Graph as itself — no client secret, no stored credential.
Wait 10 to 15 minutes after the deploy reports success
The App Service's system-assigned managed identity takes 10 to 15 minutes to propagate across Microsoft Entra ID. Run this snippet only after that window has elapsed. Running it earlier returns a "service principal not found" error.
Find the App Service principal ID¶
The deploy output includes the App Service's managed identity principal ID. To retrieve it:
- Go to Azure Portal > your resource group > Deployments.
- Select the deployment that just completed.
- Select Outputs in the left navigation.
- Copy the value of appServicePrincipalId.
You can also retrieve it later from App Service > Identity > System assigned > Object (principal) ID.
Run the snippet¶
Open a PowerShell session with the Microsoft Graph PowerShell SDK installed (Install-Module Microsoft.Graph -Scope CurrentUser), or use Azure Cloud Shell, which has the module pre-installed.
Paste the principal ID into the first line, then run the rest:
# Paste the appServicePrincipalId from the deploy output
$AppServicePrincipalId = "<paste-the-principal-id-from-deploy-output>"
Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All","Application.Read.All"
$GraphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
$Permissions = @(
"DeviceManagementApps.Read.All",
"DeviceManagementApps.ReadWrite.All",
"DeviceManagementConfiguration.Read.All",
"DeviceManagementManagedDevices.Read.All",
"Group.ReadWrite.All",
"User.Read.All",
"Mail.Send"
)
foreach ($p in $Permissions) {
$role = $GraphSp.AppRoles | Where-Object { $_.Value -eq $p }
if (-not $role) {
Write-Warning "App role $p not found on Microsoft Graph"
continue
}
New-MgServicePrincipalAppRoleAssignment `
-ServicePrincipalId $AppServicePrincipalId `
-PrincipalId $AppServicePrincipalId `
-ResourceId $GraphSp.Id `
-AppRoleId $role.Id `
-ErrorAction SilentlyContinue
Write-Host "Granted $p"
}
The snippet takes about 10 seconds.
What each permission is for¶
| Permission | Used for |
|---|---|
DeviceManagementApps.Read.All |
Read the existing Intune app catalog and assignment state |
DeviceManagementApps.ReadWrite.All |
Create and update Intune Win32 app deployments |
DeviceManagementConfiguration.Read.All |
Read Intune assignment filters used by ring deployment settings |
DeviceManagementManagedDevices.Read.All |
Read managed devices associated with the requesting user |
Group.ReadWrite.All |
Create and manage the security groups that drive app assignments |
User.Read.All |
Read user profiles, managers, and group memberships for approvals |
Mail.Send |
Send email notifications from a configured mailbox (optional, used only if email notifications are enabled) |
Verify the grant¶
In Azure Portal, go to Microsoft Entra ID > Enterprise applications > All applications. Change the Application type filter to Managed Identities and find the App Service by name. Select it, then select Permissions in the left navigation. You should see all seven Graph application permissions listed with admin consent granted.
You can also verify by signing in to the portal and selecting Admin > App Catalog > Sync from Intune. If apps appear, the permissions are in place.
Rerunning the snippet is safe
The snippet uses ErrorAction SilentlyContinue so re-running after a partial failure, or after a future release adds a permission, is idempotent. Already-granted roles are skipped, missing roles are added.
Next step¶
Continue to Add the production redirect URI.