Sharepoint API can work also with Sites.Selected for more secure approach
Suggestion to improve documentation:
README says not precisely that Sites.Read.All or Sites:ReadWrite.All is needed to work with Sharepoint class. It is not completely true. I managed to work with API keys with only Sites.Selected scope set but then before using the API keys I had to give permissions using Powershell PnP to particular sites/libraries and their particular permissions.
Since autumn 2024 (source: https://pnp.github.io/powershell/articles/registerapplication.html) a custom "master" appID for all sites is needed to manage things via PnP (Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP PowerShell app for interactive tenant management" -Tenant NAME.onmicrosoft.com -Interactive) and log in interactively as some powerful admin (not sure if anything less than Global Admin work). After it generates the AppID for the management session connection to this AppID so next Powershell PnP commands are from within this master app. (Formerly it used some multi-tenant app which is not possible anymore): Connect-PnPOnline -Url https://NAME.sharepoint.com -Interactive -ClientId your-management-app-id.
Then create the "regular" app to be used with python-o365, either also via PnP or via GUI in Entra ID admin center. Give it Graph API Sites.Selected permissions. (https://learn.microsoft.com/en-us/graph/auth-v2-service)
And then the key ingredient: use this type of command to set particular permissions to a library: The admin who connected to the master app before must be owner of the library or the app must have AllSites.FullControl super-power. (“In order to be able to run this cmdlet, you will need to connect to PnP PowerShell using preferably another Entra ID application registration which will have the AllSites.FullControl permission on the delegate scope on SharePoint set to it and being logged on with a Global Administrator or SharePoint Administrator priviledged account.” Source: https://pnp.github.io/powershell/articles/determinepermissions.html)
Grant-PnPAzureADAppSitePermission -AppId "<Client ID of your Entra ID applicarion registration>" -DisplayName "PnP PowerShell" -Permissions Read -Site <url of the SharePoint Online site to which you will connect>
This command can be repeated for other sharepoint sites so the same app ID + app secret or certificate can be used for multiple sharepoint sites within the same tenant. Permissions can be among "Read, Write, FullAccess" so some sites may be readonly for just downloading files or excel data and some may be for writing.
Setting the app this way is more work but security is much better than giving the app ID/secret full control or any control over ALL sharepoint sites within the tenant. Usually most developers use the API not to interact with all sharepoint sites but perhaps to download or upload stuff to one particular site out of hundreds, hacking and exposing this single key must cause the least damage not allow exfiltrating all tenant data or overwriting any data.
You are correct! I will modify the Readme to state that permission Sites.Selected is also a viable option provided that site permissions are given. Although the specifics on how to do this will remain here for the moment.
Thanks for the issue
I second the Sites.Selected comment. My recent PR came about from working on an integration service for which I was granted Sites.Selected permissions. I was able to list files and get a Drive instance in O365 out of those files and read/write to them. No changes were required to O365 itself.
Given that Sites.Selected worked, I have a feeling the version for OneDrive (Files.Selected?) might work as well, but I was unable to test that since my institution only granted Sites.Selected for my project.
@alejcas I looked now at the documentation (https://o365.github.io/python-o365/latest/usage/sharepoint.html) and still see there the assertion "These are the scopes needed to work with the SharePoint and Site classes." followed by a table with the *.All scopes. No mention there about the recommendation to use more secure approach and prefer the *.Selected scopes.
Please consider fixing the documentation to promote the Selected scope instead of the All scope.
From security standpoint I suggest even warning users to not use the .All scopes unless necessary and unless the API tokens are really well secured and their usage actively monitored, and suggest users if they allowed such broad permissions in their API apps to revoke them and recreate them more securely.
@alejcas I looked now at the documentation (https://o365.github.io/python-o365/latest/usage/sharepoint.html) and still see there the assertion "These are the scopes needed to work with the SharePoint and Site classes." followed by a table with the *.All scopes. No mention there about the recommendation to use more secure approach and prefer the *.Selected scopes.
Please consider fixing the documentation to promote the Selected scope instead of the All scope.
From security standpoint I suggest even warning users to not use the .All scopes unless necessary and unless the API tokens are really well secured and their usage actively monitored, and suggest users if they allowed such broad permissions in their API apps to revoke them and recreate them more securely.
You are right. I will work on this asap
Done in https://github.com/O365/python-o365/commit/b090a165260f2813d29955d32ae0ece15f512190
https://o365.github.io/python-o365/latest/usage/sharepoint.html