The process of building custom applications and tools that interact with Microsoft SharePoint, including SharePoint Online in Microsoft 365.
Use SharePoint REST or CSOM with a certificate-authenticated Entra ID app: Microsoft Graph, including its beta permission APIs, does not enumerate members of SharePoint-specific Owners, Members, and Visitors groups.
Recommended backend design
1. Configure app-only authentication for SharePoint
For SharePoint Online, use an Entra ID application rather than the retired SharePoint Azure ACS app-only model, which stops working on April 2, 2026.^1^
In Entra admin center → Applications → App registrations:
- Register the backend application.
- Under API permissions, add the required application permission to the SharePoint resource, not only Microsoft Graph.
- Grant tenant admin consent.
- Under Certificates & secrets → Certificates, upload a certificate.
- Request a client-credentials token for:
https://{tenant}.sharepoint.com/.default
Certificate authentication is required for Entra app-only access to SharePoint CSOM/REST.^2^
Use least privilege where possible. With Sites.Selected, assigning the scope alone grants access to no sites; the app must also receive an explicit role on each target site.^3^
A Graph token is not interchangeable with a SharePoint token. Send the SharePoint-audience token to https://{tenant}.sharepoint.com/sites/{site}/_api/....
2. Enumerate Owners, Members, and Visitors
Do not derive group names by appending “Owners” or “Members”; sites can rename or customize groups. Resolve the associated groups first, then enumerate their users.
The SharePoint API exposes site groups through /_api/web/sitegroups, and CSOM exposes associated-group properties.^4^
Typical REST requests are:
GET https://{tenant}.sharepoint.com/sites/{site}/_api/web/associatedownergroup/users
GET https://{tenant}.sharepoint.com/sites/{site}/_api/web/associatedmembergroup/users
GET https://{tenant}.sharepoint.com/sites/{site}/_api/web/associatedvisitorgroup/users
Authorization: Bearer {sharepoint_access_token}
Accept: application/json;odata=nometadata
If associated-group navigation is unsuitable, retrieve /_api/web/sitegroups, identify each group by ID, and query its users. SharePoint REST read operations use GET, and its endpoint model follows CSOM objects and members.^5^
This can be implemented with any HTTP library, including Python:
import requests
def get_group_users(site_url, group_kind, token):
endpoint = f"{site_url}/_api/web/associated{group_kind}group/users"
response = requests.get(endpoint, headers={
"Authorization": f"Bearer {token}",
"Accept": "application/json;odata=nometadata",
}, timeout=30)
response.raise_for_status()
return response.json()["value"]
owners = get_group_users(site_url, "owner", sharepoint_token)
members = get_group_users(site_url, "member", sharepoint_token)
visitors = get_group_users(site_url, "visitor", sharepoint_token)
Alternatively, use Microsoft.SharePointOnline.CSOM in C#. CSOM officially supports loading a SharePoint group’s Users collection.^6^
var web = context.Web;
context.Load(web,
w => w.AssociatedOwnerGroup.Users,
w => w.AssociatedMemberGroup.Users,
w => w.AssociatedVisitorGroup.Users);
await context.ExecuteQueryAsync();
var owners = web.AssociatedOwnerGroup.Users;
var members = web.AssociatedMemberGroup.Users;
var visitors = web.AssociatedVisitorGroup.Users;
Attach the SharePoint access token to ClientContext.ExecutingWebRequest, as shown in Microsoft’s certificate-based CSOM app-only pattern.^2^
Check whether one user has site access
Use SharePoint’s effective-permission operation rather than checking only the three associated groups:
GET https://{tenant}.sharepoint.com/sites/{site}/_api/web/getusereffectivepermissions(@user)?@user='{encoded-login-name}'
Authorization: Bearer {sharepoint_access_token}
Accept: application/json;odata=nometadata
The corresponding supported CSOM operation is:
var result = context.Web.GetUserEffectivePermissions(userLoginName);
await context.ExecuteQueryAsync();
bool canView = result.Value.Has(PermissionKind.ViewPages) ||
result.Value.Has(PermissionKind.ViewListItems);
Web.GetUserEffectivePermissions returns BasePermissions for the specified identity.^7^ Equivalent operations exist for lists and list items when checking access below site scope.^8^
Do not treat membership in Owners/Members/Visitors as a complete access report. A user can receive access through direct role assignments, custom SharePoint groups, Entra groups, or inheritance; lists, folders, and items can also have unique permissions.^9^ Therefore:
- “Can user X access this site?” → call
GetUserEffectivePermissions. - “Who is in the three associated groups?” → enumerate those groups’
Users. - “List every effective user with access” → there is no single complete Graph report API. Traverse role assignments and inheritance at the required scopes, enumerate SharePoint groups, and separately expand any Entra groups through Graph. This can become expensive and should be bounded to the scopes your tool actually evaluates.
For Entra-group expansion, use Graph /groups/{id}/members with application permission such as GroupMember.Read.All. Additional permissions may be required to return full properties instead of only object type and ID.^10^
Graph and beta boundary
Graph can expose permission objects for supported resources—for example, the beta list-permissions endpoint—but beta APIs are not supported for production, and permission objects do not provide membership expansion for SharePoint site groups.^11^ Graph group membership APIs apply to Entra/Microsoft 365 groups, not SharePoint SPGroup objects.
PowerShell is therefore unnecessary. A practical MCP backend can use:
- MSAL + HTTP/SharePoint REST in Python, C#, Java, or Node.js; or
- MSAL.NET + Microsoft.SharePointOnline.CSOM in C#;
- plus Microsoft Graph only for site discovery and expansion of Entra groups encountered in SharePoint assignments.
References
- Accessing SharePoint using an application context, also known as app-only
- Granting access via Entra ID Application Permissions
- Understanding Resource Specific Consent for Microsoft Graph and SharePoint Online
- SharePoint .NET Server, CSOM, JSOM, and REST API index
- Get to know the SharePoint REST service
- Retrieves and lists all users in a SharePoint group named 'Members' using the SharePoint .NET Framework client object model (CSOM).
- Web.GetUserEffectivePermissions(String) Method-Definition
- List.GetUserEffectivePermissions(String) Method-Definition
- Authorization, users, groups, and the object model in SharePoint
- Overview of Microsoft Graph permissions
- Get permission on a list