Connecting n8n to SharePoint returns 403 on every node action, despite the credential showing as successfully connected. This persists even after switching from Application to Delegated permissions as suggested in other threads.
403 - Forbidden
Access denied
Check your credential
What we’ve already tried
Registered an Azure App with OAuth callback URL per n8n docs
Generated a client secret
Started with Application permissions (Sites.Read.All, Sites.ReadWrite.All) + admin consent → 403
Switched to Delegated permissions (Sites.ReadWrite.All, Files.ReadWrite.All) + admin consent → still 403
Skipped SearchConfiguration.* entirely (couldn’t add them on our app type anyway)
Confirmed the authenticating user has direct SharePoint site access (opens fine in browser)
Reconnected the credential in n8n after each change
Key detail: the user authenticating the OAuth flow has confirmed browser access to the SharePoint site. The issue is not missing site-level membership.
Setup
Detail
Value
n8n hosting
Cloud
SharePoint
SharePoint Online (Microsoft 365)
App registration type
Accounts in any organizational directory (Multitenant)
Auth user
Personal organizational account
Azure setup done by
Sys admin (separate from n8n user)
What I suspect
The OAuth token may not be picking up the correct scopes, or there’s a mismatch between what Azure is issuing and what the SharePoint API expects. The credential connection check passing regardless of permission type suggests n8n’s connection test isn’t actually validating Graph API access.
@Daniel.k96 youve been fighting the wrong layer, its not your Azure permissions, its the scope n8n actually requests. the Microsoft SharePoint OAuth2 credential asks for a narrow scope (basically openid profile offline_access), so the token comes back WITHOUT Sites.ReadWrite.All even though you granted and consented it in Azure, and SharePoint 403s because the token carries no Sites scope. known issue, n8n widened the defaults in a recent build.
fix: open that credential, set the Scope field explicitly to
openid profile offline_access Sites.ReadWrite.All Files.ReadWrite.All
then reconnect so it re-consents with those.
to confirm, paste the access token into jwt.ms and check the scp claim, right now its missing Sites, thats the smoking gun. the redirect-uri and multitenant stuff isnt it, a mismatch breaks the connect step not 403 after.
Yes. Since you are on n8n Cloud, you cannot easily intercept the network traffic, but you can use an HTTP Request Node to “leak” the token to yourself:
Create an HTTP Request node.
Use the same SharePoint credentials.
Set the URL to https://graph.microsoft.com/v1.0/me.
If this works, the token is valid for the user. To see the scopes, you can use a tool like jwt.ms (Microsoft’s official decoder). However, n8n doesn’t expose the raw token in the UI. To get it, you would need to use a tool like Postman to perform the OAuth flow with your Client ID/Secret and then paste the resulting access_token into jwt.ms. Look for the scp (scopes) claim.
Yes. If the Redirect URI were mismatched, the OAuth flow would fail immediately with a Redirect URI mismatch error page from Microsoft before you ever got back to n8n. Since your credential is “Connected,” the URI is correct.
Single-tenant for your use case. While Multitenant can work, it introduces additional consent layers. If you are only accessing data within your own organization, switch to “Accounts in this organizational directory only (Single tenant)”. This ensures that the token is issued specifically for your tenant’s security context and simplifies the permission propagation.
Not applicable for your case since you are on n8n cloud
One more thing worth checking on top of what kjooleng covered: for Application permissions specifically, AAD admin consent alone is not enough for SharePoint Online. Microsoft requires your Azure app to also be explicitly granted access at the site collection level. Your sys admin can do this with the PnP PowerShell command: Grant-PnPAzureADAppSitePermission -AppId <your-app-id> -DisplayName <app-name> -Site ``https://tenant.sharepoint.com/sites/yoursite`` -Permissions Write. Without this step, the credential test passes (because it just validates the OAuth token), but actual SharePoint API calls will 403 because the app isn’t recognized as having site-level access.
try the delegated flow with Single-tenant first before anything else. Multitenant apps often get a generic token that SharePoint’s API rejects even with correct scopes, because the tenant context isn’t pinned. Switch to Single-tenant in Azure, reconnect, and test again.
Also, a quick way to confirm the scope fix worked without Postman: add an HTTP Request node using your SharePoint credential and hit:
If that returns data, your token is valid and scoped correctly. If it 403s too, the token itself is the problem, not the SharePoint node.
One more edge case: if your org has Conditional Access Policies on SharePoint (common in enterprise M365 setups), the OAuth token can pass but still get blocked at the resource level. Ask your sys admin to check the Azure AD sign-in logs for your app, it’ll show exactly why the token was rejected.
This smells like a SharePoint site/resource targeting issue rather than a basic OAuth connection issue. I would verify the exact site ID/drive/list scope n8n is calling, then test the same token against Graph Explorer or a raw HTTP Request node so you can separate “credential works” from “this resource is allowed.” If you share the node operation and sanitized site URL shape, I can help narrow the permission mismatch.