The Sites.Selected
application scope was introduced in Microsoft Graph some time ago to support granular app access permissions in SharePoint Online. With this scope one can grant application access to specific SharePoint Online site collections, instead of granting access to all site collections in the tenant, and this is very welcomed granular and least-privilege functionality in Microsoft Graph - as Graph in general is based on “all or nothing” permission scopes. It’s a step in the right direction, and I hope we will see more of these types of scopes in Microsoft Graph in the future.
When granting Sites.Selected
application scope to a Service Principal, it receives no access to data in SharePoint Online without further action. One must additionally grant app access within each SharePoint Online site which the Service Principal should be allowed to access, with Read or Write role. This can, depending on the scenario, completely remove the necessity of granting Sites.Read.All
or Sites.ReadWrite.All
scopes which grants access to all sites in the tenant.
Recently I was looking into automating Microsoft 365 tasks using Logic Apps, and being a zero-trust and least-privilege advocate I figured out that a Managed Identity with Sites.Selected
application scope would be the best option. I’ve seen several blogs explaining how to use the Sites.Selected
scope with an App Registration and Service Principal, but none of them so far described how to make it work with Managed Identities. Also, Microsoft’s own documentation on this topic could be better - which is why I decided to write this blog post.
Refer to my blog posts on Managed Identities and Microsoft Graph if you need more information on these topics.
So, let’s dive into the technicalities.
- The scenario
- The prerequisites
- Grant application scope in Microsoft Graph
- Grant app access to a specific SharePoint site
- Configure Logic App to retrieve SharePoint list items
The scenario
A Logic App will be used to retrieve items from a specific SharePoint List, with the end-goal of processing the items by creating Microsoft 365 groups, setting group ownership etc. The Logic App will be granted application scopes in Microsoft Graph to be allowed to carry out these actions. Focus is on automation and least-privilege access. This blog post will only describe the first part; how to retrieve items from a SharePoint list using a Managed Identity with Sites.Selected
application scope.
The prerequisites
I needed the following resources:
- A Logic App with a
System assigned
Managed Identity. - A SharePoint Site with a SharePoint list populated with a few columns and items.
- Access to grant Microsoft Graph application scopes and SharePoint site permissions.
Once the System assigned
Managed Identity was enabled on the Logic App, I noted down the Object (principal) ID
for the Managed Identity (guid e8800382-610d-4761-9b15-873065e53227) - which will be used to grant Sites.Selected
application scope in Microsoft Graph.
Visiting the Enterprise Application blade in the Azure AD Portal, I found the recently created Managed Identity object and noted down the Application ID
for the Managed Identity (guid 827fc69f-2814-44d7-96bc-492f2bf21c83) - which will be used to grant permission within the SharePoint site.
I then created a Team with the name LBD M365 Automation, which generated a SharePoint site, and added a SharePoint List with the name OrderList with necessary columns and a few items.
Using Graph Explorer I verified that I was able to retrieve the items in the SharePoint List.
GET https://graph.microsoft.com/v1.0/sites/<tenant>.sharepoint.com:/sites/LBDM365Automation:/lists/OrderList/items?$select=id,webUrl,fields,createdDateTime&$expand=fields($select=Title,Owner,Description,AutomationCompleted)
The prerequisites are completed, now over to grant permissions.
Grant application scope in Microsoft Graph
I used the Microsoft Graph PowerShell SDK to grant the Sites.Selected
application scope in Microsoft Graph. Check out my blog post What is Microsoft Graph PowerShell SDK if you need help on getting started with it.
$ObjectId
is set to the guid value of Object (principal) ID
for the Managed Identity noted down earlier.
# Add the correct 'Object (principal) ID' for the Managed Identity
$ObjectId = "e8800382-610d-4761-9b15-873065e53227"
# Add the correct Graph scope to grant
$graphScope = "Sites.Selected"
Connect-MgGraph -Scope AppRoleAssignment.ReadWrite.All
$graph = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$graphAppRole = $graph.AppRoles | ? Value -eq $graphScope
$appRoleAssignment = @{
"principalId" = $ObjectId
"resourceId" = $graph.Id
"appRoleId" = $graphAppRole.Id
}
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $ObjectID -BodyParameter $appRoleAssignment | Format-List
Running the Powershell code produced the following output in the console, indicating that the scope was successfully granted.
AppRoleId : 883ea226-0bf2-4a8f-9f9d-92c9162a727d
CreatedDateTime : 14.02.2022 07:45:10
DeletedDateTime :
Id : 9Uv0TSLb...Yw3xRUH8
PrincipalDisplayName : lbd-m365-automation-la
PrincipalId : e8800382-610d-4761-9b15-873065e53227
PrincipalType : ServicePrincipal
ResourceDisplayName : Microsoft Graph
ResourceId : 07165e04-89b3-4996-8b1d-a2a225eb5104
AdditionalProperties : {[@odata.context, https://graph.microsoft.com/v1.0/$metadata#servicePrincipals('e8800382-610d-4761-9b15-873065e53227')/appRoleAssignments/$entity]}
The Managed Identity now has the Sites.Selected
application scope in Microsoft Graph, but still requires app access within the specific SharePoint site.
Grant app access to a specific SharePoint site
I used the Microsoft Graph PowerShell SDK to grant the Managed Identity app access to the SharePoint site. Check out my blog post What is Microsoft Graph PowerShell SDK if you need help on getting started with it.
id
in the application
hashtable is set to the guid value of Application ID
for the Managed Identity noted down earlier.
# Add the correct 'Application (client) ID' and 'displayName' for the Managed Identity
$application = @{
id = "827fc69f-2814-44d7-96bc-492f2bf21c83"
displayName = "lbd-m365-automation-la"
}
# Add the correct role to grant the Managed Identity (read or write)
$appRole = "write"
# Add the correct SharePoint Online tenant URL and site name
$spoTenant = "tenant.sharepoint.com"
$spoSite = "LBDM365Automation"
# No need to change anything below
$spoSiteId = $spoTenant + ":/sites/" + $spoSite + ":"
Import-Module Microsoft.Graph.Sites
Connect-MgGraph -Scope Sites.FullControl.All
New-MgSitePermission -SiteId $spoSiteId -Roles $appRole -GrantedToIdentities @{ Application = $application }
Running the Powershell code produced the output of a permission Id in the console, indicating that the permission was successfully granted.
The Logic App’s Managed Identity should now have enough permissions to both read and write the SharePoint List items via Microsoft Graph.
Configure Logic App to retrieve SharePoint list items
I then went back to the Logic App and the Logic app designer blade, and added a new action step.
- Connector:
HTTP
- Method:
GET
- URI:
https://graph.microsoft.com/v1.0/sites/<tenant>.sharepoint.com:/sites/LBDM365Automation:/lists/OrderList/items?$select=id,webUrl,fields,createdDateTime&$expand=fields($select=Title,Owner,Description,AutomationCompleted)&$top=999
- Authentication
- Authentication type:
Managed Identity
- Managed identity:
System-assigned managed identity
- Audience:
https://graph.microsoft.com
- Authentication type:
I saved the new configuration and triggered the Logic App. And behold - status code 200
and a response body with the list items!
Success! The Logic App is able to work with data in SharePoint Online sites authenticating with its least-privileged Managed Identity, but only for sites it is specifically granted app access to. To verify, I created a new Team named LBD M365 Automation 2, added a SharePoint list named OrderList to the SharePoint site with a few list items. Using Graph Explorer I verified that I was able to retrieve the items in the SharePoint List using my own account.
GET https://graph.microsoft.com/v1.0/sites/<tenant>.sharepoint.com:/sites/LBDM365Automation2:/lists/OrderList/items?$select=id,webUrl,fields,createdDateTime&$expand=fields($select=Title,Owner,Description,AutomationCompleted)
And then, when updating the URI
in the HTTP connector in the Logic App to retrieve the list items from the new SharePoint site - which the Managed Identity has not been granted app access to - it resulted in status code 403
with the message Access denied
. Just as expected.
Now you know how to utilize Sites.Selected
application scope and app access roles in SharePoint Online to grant least-privileged access for automation processes utilizing Managed Identities.
And that concludes this blog post, thanks for reading!