SharePoint / OneDrive Sensor
What it ingests
Documents from SharePoint document libraries — and, when you opt in, from users' personal OneDrive libraries. Each file becomes one CreativeWork in the ontology, attributed to whoever last modified it, so the graph links the people writing documents to the people shipping code and running meetings.
Body text is extracted from text-like formats (.md, .txt, .csv, .json, .html, …). Other files — including Office .docx / .pptx / .xlsx, which are ZIP containers rather than text — still land as an entity with their title, URL, author and library, just without a body.
Site pages, SharePoint lists, and sharing/permission signals are out of scope.
Credential
References the same microsoft_graph credential as the Microsoft Teams sensor — a JSON object describing an Entra ID app registration:
{
"tenant_id": "72f988bf-86f1-41af-91ab-2d7cd011db47",
"client_id": "a1b2c3d4-e5f6-4789-8abc-def012345678",
"client_secret": "abc8Q~…"
}Already running the Teams source? Reuse that credential.
Point this source at the same vault row. A tenant that has connected Teams does not need a second app registration — only two additional consented permissions on the one it already has (below). That is why the credential type was named for Graph rather than for Teams.
Config fields
| Key | Required | Notes |
|---|---|---|
site_ids | no | Site URLs or site IDs to ingest, newline- or semicolon-separated. Blank crawls every site in the tenant. |
cloud | no | global (default) for commercial Microsoft 365 — including GCC, which is served by the commercial endpoints — usgov for GCC-High (L4), or usgovdod for DoD (L5). |
file_extensions | no | Comma-separated extensions to restrict ingestion to (e.g. md, pdf, docx). Blank ingests every file. |
include_personal_sites | no | true to also crawl every user's personal OneDrive. Off by default — see below. |
Do not separate site_ids with commas
A SharePoint site ID is itself a comma-joined triple:
contoso.sharepoint.com,bf6fb551-d508-4946-a439-b2a6154fc1d9,65a04b8b-1f44-442b-a1fc-9e5852fb946cThat is the exact string Graph returns, so it is the one you are most likely to paste. Splitting on commas would shred it into three unusable fragments, so this field splits on newlines and semicolons instead. Plain site URLs (https://contoso.sharepoint.com/sites/Engineering) work too and are easier to read.
Multi-geo. Leave site_ids blank to list sites in every geography. If the source looks healthy and a site you need is still missing, set site_ids to that site's URL.
About include_personal_sites
Graph's tenant-wide site enumeration returns each user's personal OneDrive alongside the team sites, flagged isPersonalSite. Crawling them multiplies the job by your headcount and reaches into individual employees' document stores, so Corveil skips them unless you ask. Turn it on deliberately, and expect the first crawl to take considerably longer.
Provider-side setup
1. Use (or create) the app registration
If you already configured the Teams source, reuse that app registration and skip to step 2. Otherwise follow the Teams guide's app-registration steps — the registration itself is identical; only the permissions differ.
2. Add application permissions and grant admin consent
In Entra ID → App registrations → your app → API permissions, add these Application (not Delegated) permissions and click Grant admin consent:
| Permission | Why |
|---|---|
Sites.Read.All | Enumerate the tenant's sites |
Files.Read.All | List document libraries, read their changes, download file bodies |
Both are ✅ available in GCC-High (L4) and DoD (L5), as are every endpoint this source calls.
Why not Sites.Selected?
Grant Sites.Read.All. Sites.Selected does not let this sensor list sites. To limit which sites are ingested, set site_ids.
3. GCC-High / DoD tenants
L4 and L5 are different hosts. Set cloud to usgov for GCC-High and usgovdod for DoD:
cloud | Graph host | Token scope |
|---|---|---|
usgov | graph.microsoft.us | https://graph.microsoft.us/.default |
usgovdod | dod-graph.microsoft.us | https://dod-graph.microsoft.us/.default |
Both authenticate against login.microsoftonline.us. The cloud value has to match the tenant: a GCC-High registration will not read a commercial or DoD tenant, and the reverse is also true. Plain GCC (not GCC-High) uses the commercial endpoints — set cloud to global there.
Wire-up
POST /api/sensors
Whole tenant:
{
"sensor_type": "sharepoint",
"name": "Contoso SharePoint",
"config": {},
"credentials": { "graph_credential": "<microsoft_graph credential id>" }
}Specific sites, text documents only:
{
"sensor_type": "sharepoint",
"name": "Engineering docs",
"config": {
"site_ids": "https://contoso.sharepoint.com/sites/Engineering\nhttps://contoso.sharepoint.com/sites/Architecture",
"file_extensions": "md, txt, pdf, docx"
},
"credentials": { "graph_credential": "<microsoft_graph credential id>" }
}GCC-High:
{
"sensor_type": "sharepoint",
"name": "Agency SharePoint",
"config": { "cloud": "usgov" },
"credentials": { "graph_credential": "<microsoft_graph credential id>" }
}Verify
Run Test connection. It enumerates the sites in scope and lists each one's document libraries, so a missing consent or a mistyped site URL fails here rather than silently ingesting nothing.
A partially-working configuration is reported without stopping the source: if one site of five cannot be read, the other four keep ingesting and the source's status line names the offending site. Sensors only begin polling once you confirm their bindings.
Notes and limits
The first crawl drains across several polls. There is no tenant-wide file delta in Graph, so the source walks each library's own change feed and stores one resume link per library. When a library is larger than one poll's page budget, the source stores the point it reached and continues from there on the next tick — so the first crawl of a large tenant fills in progressively rather than arriving as one enormous poll or restarting from the top each time.
Files are tracked by id, not by path. Graph's delta feed omits the path on parentReference and reports each item's latest state rather than every individual change, so a moved or renamed file is the same document to Corveil, not a new one.
Expired change tokens resync automatically. After a long gap Graph can invalidate a library's resume link (HTTP 410). The source treats that as an instruction to re-enumerate that library, not as an error.
Deleted files are not removed from the ontology. Deletions are recognized and skipped — a removed document is never re-ingested — but entities already created from it remain.
Author emails come from the file, not from a directory lookup. SharePoint usually reports the last modifier's email on the item itself. When it does not, the document still ingests with a display name and simply does not link to a Corveil user.
Sharing and permission signals are out of scope. Graph exposes them through Prefer: deltashowsharingchanges, which requires Sites.FullControl.All — a permission that would dominate a government security review for a read-only intelligence connector.