Permissions in Power Automate are easy to get wrong. You build a flow, test it with your account (which naturally has full permissions), and it works perfectly. Then users start running it and get "403 Forbidden" access denied errors. The flow worked for you, so why not for them? The answer is understanding who actually runs each action, and which permissions apply.
The Power Automate permission model is more nuanced than it appears, with different behaviors for connection owners, run-only users, and flows triggered from Power Apps. Let's break down these distinctions so your flows work for everyone, not just administrators.
I will add more information here over time as I find it, so consider this as a "living" reference article to check in case of issues. It's possible as well that some of the issues that you see will be deprecated with SharePoint's evolution so I'll do my best to keep things updated.
Why you get 403 Forbidden errors
When users hit a 403, the message is frustratingly vague: "SharePoint file could not be created due to the access not available for the location." That one message covers several very different causes, and none of them are obvious from the text.
The connection's authentication token has expired
If the flow's connection hasn't been refreshed recently and its token has expired, every user hits permission errors regardless of their own access. We cover reauthenticating further down.
The account running the action lacks library permissions
The account running the action (which might not be the connection owner, more on that shortly) doesn't have Contribute permissions on the target library. Check the account behind the connection, not the person who reported the problem.
MFA requirements changed on a service account
If the connection uses a service account and MFA requirements changed, authentication breaks with no obvious indicator. The flow just starts failing, and the error says nothing about MFA. Worth checking whenever failures begin right after a tenant policy change.
Run-only users are providing their own connections
When "Run-only users will be asked to provide their own connection" is enabled, the flow runs with each user's individual permissions rather than the connection owner's. A user without access to the library will fail even though the flow works perfectly for you.
The filename contains illegal characters
This is the surprising one. A filename validation problem in the SharePoint "Create file" action comes back as a 403 permission error instead of a 400 bad request. Characters like #, %, *, :, <, >, ?, /, and | will do it. If the permissions all check out and the error persists, look at the filename you're generating.
Minimum permission requirements
For basic file operations using the SharePoint "Create file" action, users need Contribute permissions on the target document library. That's the minimum level that allows creating and editing files.
For flows that manage permissions using actions like "Grant access to an item or a folder", users need List owner permissions. Contribute is not enough, and the same applies to "Stop sharing an item or a file".
This matters when a flow creates a file and then sets sharing permissions on it. Each action needs its own level of access.
When the built-in Members and Visitors roles aren't enough, the Roles property also accepts a custom permission level, entered as a custom value:
role:<insertRoleId>
To find the role ID, browse to the role definitions endpoint on your site and look for the role you want:
https://<insertTenant>.sharepoint.com/sites/<insertSite>/_api/web/roledefinitions
Run-only users vs connection owner
This is the critical distinction that catches most people: when you enable "Run-only users will be asked to provide their own connection" on a flow, all actions run with individual user permissions, not the connection owner's permissions.
This setting appears when you share a flow with others. If enabled, each user must provide their own connection to SharePoint, and the flow uses that connection's permissions. If disabled, the flow uses the connection owner's permissions for all users.
One requirement catches people before any of this matters. For flows built on a SharePoint list, run-only users need Edit permission on that list to run the flow at all. However the connections are configured, without Edit on the list the flow won't start for them.
Flows triggered from Power Apps
Here's where a lot of older advice is out of date. Flows triggered from Power Apps run as the calling user by default, but that's a default, not a rule.
With the PowerApps (V2) trigger, the "Connections used" list in the run-only settings lets us switch any connector from "Provided by run-only user" to a specific saved connection. Point SharePoint at a service account there and every run uses that account, whoever pressed the button in the app. The older PowerApps (V1) trigger doesn't offer this, which is where the "Power Apps flows always run as the current user" advice came from. On V1 that limitation is real, and moving to V2 is the fix.
There's a catch worth thinking about first. The moment a connection is pinned to one account, SharePoint stops deciding whether the caller can touch the item, and your flow decides instead. If the app sends an item ID and the flow updates it, anyone with run access can update any item.
A good way to close that gap is an Office 365 Users "Get my profile" action at the top of the flow, with its connection set to "Provided by run-only user". That action runs as the real caller, so we get their identity from Microsoft 365 instead of trusting whatever the app passed in, and we can check it before doing anything else.
Service principal limitations
A service principal gives you application-level authentication that doesn't depend on any user account, which makes it ideal for production automation. There's a catch though: the SharePoint connector still does not support service principal authentication. It only supports user-based OAuth, and Dataverse remains the only standard connector with native service principal sign-in.
The workaround is to use Microsoft Graph through the HTTP connector instead of the SharePoint actions. You register an application in Microsoft Entra ID, give it the "Sites.Selected" Microsoft Graph permission, then grant that application access to the specific sites it needs.
How you grant that site access has changed, and it trips up anyone following an older guide. Azure Access Control Services was fully retired for SharePoint Online on April 2, 2026, so app-only credentials created through the AppRegNew.aspx or AppInv.aspx pages no longer issue tokens, and calls using them fail with 401 Unauthorized. Today you grant site access through the Graph permissions endpoint (/sites/{site-id}/permissions) or with Grant-PnPAzureADAppSitePermission in PnP PowerShell.
Microsoft has also made "Sites.Selected" more granular. The newer "Files.SelectedOperations.Selected", "ListItems.SelectedOperations.Selected", and "Lists.SelectedOperations.Selected" scopes let you scope an application below site level, down to specific libraries, lists, or files.
One misconception worth clearing up: the "Send an HTTP request to SharePoint" action isn't a way around any of this. It runs under its own connection's user context like every other SharePoint action, so it inherits the same permissions.
The whole approach is more work than the standard actions, but it's the only way to get true application-level authentication without depending on a user account.
Authentication token issues
Even when permissions are correct, tokens can expire or become invalid, causing 401 Unauthorized errors. This commonly happens after SharePoint service degradations or migrations.
The fix is manual: reauthenticate or replace the connector connection. Go to the flow's connections, remove the existing SharePoint connection, and add a fresh one.
That forces Power Automate to obtain a new token with current credentials, and it resolves most authentication failures that aren't down to actual permission changes.
Data loss prevention policy blocks
If you encounter the error "Unable to create an OAuth connection due to connection API Policy violation", you're hitting a Data Loss Prevention (DLP) policy that blocks the connection.
DLP policies are configured by tenant administrators in the Power Platform admin center, and control which connectors can be used together and in which environments. You can't bypass them from the flow level. An administrator has to adjust the policy to allow the connections you need.
This is a governance feature, not a bug, designed to prevent sensitive data from flowing to unauthorized connectors. If you need an exception, you'll need to make a business case to your admin team.
Limitations
Even with the right permissions in place, a few hard limits will stop a flow. These are worth knowing before you design around them.
External users cannot be granted access
The "Grant access to an item or a folder" action does not support granting access to external users. If you need to share with someone outside your tenant, use the "Create sharing link for a file or folder" action instead.
Stop sharing removes everything
The "Stop sharing an item or a file" action removes all permissions on that item except for site owners. It isn't selective, so we can't use it to revoke one person and leave everyone else in place.
"Stop sharing an item or a file" wipes every permission on the item. If you only want to remove one user, you'll need to rebuild the remaining permissions afterwards.
Sharing links only work on files and folders
The "Create sharing link for a file or folder" action works on documents and folders in a document library. List items aren't supported.
Unique permissions have a ceiling
Every time a flow breaks inheritance on an item, SharePoint creates a unique security scope. The recommended limit is 5,000 per list or library, and the hard maximum is 50,000. Past that you get "You cannot break inheritance for this item because there are too many items with unique permissions in this list", and performance degrades long before we reach the cap. A flow that grants per-item permissions in a loop gets there faster than we expect.
Final Thoughts
Permission issues in Power Automate come down to one idea: "the flow" doesn't run actions, specific accounts do, and which account depends on how the flow is triggered and configured. Test with an account that has only the permissions your users actually have, not administrator permissions. Decide deliberately whether run-only users need their own connections or a shared one, and if you pin a connection to a service account, remember you've taken the access check away from SharePoint and made it your flow's job. Get those right and your flows will work for everyone, not just you.
Photo by Dave Meckler on Unsplash
No comments yet
Be the first to share your thoughts on this article!