“I’d like to set unique permissions on a SharePoint folder I just created with Power Automate, but the ‘Stop sharing…’ action throws an error.”
“Folder is not supported for this operation.”
Power Automate has an action ‘Stop sharing an item or a file’ in SharePoint that will remove all permissions. It’s easy to manage permissions with this action, but only if you work with files or items. If you need to set permissions on a SharePoint folder, e.g. to create private folders, the action won’t help. It’ll just throw an error and stop the flow: “Folder is not supported for this operation.”.
How do you then remove the existing folder permissions to assign new ones?
Remove folder permissions with HTTP request
You’ll have to go back to the permissions management with HTTP requests. There’re three HTTP requests you’ll need to remove the permissions.
Note: all the code snippets below contain placeholders inside < … >, replace them including the < and >.
1. Break permissions inheritance
The first step is to break inheritance of the default permissions. Until you break the inheritance you can’t change any permissions as they’re managed on higher level than the folder.
Method: POST
Uri:
_api/web/lists/getByTitle('<LibraryName>')/items(<FolderID>)/breakroleinheritance(true)
2. List all users with permissions
The second step is to get all the permissions on the folder. The HTTP request in the 3rd step will need to know whose permissions it should remove, therefore, it’s necessary to get a list of all these users.
Method: POST
Uri:
_api/web/lists/getByTitle('<LibraryName>')/items(<FolderID>)/roleassignments
The output of this request will be a JSON with ‘PrincipalId’ of all the users with access to the folder. Add the ‘Parse JSON’ action with schema from the output to get the ‘PrincipalId’ dynamic content for the step 3.
3. Remove all permissions
The last step is to remove the permissions. Here you’ll use the ‘PrincipalId’ to remove all the existing permissions from the folder. Since there can be multiple users with access to the item, Power Automate will add the ‘Apply to each’ around it automatically.
Method: POST
Uri:
_api/web/lists/getByTitle('<LibraryName>')/items(<FolderID>)/roleassignments(<PrincipalId>)
Headers:
X-HTTP-Method : DELETE
After the ‘Apply to each’ the folder permissions will be empty and you can start adding the permissions you need. And this time you can use the ‘Grant access to an item or a folder’ action. Unless it’s a SharePoint group, that one always needs an HTTP request.
Summary
It’s sad that Power Automate doesn’t allow you to remove SharePoint folder permissions in the same way as from an item or a file. But as most of the other times, there’s a workaround with a bit of coding knowledge.
When you run the flow above, the only users with access to the folder will be the SharePoint site owners. All the other users, including the users with full control, must be then added back.
And if you’d like to get fancy, you could process the response from step 2 without the ‘Parse JSON’.
Thanks for your post Tom, it’s pointed me in the right direction. I have the opposite issue where I’ve used the ‘Stop sharing an item or a file’ to remove a sharing link but because inheritance is still disabled on the file, I’ve reached the 50k unique permissions limit on the document library. Hopefully Microsoft support can help me restore the inheritance on the files I no longer need shared. Thanks again.
Hello Dave,
if you need to restore permissions inheritance then it’s doable using the ‘Send an HTTP request to SharePoint’ action.
Method: POST
Uri: _api/Web/lists/getByTitle('listName')/items(itemId)/ResetRoleInheritance()
Thats really helpful – thanks!
I noticed the people who have been removed from the list/library can still access the site, any suggestions for that?
Hello Bob,
the article is on removing them only from a specific folder, not from the whole site. There might be some HTTP request to remove them from the site but I don’t know what it’d look like atm.
It worked for me but i have done some small changes while getting role assignments and while removing permissions.
To get role assignments i have used the below uri:
_api/web/lists/getByTitle(‘document libaray name’)/items(275)/roleassignments?$expand=Member,RoleDefinitionBindings
To remove folder permission uri:
_api/web/lists/getByTitle(‘Document library name’)/items(275)/roleassignments/removeroleassignment(principalid=, roledefid=)
Hey Tom, thanks for all your tutorials.
I’ve got an issue with this one, the remove permissions action actually deletes my folder somehow. So basically it does not remove the permissions but removes the whole folder on the first “apply to each” loop for the first PrincipalId. Any idea why this could happen?
The first action that doesn’t throw an error (the action that deletes the folder) has this
URI:_api/web/lists/getByTitle(‘CoFolders’)/items(29)/roleassignments(3)
and this Headers:
Key: X-HTTP-Method
Value: DELETE
the DocumentLibrary (CoFolders), Folder ID (29) and the UserID (3) are correct.
It just deletes the folder that I want to remove the Users Permissions…
Hmm nevermind, I got it to work by using the Uri: _api/web/GetFolderByServerRelativeUrl(‘CoFolders/@{triggerOutputs()?[‘body/Title’]}’)/ListItemAllFields/RoleAssignments/GetByPrincipalId(@{items(‘Apply_to_each_-_Remove_Permissions’)?[‘PrincipalId’]})
and using DELETE in the Method Field instead of POST and X-HTTP-Method, not sure why this one works for me but maybe it’s because of our strange development environment for power automate…
Hello Caspar,
good to know, thank you for sharing your solution.
Could you please help! to remove the access to a folder?
in the apply to each I’m greeting below error
The execution of template action ‘Apply_to_each’ failed: the result of the evaluation of ‘foreach’ expression ‘@body(‘Parse_JSON’)?[‘d’]?[‘results’]’ is of type ‘Null’. The result must be a valid array.
and the Parse Json I’m getting
{
“d”: {
“BreakRoleInheritance”: null
}
}
Hello Raj,
the ‘Apply to each’ is processing outputs from the 2nd HTTP request that lists all the permissions, not the first one that just breaks the permissions.
Could you elaborate on this? I’m having the same issue as Raj my Parse JSON output is below
{
…long json schema…
}
Sorry for posting the Schema, my JSON output is below
{
“d”: {
“results”: [
{
“__metadata”: {
“id”: “/_api/Web/Lists(guid’43129d07-f467-4dda-bcd7-1bc9787220fa’)/Items(7)/RoleAssignments/GetByPrincipalId(3630)”,
“uri”: “/_api/Web/Lists(guid’43129d07-f467-4dda-bcd7-1bc9787220fa’)/Items(7)/RoleAssignments/GetByPrincipalId(3630)”,
“type”: “SP.RoleAssignment”
},
“Member”: {
“__deferred”: {
“uri”: “/_api/Web/Lists(guid’43129d07-f467-4dda-bcd7-1bc9787220fa’)/Items(7)/RoleAssignments/GetByPrincipalId(3630)/Member”
}
},
“RoleDefinitionBindings”: {
“__deferred”: {
“uri”: “/_api/Web/Lists(guid’43129d07-f467-4dda-bcd7-1bc9787220fa’)/Items(7)/RoleAssignments/GetByPrincipalId(3630)/RoleDefinitionBindings”
}
},
“PrincipalId”: 3630
},
…
]
}
}
Hello Erik,
the output looks fine, just make sure your Parse JSON is properly configured.
Hello Tom!
I’ve setup a flow like this and most of the time it works fine, however sometimes I get an error in the apply to each step -> “Can not find the principal with id: xx.”
When I restart the workflow manually, it usually works on the 2nd or 3rd attempt, however this is not really great since sometimes folder permissions are wrong until a flow run is successful.
Do you know this issue and maybe even a solution?
Thank you very much!
Hello Nico,
I never encountered this, maybe there’re users who have assigned permissions through different group? I’d check the output of the /roleassignments HTTP request to check if there aren’t any duplicate principalIds.
Hi Tom.. Excellent post. I have a slightly different requirement.
First, the security groups always change name and we can assume sharing links are used.
I need to keep only the owners full access access to the folder and modify all other users to have read only. I have tried polling users, groups and roleassignment to no avail.
Any suggestions would be appreciated !
Hello Martin,
you could list all permissions using /roleassignments, loop through the permissions and for each of them remove the current permission and add read instead. That way you’ll reduce everyone’s permissions to Read only. After that’s finished you can add Full Control back to the Owners group (which is hopefully the same every time).
if anyone of you has this flow created (Revoke permission at folder level) please reply to this message, tried everything and I’m frustrated. or mail me at nnandan@oceaneering.com.
Thank you so much in advance
Hi Tom,
Is it possible set unique permissions on subfolder level?
Instead of “Site/Library/Folder” i want to create unique permissions on this level: “Site/Library/Folder/Subfolder”.
I tried to change this URL:
_api/web/lists/getByTitle(”)/items()/breakroleinheritance(true)
To:
_api/web/lists/getByTitle(”)/items()/items()/breakroleinheritance(true)
But that did not work.
I really appreciate your time.
With kind regards, Luuk T.
Hello Luuk,
you should be able to do that if you enter the subfolder id.
_api/web/lists/getByTitle(listName)/items(subfolderID)/breakroleinheritance(true)
Hi Tom,
Thanks for the Excellent post,
I/m having an issue removing unique permission from folders an all the sub folders and files under.
_api/web/lists/getByTitle(‘Document library’)/items(folder ID)/ResetRoleInheritance()
above Uri only remove unique permission on a particular folder only.
do you know how can i remove all the sub folder and files under the root folder?
Thanks in advance
Hello John,
if there’s no inheritance to the folder and each subfolder/file in that folder have their own unique permissions then you must process them one by one, folder by folder. It’s the same as if you wanted to restore the permissions manually.
Hi,
I need to delete files from folders and subfolders which are older than 4years can you please help. These files have a lot of unique permissions can we remove permissions only for the deleting file and not for the rest?
Thanks in advance.
Hello Anish,
you don’t care about permissions when you delete a file. As long as you have access to the file you can just delete it, no matter the permissions.
Thanks for this incredibly helpful resource. My workflow succeeded using the steps above but the Owners group was removed as well. I can probably just run another send HTTP request action to add them back but it shouldn’t have removed the Owners group on the folder, correct?
Hello Amanda,
the HTTP requests will remove all groups, it’s the dedicated ‘Stop sharing…’ action (that can’t be used on folders) that keeps the owners.
Hi Tom. First of all, thank you for the amazing resource.
I’ve done it all but when i check the acess it still have the group access.
My goal was to remove the visitors and members of the channel (folder) so the owner (creator) can add the person and know one else have acess.
Is this possible?
Thanks!
Hello Vasco,
that was the goal of the solution, did you follow all the steps? It should remove all permissions – users, groups, even the owners.
I tried this , but it is deleting my folder in SharePoint, instead of removing the role permissions. Any idea on that?
Thank you so much! It works!
Thanks for the article and clear presentation.
I found a problem removing the SPO groups’ permission, and a solution which looked at removing the specific role assignment in a similar fashion via the HTTP request:
_api/web/lists/getbytitle(”)/items()/RoleAssignments/RemoveRoleAssignment(principalId=)
where the is the variable supplied by the loop in which you return the assigned principals. My use case created a folder within the flow and thus came with the inherited groups pre-assigned. With this REST query I was able to strip those out effectively.
Hello Paul,
thank you for sharing this, although it seems wordpress replaced some characters from the response.
Hi Tom,
Thanks for this, really useful and well-explained guide.
Unfortunately, I too am getting the error in the Apply to each at the last stage.
ExpressionEvaluationFailed. The execution of template action ‘Apply_to_each’ failed: the result of the evaluation of ‘foreach’ expression ‘@body(‘Parse_JSON’)?[‘body’]?[‘d’]?[‘results’]’ is of type ‘Null’. The result must be a valid array.
I’ve checked my roleassignments HTTP request, which seems to output very similar to yours.
{
“d”: {
“results”: [
{
“__metadata”: {
“id”: “/_api/Web/Lists(guid’002a002a-acbb-4b12-b52d-cc00f9ca5ce9′)/Items(124)/RoleAssignments/GetByPrincipalId(3)”,
“uri”: “/_api/Web/Lists(guid’002a002a-acbb-4b12-b52d-cc00f9ca5ce9′)/Items(124)/RoleAssignments/GetByPrincipalId(3)”,
“type”: “SP.RoleAssignment”
},
“Member”: {
“__deferred”: {
“uri”: “/_api/Web/Lists(guid’002a002a-acbb-4b12-b52d-cc00f9ca5ce9′)/Items(124)/RoleAssignments/GetByPrincipalId(3)/Member”
}
},
“RoleDefinitionBindings”: {
“__deferred”: {
“uri”: “/_api/Web/Lists(guid’002a002a-acbb-4b12-b52d-cc00f9ca5ce9′)/Items(124)/RoleAssignments/GetByPrincipalId(3)/RoleDefinitionBindings”
}
},
“PrincipalId”: 3
[plus a few more]
Interestingly, where you have the Site field in the ‘Apply to each’ HTTP Request item, yours shows a function outputs(..) whereas I have to set the Site to be as you would expect, my site.
Any suggestions? Thanks.
Ben
Thanks for your clear instructions, but I can’t get it to work. I think this is because I’m trying to change a Document Set, rather than a file or folder. When someone adds/edits a Document Set, I want a condition checked on one of the columns. If it’s true, I need inheritance to be stopped and apply permission only to a couple of people.
When I try your initial Uri, I get a 400 error with the message: “The expression \”web/lists/getByTitle(‘My Document Sets’)/items({\”@odata.etag\”:\”/\”12/\”\”,\”ItemInternalId\”:\”2\”,\”ID\”:2,\”Title\”:\”XYZ\”,\”Created\”:\”2024-05-13T05:29:36Z\”,\”Owner\”:[{\”@odata.type\”:\”\” is not valid.\r\nclientRequestId: 49869c78-bc95-4dfc-be90-840527ca4344\r\nserviceRequestId: bb3530a1-20e0-3000-6835-47ad5a96c33a”,
Tom,
Thank you for this! Helps greatly.
Do you know how to remove certain users instead of all? Currently trying to remove 5 specific users from multiple folder in a single Library with same name but keep the unique permissions for the remainder users.