Microsoft Graph scopes — what a deployment can add

The Microsoft connection is one delegated Graph grant per person (EaGraphAuth): it already owns consent, the encrypted refresh token and the token refresh. A feature that needs another part of Graph asks for one more scope on that grant. It does not need a package, a second app registration or a second connection (maintainer, 2026-11-04).

Adding a scope

Set the key in the deployment configuration. Entries are separated by spaces, commas or semicolons:

Authentication:Microsoft:AdditionalGraphScopes = Files.Read.All Sites.Read.All

As an environment variable it is Authentication__Microsoft__AdditionalGraphScopes. A short name and https://graph.microsoft.com/Files.Read.All are the same scope. An instance that sets nothing requests exactly what it did before.

The key belongs to the instance's operator, not to the person at the consent screen, because the token it produces is the one every agent tool and script of that person uses.

🚨 Adding a scope asks every person on the instance to reconnect once, and until they do, their mail, calendar and Teams connection reads as not connected. Entra refuses to redeem a refresh token for scopes nobody consented to, so the connection shows the reconnect link (/auth/ea/connect) rather than failing on every call. Plan the change. Removing a scope disturbs nobody: a refresh may ask for a subset of what was consented.

Tenant policy still applies. A scope that needs an administrator's approval shows "Need admin approval" until a tenant administrator has consented once. The grant stays delegated: it never reaches further than the connected account's own permissions.

🚨 Try a new value on a non-production instance first. Only the shape of a name is checked, not that Graph has such a permission: Microsoft publishes no list a portal could validate against, and a copy here would refuse the next real permission. A misspelt Files.Read.Al passes, every existing grant then reads as not connected, and the reconnect fails at Entra until the key is corrected.

What is refused

These are left out and logged as an error naming the key, because one bad entry would otherwise fail the whole token request and take the mailbox down with it:

Reading SharePoint

Do not replicate. SharePoint already indexes its documents, so copying them into the mesh or building a second index adds a store that drifts. Search there, and read the file live:

POST https://graph.microsoft.com/v1.0/search/query

{ "requests": [ { "entityTypes": ["driveItem"], "query": { "queryString": "annual report 2026" } } ] }

GET https://graph.microsoft.com/v1.0/drives/{driveId}/items/{itemId}/content

The token comes from IEaGraphAuth.GetAccessToken(user).

The Executive Assistant's tools SearchSharePoint and ReadSharePointFile (ExecutiveAssistantPlugin, module MeshWeaver.Mail.MicrosoftGraph) wrap exactly these two calls. The search returns names, drive and item ids, links, sizes and snippets; the read hands the model the file's text — a PDF, Word or Excel file through the platform's text extractor, a text file decoded, any other binary file described and not read — up to 20 MB, the listed size deciding before the stream is opened. A partly scanned PDF is handed over as incomplete, naming the pages no OCR read. The read tool is [HiddenTool]: the chat client drops a hidden tool's call and result instead of forwarding them to the thread's tool-call log, on the agent's own round and on a round it received by hand-off alike, so a document's text reaches the model within the round and never lands in the mesh. A 403 from Graph is answered with the two scopes, this key and the reconnect link, because that is the operator's change, not the user's.

What was not established