We are introducing a set of changes to the way API permissions are managed in SharePoint Online by Tenant Administrators, which should be noted in the context of SharePoint Framework (SPFx) permission grants in the Microsoft Entra ID.
Previously SharePoint Framework solutions permission grants were done against an application called “SharePoint Online Client Extensibility Web Application Principal“, which was automatically created for the customer tenants. That was used as the “identity” of the application that presented itself to get tokens to access APIs like Microsoft Graph or other third party APIs.
Starting from the second week of March 2025, we are beginning to transition to the “SharePoint Online Web Client Extensibility” application principal to be used for SPFx permission management. As the process will take time, if you are not using the API access page for managing permission request you will have to continue to use the existing process you have to keep permissions in sync between the “SharePoint Online Web Client Extensibility” and “SharePoint Online Client Extensibility Web Application Principal” object in Entra ID. We will share an update to this blogpost once the rollout has been completed and the “SharePoint Online Client Extensibility Web Application Principal” object is no longer used.
All previously granted permissions have been automatically copied over which means that the existing SharePoint Framework applications continue to work without any required changes.
We have also updated the API Access Page in SharePoint Online Tenant Administration now displays a set of additional permissions that have been automatically pre-authorized by Microsoft. Those permissions are required for SharePoint Online to function properly. Tenant Administrators can remove those permissions (and add them back via the API Access page), but by doing that they might compromise some of the out of the box functionalities provided by SharePoint. Previously provisioned “SharePoint Online Client Extensibility Web Application Principal” application registration will not be automatically deleted and will remain as unused application registration in any tenant where it was previously created.
Why is this change done?
We introduced this change to provide the following benefits:
- better performance: with a single application we are using a faster path for getting the access tokens and you have shared access tokens with 1st party code (the same token is used by both 1st and 3rd parties)
- better reliability: we ensure the state of the application principal at app boot.
- more governance: as an administrator, you can now control the set of permissions that Microsoft pre-authorized to the application principal. Note however that removing default permissions will affect out of the box functionalities.
PowerShell to grant permissions
As you no longer can grant permissions directly from the Microsoft Entra ID user interface, we also have released an example PowerShell script that can be used in scenarios were you want to manage SharePoint Framework permissions outside of SharePoint Online Tenant Administration user interface.
You can find reference PowerShell script below :
<#
.SYNOPSIS
This cmdlet privovides a way for developer and system administrators to add permissions to AAD protected APIs for SharePoint Framework custom code.
.PARAMETER appID
the ID of the app to set permissions for
.PARAMETER scope
the scope of the permission request to add
.EXAMPLE
AddSPFxPermissions -appID "00000003-0000-0000-c000-000000000000" -scope "Sites.Read.All"
.NOTES
requires Graph SDK to be installed. Follow documentation here: https://learn.microsoft.com/en-us/powershell/microsoftgraph/installation?view=graph-powershell-1.0
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string] $appID,
[Parameter(Mandatory=$true)]
[string] $scope
)
$sPFxAppID = "08e18876-6177-487e-b8b5-cf950c1e598c"
$objectGrant = $null
connect-MgGraph -scopes "Application.ReadWrite.All", "Directory.ReadWrite.All" -NoWelcome
try{
#Get the SPFx Service Principal
$sPFxSP = Get-MgServicePrincipal -Filter "appid eq '$spfxAppID'" -ErrorAction Stop | Out-Null
#get the endpoint service princpal (required to identify the object ID)
$resourceSP = Get-MgServicePrincipal -Filter "appid eq '$appID'" -ErrorAction Stop | Out-Null
#check if some scopes have been already added for the endpoint
$oGrants = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $sPFxSP.Id -ErrorAction Stop | Out-Null
foreach ($item in $oGrants)
{
if( $item.ResourceId -eq $resourceSP.Id)
{
$objectGrant = $item
break
}
}
#if $objectGrant is not null, we check if the scope already exists there
if ($null -ne $objectGrant)
{
if ($objectGrant.Scope | Select-String $scope -Quiet ){
throw "Scope has already been granted"
}
#The scope was not added, added it to the $objectGrant and update it
$objectGrant.Scope += " $scope"
Update-MgOauth2PermissionGrant -OAuth2PermissionGrantId $objectGrant.Id -Scope $objectGrant.Scope -ErrorAction Stop | Out-Null
}
#otherwise, we just create the new object witht the scope
else{
$params = @{
"clientId" = $sPFxSP.id
"ConsentType" = "AllPrincipals"
"ResourceId" = $resourceSP.id
"scope" = $scope
}
New-MgOauth2PermissionGrant -BodyParameter $params -ErrorAction Stop | Out-Null
}
Write-Host "Permissions set for SPFx app with ID $appID"
}
catch{
Write-Host "the following error occurred: $_.Exception" -ForegroundColor Red
}
finally{
Disconnect-MgGraph
Write-Host "Command completed."
}
Regarding the code provided (PowerShell). I do not know what the following constant is keeping? Suppose that it has to be updated for a use in my tenant but not sure where to get it.
I noticed that the API access page is no longer working if I try to enable a custom API. The first time I noticed it was on Friday March 7. Is it possible that this is related to the changes described in this article?
If I try to enable the API I receive an error message: "Access can't be approved because you didn't accept the requested permissions.".Read more
In the network trace I noticed that it uses the Graph API to get the app from Entra ID, but since I has never been approved first, it always returns an empty array. (https://graph.microsoft.com/beta/servicePrincipals/?$filter=appId%20eq%20%27[AppID]%27)
Is there any value being added by this limitation in Entra ID and forcing PowerShell to update permissions? For example, does it get us closer to having app specific permissions while allowing SPFx to handle the token acquisition?