Scoping Microsoft Graph Permissions for a SharePoint MCP Server to Least Privilege with Sites.Selected
Replace tenant-wide application permissions such as Sites.Read.All or Sites.ReadWrite.All on the MCP server's app registration with Sites.Selected. Then grant the app access to each named site at the lowest role its tools need (read, write, or manage), and test against granted and non-granted sites. Sites.Selected bounds which sites the identity can reach. It does not limit which tools the agent calls, what content comes back, or what evidence exists, so those need runtime enforcement on tool calls.
Implementation sequence
- 1
1. Inventory tool needs
List each MCP tool, the SharePoint operations it performs, and the sites it must touch. Separate read-only retrieval tools from tools that create or modify content.
- 2
2. Register a dedicated app
Use one app registration for the MCP server, not a shared one. Use application permissions deliberately, knowing the server will then act under its own identity rather than the user's.
- 3
3. Replace broad permissions
Add Sites.Selected, remove Sites.Read.All and Sites.ReadWrite.All, and record the removal with date and approver. Confirm no other broad permission on the registration still covers site content.
- 4
4. Grant per-site access
Using an administrative identity separate from the MCP server, grant the app a role on each approved site. Choose read, write, or manage per site, not one role for all.
- 5
5. Secure the credential
Prefer certificate-based credentials held in a managed secret store over shared secrets. Limit who can read or rotate them, since the credential is the identity.
- 6
6. Verify effective access
Run representative tool calls against granted and non-granted sites, and against operations above the granted role. Keep the results as evidence.
Verification checklist
- A call to a granted site at the granted role succeeds for each tool.
- A call to a site that was never granted fails, for every tool that takes a site input.
- A write attempt on a read-only site fails.
- No tenant-wide site permission remains on the registration, and the removal is recorded.
- The site list, roles, approver, and review date are documented in one reviewable place.
- Credential ownership, rotation, and access to the certificate are documented and tested.
What Sites.Selected constrains, and what it does not
A SharePoint MCP server usually runs as an application, not as a signed-in user. When that application holds Sites.Read.All or Sites.ReadWrite.All, every site in the tenant is in scope for it. Any tool call the agent makes inherits that reach, including a call produced by prompt injection or a misdirected instruction. The user's own access does not trim the result, because the server acts as itself.
Sites.Selected changes the starting position. The permission on its own does not name any sites. Access exists only where an administrator has explicitly granted the application a role on a specific site. That turns the app registration from an open door into a reviewable list of sites and roles, which is the form least-privilege assessments expect: a list of assigned access authorizations plus the configuration settings that implement it.
This is the principle behind NIST SP 800-53 control AC-6, which applies least privilege to system processes as well as people. An MCP server is such a process. Its identity should operate at no higher privilege than the business function requires.
The boundary is the site and the role. Inside a granted site, the identity can do whatever the role allows. Sites.Selected does not decide which MCP tools are exposed, which documents a call returns, or whether anyone can later show what was read. Treat it as the identity layer of a larger design, not the whole design.
Choosing the role and the site list
Start from the lowest role. Most retrieval-focused MCP servers need read only. Grant write only for sites where a tool must create or update content, and treat manage as exceptional, because it extends beyond content operations. If one server needs read on many sites and write on one, record that as separate per-site decisions rather than raising the whole server to write.
Consider splitting a server into two registrations when read and write tools have different risk profiles. A read-only retrieval server and a separate content-update server each carry a smaller blast radius than one identity holding both. The cost is more registrations to review.
The site list is a governance artifact. Define who approves additions, who reviews the list and on what schedule, and where removals are recorded. A site should enter the list because a named tool needs it, not because it is convenient. Sensitive content that agents do not need should stay out of scope, and site-level boundaries are only useful if sensitive material is not mixed into granted sites.
If a site is too coarse a boundary, for example because one site mixes agent-appropriate and restricted libraries, the safer fix is often structural: move the agent-relevant content to its own site and grant that. Selected-permission models narrower than a site may also fit, but validate their behavior in a test tenant before relying on them.
Residual risk and where runtime enforcement fits
After Sites.Selected is applied, the server can still be misused inside its granted sites. A prompt-injected instruction can ask a retrieval tool for the most sensitive document in a granted site, or ask a write-capable tool to alter content it can legitimately reach. The identity allows both, because the identity cannot see intent, arguments, or the content in the response.
Two gaps are worth stating plainly. First, agent behavior is hard to predict at deployment, so a static grant cannot fully anticipate which actions are needed. Second, an agent that combines results from several tools may produce a response with a different sensitivity than any single input. Evaluating the returned content, not just the access that produced it, is part of the control design.
Zero trust and attribute-based access control models point to the same answer: decide per request, using attributes of the subject, the object, the operation, and context. Applied to MCP, that means evaluating each tool call, which is a design inference rather than something Graph provides.
Trussed enforces policy in the execution path on MCP server tool calls: allow, redact, or block an individual call, and escalate for human approval where required. Enforcement runs at runtime, not reviewed after the fact, and it generates audit-ready evidence of what was permitted and what happened. That complements the Graph grant. Sites.Selected limits where the identity can go, and runtime policy limits what each call may do and return. Least-privilege assessments also examine audit records, so decide in advance which records must exist, how long they are retained, and who can read them.
Layers of least privilege for a SharePoint MCP server
Identity scope
Sites.Selected replaces tenant-wide site permissions on the app registration.
Per-site grant
Each named site is granted at read, write, or manage.
Verification
Granted sites succeed, non-granted sites fail, and results are recorded.
Tool-call policy
Runtime checks decide what each call may do and return.
Evidence
Records show what each call accessed.
Pair identity scoping with tool-call enforcement
See how policy is enforced on MCP server tool calls and how audit-ready evidence is produced for a regulated enterprise.
Request a DemoHow does your AI governance program compare?
See where your program has gaps in less than 2 minutes.