2 minute read

If you want to programmatically set permissions to documents in SharePoint - it is quite simple, just use Microsoft Graph. If you want to set those permissions to list items, it is slightly more complicated than just calling Microsoft Graph.

We have a customer who requires to have very restrictive permissions on items in a SharePoint list. Like mentioned above, this is fairly simple when using document libraries, but when you want to achieve the same with lists… Well, hold your hats, it’s more complex.

So first of all, you may want to break inheritance. In order to do that, you can call a nice API endpoint within SharePoint:

HTTP POST

_api/web/lists/getByTitle('<list_name>')/items('<item_id>')/breakroleinheritance(copyRoleAssignments=false, clearSubscopes=true)

This is obviously optional, because you may just want to add explicit permission to the item, but in most cases, you will want to break it. Also notice, that we break inheritance with copyRoleAssignments=false which means that the assignments from upstream item will be discarded.

Next, you need to convert the Azure AD Group to SharePoint’s principal. Objects in Azure Active Directory (AAD) are primarily identified by a GUID also referred to as objectId or id.

You can obtain this ID from Azure AD Portal, Microsoft 365 Admin (when you open specific group, take the guid from the address bar) or you can search it via Microsoft Graph or using Microsoft Flow’s Office 365 Group connector and others.

In order to convert the Group ID to Principal ID (internal SP identifier) you need to call the following endpoint in SharePoint:

HTTP GET

_api/web/siteusers('c:0t.c|tenant|<your_aad_group_id>')

Simply replace <your_aad_group_id> with your group’s ID. The object returned is going to be a complex one, so you may want to check the response and JSON parse it, so you can work with it more easily.

Now you have to set the actual permissions:

HTTP POST

_api/web/lists/getByTitle('Test')/items('4')/roleassignments/addroleassignment(principalid=<previousrequest['d']['Id']>,roledefid=<your_role_id>)

The <previousrequest['d']['Id']> is an integer (whole-number) obtained with the previous request for Principal ID.

There are some well-known role IDs, but you can also make a custom one, in case of that, just call /_api/web/roledefinitions to get them for your site, or pull it from the URL when modifying the role.

Permission Value
Full Control 1073741829
Contribute 1073741827
Read 1073741826

All in all, I just wish that Microsoft made it as easy as with Document Libraries, because this is quite obscure…

Answer also posted to the Stack Exchange thread.

Update:

In case the principal (group) doesn’t exist in the site yet, you need to provision it in the site via EnsureUser method. It will go to AAD behind the scenes and create a SharePoint principal for it. Fun!

So first, obtain the FormDigestValue from /_api/contextinfo endpoint. This is a regular GET request. Next, call _api/web/ensureuser('c:0t.c|tenant|<your_aad_group_id>'), it is a POST request, and you need to include the X-RequestDigest header with value obtained from the contextinfo request. Then simply send it and the group will get provisioned. It will also contain the Id field which you can use directly.

Comments

Shawn Eingle

Thank you for this post; it was very helpful! I wanted to mention I bumped into an error with the call to contextinfo; appears PUT is the only supported method. After that change, the call was successful. Thanks again!

Thomas

Thank you very much. I can’t describe the trouble I have had until I saw you blog post. I do the following: _api/web/ensureuser(‘c:0o.c|federateddirectoryclaimprovider|bcd0d484-c399-4282-ba70-095b6fdcebdb’)

josef

Amazing post. I have been searching for a long time to grand ADD groups direct permissions to an SharePoint library with Power Automate. Your post was the final key to solve this issue. Keep up the good work

To submit comments, go to GitHub Discussions.