Audit Service Principal Access to SharePoint Sites with Sites.Selected Permissions
Ensuring the security and compliance of your SharePoint environment is crucial, especially when dealing with service principals, Entra ID apps, or federated identities. These entities often have elevated permissions that, if mismanaged, can lead to unauthorized access and potential data breaches. Regularly auditing these permissions is a best practice for maintaining a secure and compliant SharePoint environment.
Application only or granular access to individual site instead of whole tenant, scope called “Sites.Selected” is used for different purposes :
- SPFx deployment from CI/CD pipelines via service connections
Refer to the articles for various flavours
Deploy SPFx app using pipeline’s Workload Identity federation
Deploying SPFx apps with Azure DevOps pipelines - Classic variant
- Granting access to applications to the SharePoint sites Refer to Dan Toft’s blog post Sites.Selected Permissions what is it, and how do I use it for more info on this.
Why Audit Service Principal Permissions?
There is no central managed way to view the permissions granted to service principals. It is important for security,compliance and governance.
Granting Permissions
Permissions to service principals, Entra ID apps, or federated identities can be granted to SharePoint sites using the cmdlet if the Sites.Selected permission is granted:
grant-PnPAzureADAppSitePermission -AppId 27f0f80f-4c32-4e49-a3ce-377fff559532 -DisplayName p-m365 -Permissions FullControl
Auditing Permissions
The following PowerShell script retrieves permissions assigned to SharePoint sites for auditing purposes:
param (
[Parameter(Mandatory = $true)]
[string] $domain
)
$adminSiteURL = "https://$domain-Admin.SharePoint.com"
$TenantURL = "https://$domain.sharepoint.com"
$dateTime = "_{0:MM_dd_yy}_{0:HH_mm_ss}" -f (Get-Date)
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$fileName = "entraid_site_permissions" + $dateTime + ".csv"
$outputPath = $directorypath + "\"+ $fileName
if (-not (Test-Path $outputPath)) {
New-Item -ItemType File -Path $outputPath
}
Connect-PnPOnline -Url $adminSiteURL -Interactive -WarningAction SilentlyContinue
Write-Host "Getting entra id permissions..." -ForegroundColor Yellow
$report = Get-PnPTenantSite -Filter "Url -like '$TenantURL'"| Where-Object { $_.Template -ne 'RedirectSite#0' } | foreach-object {
$siteUrl = $_.Url
connect-PnPOnline -Url $siteUrl -interactive -WarningAction SilentlyContinue
Get-PnPAzureADAppSitePermission | ForEach-Object {
[PSCustomObject]@{
##add the properties from the $sharingsetting object
Id = $_.Id
Url = $siteUrl
Roles = $_.Roles -join ","
Apps = $_.Apps -join ","
}
}
}
$report |select * |Export-Csv $outputPath -NoTypeInformation -Append
Results of the script
References
SharePoint now supports delegated Sites.Selected authentication
Develop Applications that use Sites.Selected permissions for SPO sites.
Sites.Selected Permissions what is it, and how do I use it for more info on this.