Connector Release October 27, 2026 • 9 min read

Microsoft Graph v1.0 & Zero-Trust Enterprise RAG: Announcing the SharePoint Online Repository Connector

Across the Fortune 500, Microsoft SharePoint Online is the backbone of collaborative enterprise documentation—housing architecture records, legal contracts, engineering specifications, and board policies. Today, we are thrilled to announce the official SharePoint Online Repository Connector (oc-sharepoint-repository-connector)! Crawl SharePoint Online document libraries via Microsoft Graph v1.0 using least-privilege Entra ID app-only credentials (Sites.Selected or Sites.Read.All), track incremental changes via @odata.deltaLink and permission-fingerprint tree scans, extract custom SharePoint list item columns (sharepoint_field_*), coordinate concurrent Java 25 Virtual Threads through a shared Retry-After throttle gate, and enforce fail-closed Zero-Trust permissions across every vector store and MCP agent. šŸŒšŸ”’

SharePoint Online & Microsoft Graph v1.0 Enterprise Ingestion Pipeline
Microsoft Entra ID + Graph v1.0 (/delta & /permissions)
→
SharePointRepositoryConnector (Shared Throttle Gate)
→
Pre-Signed Download + TempFileInputStream
→
Claim-Check Store (Ozone / S3)
→
OIS Document + SharePointSecurityMapper
→
Vector Stores & Secure MCP Server

1. Why SharePoint Online Needs a Fail-Closed, Graph-Native RAG Connector

Connecting Microsoft SharePoint Online to an enterprise Retrieval-Augmented Generation (RAG) pipeline requires far more than listing files in a drive. Production SharePoint tenants expose subtle security, throttling, and synchronization challenges that naive scripts fail to handle safely:

The new oc-sharepoint-repository-connector was engineered on Java 25 and the OpenCrawling SPI to address every one of these requirements—backed by a 6-tier verification suite including official Microsoft Graph docs conformance, OpenAPI schema validation, Microsoft Dev Proxy chaos injection, and an independent 16-user RBAC oracle.

2. Entra ID App-Only Authentication & Site / Library Discovery

GraphClient authenticates against Microsoft Entra ID (https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token) using the OAuth 2.0 client_credentials grant for https://graph.microsoft.com/.default. It supports both tenant-wide Sites.Read.All and least-privilege Sites.Selected application permissions, caches the bearer token in memory, refreshes it proactively before expiry, and re-acquires it automatically once on HTTP 401.

Target sites can be specified either by their human-friendly SharePoint URL (site-url, e.g., https://contoso.sharepoint.com/sites/Engineering, resolved via GET /sites/{hostname}:/{server-relative-path}) or by their composite Graph Site ID (site-id). By default, the connector discovers and crawls every documentLibrary drive on the site, or filters to specific libraries via drive-ids or drive-names (e.g., Documents, Policies).

3. Two Complementary Crawl Modes: delta and tree

SharePointRepositoryConnector provides two crawl modes via crawl-mode, backed by persistent per-drive state in SharePointCrawlState (data/sharepoint-state/):

1. Incremental Delta Crawl (delta, default)

Walks GET /drives/{driveId}/root/delta across @odata.nextLink pages and persists the final @odata.deltaLink together with each file's eTag, path, and SHA-256 permission fingerprint:

2. Folder Tree Traversal & Permission-Only Reconciliation (tree)

Traverses GET /drives/{driveId}/root/children (or /root:/{path}:/children when root-folder-path is set), recursing into subfolders when recursive: true. When combined with incremental-enabled: true, tree mode compares each file's current eTag and SHA-256 permission fingerprint against stored state—re-emitting files whose permissions changed even when their eTag did not, and emitting DELETE tombstones for vanished files.

💡

Least-Privilege Permission Reconciliation: Because Microsoft Graph delta only surfaces permission-only changes to apps holding Sites.FullControl.All, teams running with least-privilege Sites.Read.All or Sites.Selected can run frequent delta crawls for fast content sync and schedule a periodic incremental tree crawl to reconcile permission-only updates without re-indexing unchanged files.

4. SharePoint List Item Columns & Secure Pre-Signed Downloads

When include-custom-fields: true (default) is enabled, SharePointDocumentBuilder fetches GET /drives/{driveId}/items/{itemId}/listItem?$expand=fields and maps custom SharePoint columns into OIS metadata under sharepoint_field_<InternalName> (configurable via field-prefix). Complex person, lookup, and managed-metadata fields are automatically reduced to their clean display labels, while internal SharePoint system properties (@odata.*, _UIVersionString, DocIcon, Edit) are stripped.

For binary content (include-content: true), GraphClient streams bytes from the pre-authenticated @microsoft.graph.downloadUrl without forwarding the Microsoft Graph Authorization: Bearer header (falling back to GET /drives/{driveId}/items/{itemId}/content 302 redirect if the pre-signed URL has expired). Content is spooled to a size-capped temporary file (TempFileInputStream, bounded by max-file-size-bytes, default 50 MB) that deletes itself on stream close, and handed to the OpenCrawling Claim-Check store (Apache Ozone / S3) and Apache Tika 4.

5. Fail-Closed Zero-Trust Security Mapping (SharePointSecurityMapper)

For every crawled file (include-acls: true), SharePointSecurityMapper evaluates GET /drives/{driveId}/items/{itemId}/permissions on a strict fail-closed basis. Only roles that grant content read access (read, write, owner, sp.full control, sp.contribute, sp.read) are accepted; metadata-only or custom roles such as sp.restricted view are ignored:

Graph Permission Facet Emitted OIS Principal (identity) identityType Security Behavior
Person (grantedToV2.user / siteUser) Lower-case email/UPN (from user.email or i:0#.f|membership|<upn>) and Entra object ID (user.id) user Display names and numeric siteUser.id are never used as principals
Entra Security / M365 Group (grantedToV2.group or claim c:0t.c|tenant|<guid>) Entra group object ID (<guid>) group Matches Entra group GUIDs in user JWT groups claims
SharePoint Site Group (grantedToV2.siteGroup) sharepoint-group:<siteId>:<siteGroup.id> group Site-qualified so numeric site group IDs never collide across sites
Specific-People Link (link.scope = "users") Each recipient in grantedToIdentitiesV2 user / group Grants access strictly to listed link recipients
Broad Access Grants (Everyone, Everyone except external, organization / anonymous links) Configured *-identity property *(as configured)* Ignored by default (fail-closed) unless explicitly mapped
Empty / Unreadable Permissions fallback-principals or nobody — Never marked public by default

6. Shared Throttling Gate & Java 25 Structured Concurrency

Drive items are enriched concurrently using Java 25 StructuredTaskScope.open() and ObservabilityTask.observed(...), bounded by a configurable Semaphore (parallelism, default 4). Every request carries Microsoft's recommended ISV User-Agent header (ISV|OpenCrawling|OpenCrawling-SharePoint-Connector/1.0) and a per-request client-request-id UUID.

Crucially, all concurrent Virtual Thread workers share a single coordinated throttle gate inside GraphClient: when any request receives HTTP 429 Too Many Requests, 503 Service Unavailable, or 504 Gateway Timeout, all workers pause until the server's Retry-After window (with a 1-second floor) has elapsed before retrying with exponential backoff and jitter. Server errors (500, 502, 507) fail the item so the @odata.deltaLink never advances past an unindexed file.

7. Sample OIS Document Payload

{
  "id": "sharepoint://contoso.sharepoint.com,11111111-2222-3333-4444-555555555555,66666666-7777-8888-9999-000000000000/drives/b!drive123/items/01ABCDEF23456789",
  "action": "UPSERT",
  "acl": "alice@contoso.com,aaaa1111-bbbb-2222-cccc-333333333333,dddd4444-eeee-5555-ffff-666666666666,sharepoint-group:contoso.sharepoint.com,11111111-2222-3333-4444-555555555555,66666666-7777-8888-9999-000000000000:7",
  "metadata": {
    "name": ["Architecture-Decision-Record-012.pdf"],
    "title": ["ADR 012 - Event Driven Ingestion"],
    "mimeType": ["application/pdf"],
    "sharepoint.siteId": ["contoso.sharepoint.com,11111111-2222-3333-4444-555555555555,66666666-7777-8888-9999-000000000000"],
    "sharepoint.siteName": ["Engineering"],
    "sharepoint.driveId": ["b!drive123"],
    "sharepoint.driveName": ["Documents"],
    "sharepoint.itemId": ["01ABCDEF23456789"],
    "sharepoint.path": ["/Architecture/Architecture-Decision-Record-012.pdf"],
    "sharepoint.eTag": ["\"{D9B3F1E0-1234-4BCD-8EF0-112233445566},3\""],
    "sharepoint.quickXorHash": ["aGVsbG8gd29ybGQ="],
    "sharepoint_identity_users": ["alice@contoso.com", "aaaa1111-bbbb-2222-cccc-333333333333"],
    "sharepoint_identity_groups": [
      "dddd4444-eeee-5555-ffff-666666666666",
      "sharepoint-group:contoso.sharepoint.com,11111111-2222-3333-4444-555555555555,66666666-7777-8888-9999-000000000000:7"
    ],
    "sharepoint_field_Title": ["ADR 012 - Event Driven Ingestion"],
    "sharepoint_field_Department": ["Platform Engineering"],
    "sharepoint_field_Confidentiality": ["Internal"],
    "sharepoint_field_ReviewStatus": ["Approved"]
  },
  "security": {
    "inheritanceEnabled": true,
    "permissions": [
      { "identity": "alice@contoso.com", "identityType": "user", "access": "read" },
      { "identity": "aaaa1111-bbbb-2222-cccc-333333333333", "identityType": "user", "access": "read" },
      { "identity": "dddd4444-eeee-5555-ffff-666666666666", "identityType": "group", "access": "read" },
      { "identity": "sharepoint-group:contoso.sharepoint.com,11111111-2222-3333-4444-555555555555,66666666-7777-8888-9999-000000000000:7", "identityType": "group", "access": "read" }
    ]
  }
}

8. 6-Tier Verification: OpenAPI Conformance, Dev Proxy Chaos & 16-User RBAC Oracle

To verify production fidelity without requiring a live Microsoft 365 tenant in CI, the connector ships with a 6-tier verification suite:

# 1. Unit, MockWebServer & verbatim Microsoft Graph documentation examples
$ mvn test -pl oc-sharepoint-repository-connector -am

# 2. Stateful Graph v1.0 Mock + Microsoft OpenAPI schema & docs conformance
$ ./scripts/test-sharepoint-repository-connector.sh

# 3. Microsoft Dev Proxy chaos & Retry-After throttling test (50% error rate)
$ ./scripts/test-sharepoint-devproxy.sh

# 4. Independent mock-graph-server + 16-user RBAC oracle comparison (144 access checks)
$ ./scripts/test-sharepoint-independent-mock.sh

# 5. Full decoupled Docker Compose pipeline (Kafka + Tika + Ollama + pgvector + Secure MCP)
$ ./scripts/test-sharepoint-decoupled.sh
✅

Zero False Allows, Zero False Denies: In test-sharepoint-independent-mock.sh, compare_acl_oracle.py evaluates 16 distinct user personas across 9 SharePoint files (144 authorization decisions) against an independent SharePoint RBAC oracle—confirming 100% agreement with McpAclEvaluator.

Ready to Connect SharePoint Online to Enterprise RAG?

Explore the SharePoint Online Repository Connector documentation on the OpenCrawling Wiki, test drive the interactive simulator, or star the project on GitHub.