{"id":23896,"date":"2025-03-10T06:32:50","date_gmt":"2025-03-10T13:32:50","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/?p=23896"},"modified":"2025-10-13T09:16:06","modified_gmt":"2025-10-13T16:16:06","slug":"changes-on-sharepoint-framework-spfx-permission-grants-in-microsoft-entra-id","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/changes-on-sharepoint-framework-spfx-permission-grants-in-microsoft-entra-id\/","title":{"rendered":"Changes on SharePoint Framework (SPFx) permission grants in Microsoft Entra ID"},"content":{"rendered":"<p>We are introducing a <strong>set of changes to the way API permissions are managed in SharePoint Online<\/strong> by Tenant Administrators, which should be noted in the context of SharePoint Framework (SPFx) permission grants in the Microsoft Entra ID.<\/p>\n<p>Previously SharePoint Framework solutions permission grants were done against an application called &#8220;<strong>SharePoint Online Client Extensibility Web Application Principal<\/strong>&#8220;, which was automatically created for the customer tenants. That was used as the &#8220;identity&#8221; of the application that presented itself to get tokens to access APIs like Microsoft Graph or other third party APIs.<\/p>\n<p><strong>Starting from the second week of March 2025<\/strong>, we are beginning to transition to the &#8220;SharePoint Online Web Client Extensibility&#8221; 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 <strong>keep permissions in sync<\/strong> between the &#8220;SharePoint Online Web Client Extensibility&#8221; and &#8220;SharePoint Online Client Extensibility Web Application Principal&#8221; object in Entra ID. We will share an update to this blogpost once the rollout has been completed and the &#8220;SharePoint Online Client Extensibility Web Application Principal&#8221; object is no longer used.<\/p>\n<p>All previously granted permissions have been automatically copied over which means that the existing SharePoint Framework applications continue to work without any required changes.<\/p>\n<p><b><i data-olk-copy-source=\"MessageBody\">Note:<\/i><\/b><i>\u00a0if any of the SharePoint Framework applications use\u00a0<u>Sites.Selected\u00a0<\/u>permissions (<\/i><i><u><a id=\"OWAd85c9e73-7de6-d87e-21e3-5f928c8ff7ab\" title=\"Original URL: https:\/\/learn.microsoft.com\/en-us\/graph\/permissions-selected-overview?tabs=http. Click or tap if you trust this link.\" href=\"https:\/\/nam06.safelinks.protection.outlook.com\/?url=https%3A%2F%2Flearn.microsoft.com%2Fen-us%2Fgraph%2Fpermissions-selected-overview%3Ftabs%3Dhttp&amp;data=05%7C02%7CVesa.Juvonen%40microsoft.com%7C9d4fdcc10494418152f208de0a732198%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C638959686818851367%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;sdata=Ve7DLxtLMY4irrByvnVrilLQb6lIslSKLbMo38oVREM%3D&amp;reserved=0\" data-auth=\"NotApplicable\" data-linkindex=\"0\">Overview of Selected Permissions in OneDrive and SharePoint &#8211; Microsoft Graph | Microsoft Learn<\/a><\/u><\/i><i>), the application will not be able to access the targeted site explicit permissions are not granted again by a tenant global admin or an application with Sites.FullControl.All application permission. Please refer to this link to learn more on how to re-apply such permissions: <a href=\"https:\/\/learn.microsoft.com\/en-us\/sharepoint\/dev\/sp-add-ins-modernize\/understanding-rsc-for-msgraph-and-sharepoint-online#granting-permissions-to-a-specific-site-collection\">Granting permissions to a specific Site Collection | Microsoft Learn<\/a>.<\/i><\/p>\n<p>We have also <strong>updated the API Access Page in SharePoint Online Tenant Administration<\/strong> 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 &#8220;SharePoint Online Client Extensibility Web Application Principal&#8221; application registration will not be automatically deleted and will remain as unused application registration in any tenant where it was previously created.<\/p>\n<h3>Why is this change done?<\/h3>\n<p>We introduced this change to provide the following benefits:<\/p>\n<ul>\n<li><strong>better performance:<\/strong> 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)<\/li>\n<li><strong>better reliability:<\/strong> \u00a0we ensure the state of the application principal at app boot.<\/li>\n<li><strong>more governance:<\/strong> 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 <i>will <\/i>affect out of the box functionalities.<\/li>\n<\/ul>\n<h3>PowerShell to grant permissions<\/h3>\n<p><strong>As you no longer can grant permissions directly from the Microsoft Entra ID user interface<\/strong>, 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.<\/p>\n<p>You can find reference PowerShell script below :<\/p>\n<pre class=\"prettyprint language-ps\"><code class=\"language-ps\">&lt;#\r\n.SYNOPSIS\r\nThis cmdlet privovides a way for developer and system administrators to add permissions to AAD protected APIs for SharePoint Framework custom code.\r\n\r\n.PARAMETER appID\r\nthe ID of the app to set permissions for\r\n.PARAMETER scope\r\nthe scope of the permission request to add\r\n\r\n.EXAMPLE\r\nAddSPFxPermissions -appID \"00000003-0000-0000-c000-000000000000\" -scope \"Sites.Read.All\"\r\n\r\n.NOTES\r\nrequires Graph SDK to be installed. Follow documentation here: https:\/\/learn.microsoft.com\/en-us\/powershell\/microsoftgraph\/installation?view=graph-powershell-1.0\r\n#&gt;\r\n\r\n[CmdletBinding()]\r\nparam(\r\n    [Parameter(Mandatory=$true)]\r\n    [string] $appID,\r\n\r\n    [Parameter(Mandatory=$true)]\r\n    [string] $scope\r\n)\r\n\r\n$sPFxAppID = \"08e18876-6177-487e-b8b5-cf950c1e598c\"\r\n$objectGrant = $null\r\n\r\nconnect-MgGraph -scopes \"Application.ReadWrite.All\", \"Directory.ReadWrite.All\" -NoWelcome\r\ntry{\r\n    #Get the SPFx Service Principal\r\n    $sPFxSP =  Get-MgServicePrincipal -Filter \"appid eq '$spfxAppID'\" -ErrorAction Stop\r\n    #get the endpoint service princpal (required to identify the object ID)\r\n    $resourceSP =  Get-MgServicePrincipal -Filter \"appid eq '$appID'\" -ErrorAction Stop\r\n\r\n    #check if some scopes have been already added for the endpoint\r\n    $oGrants = Get-MgServicePrincipalOauth2PermissionGrant -ServicePrincipalId $sPFxSP.Id -ErrorAction Stop\r\n    foreach ($item in $oGrants)\r\n    {\r\n        if( $item.ResourceId -eq $resourceSP.Id)\r\n        {\r\n            $objectGrant = $item\r\n            break\r\n        }\r\n    }\r\n\r\n    #if $objectGrant is not null, we check if the scope already exists there\r\n    if ($null -ne $objectGrant)\r\n    {\r\n        if ($objectGrant.Scope | Select-String $scope -Quiet ){\r\n            throw \"Scope has already been granted\"\r\n        }\r\n        #The scope was not added, added it to the $objectGrant and update it\r\n        $objectGrant.Scope += \" $scope\"\r\n        Update-MgOauth2PermissionGrant -OAuth2PermissionGrantId $objectGrant.Id -Scope $objectGrant.Scope -ErrorAction Stop | Out-Null\r\n    }\r\n    #otherwise, we just create the new object witht the scope \r\n    else{\r\n        $params = @{\r\n            \"clientId\" = $sPFxSP.id\r\n            \"ConsentType\" = \"AllPrincipals\"\r\n            \"ResourceId\" = $resourceSP.id\r\n            \"scope\" = $scope\r\n          }\r\n        New-MgOauth2PermissionGrant -BodyParameter $params -ErrorAction Stop | Out-Null\r\n    }\r\n    \r\n    Write-Host \"Permissions set for SPFx app with ID $appID\"\r\n}\r\ncatch{\r\n    Write-Host \"the following error occurred: $_.Exception\" -ForegroundColor Red\r\n}\r\nfinally{\r\n    Disconnect-MgGraph \r\n    Write-Host \"Command completed.\"\r\n}<\/code><\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Changes on the SPFx permission management model in the Microsoft Entra ID.<\/p>\n","protected":false},"author":69078,"featured_media":23898,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,166,9],"tags":[134,392,162,19,214],"class_list":["post-23896","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-365-developer","category-sharepoint","category-sharepoint-framework","tag-microsoft-365-administration-center","tag-microsoft-entra-id","tag-sharepoint","tag-sharepoint-framework","tag-sharepoint-online"],"acf":[],"blog_post_summary":"<p>Changes on the SPFx permission management model in the Microsoft Entra ID.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/23896","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69078"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=23896"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/23896\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/23898"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=23896"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=23896"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=23896"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}