Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

SharePoint Sync — a Cortex App

Sync SharePoint document libraries into the Cortex knowledge graph — on demand or on a schedule, fully server-side, with no user sign-in anywhere.

The model: your instance gets an Entra application with the Sites.Selected permission — the least-privilege way into SharePoint. A SharePoint admin grants that application access to specific sites, and only those sites become visible and syncable. No consent screens for users, no tenant-wide access, no OAuth flows. Microsoft Graph's per-library delta feeds drive incremental sync; edited files replace their previous Cortex document instead of duplicating.

Built from cortex-app-template. Type: platform — the sync runs inside Cortex as a declarative platform task.

Requires a Cortex instance with the ms_graph_token auth transform and binary passthrough upload with redirect following (cortex-app ≥ 2.1 / July 2026 platform extensions). Credentials are deliberately per deployment — Cortex ships no shared client id or secret. Built on Microsoft Graph, not the retired SharePoint Add-in/ACS model.

Install

  1. Register the app (once, in your own M365 tenant): portal.azure.com → App registrations → New (single-tenant is fine, no redirect URI). Under Certificates & secrets, create a client secret — note its expiry policy.

  2. Permissions: API permissions → Add → Microsoft Graph → Application permissions → Sites.Selected → Grant admin consent. With only this permission the app can access nothing until step 3.

  3. Grant sites — a SharePoint admin allows the app onto each site. Graph Explorer (or any admin-credentialed client):

    POST https://graph.microsoft.com/v1.0/sites/{site-id}/permissions
    {
      "roles": ["read"],
      "grantedToIdentities": [
        { "application": { "id": "<ENTRA_CLIENT_ID>", "displayName": "Cortex SharePoint Sync" } }
      ]
    }
    

    (Find the site id via GET /sites/{hostname}:/sites/{path} with admin credentials.) Or PnP PowerShell:

    Grant-PnPAzureADAppSitePermission -AppId <ENTRA_CLIENT_ID> \
      -DisplayName "Cortex SharePoint Sync" -Permissions Read \
      -Site https://tenant.sharepoint.com/sites/TeamX
  4. npm install && npm run package → sharepoint-sync-{version}.zip; install via Cortex admin → Settings → Apps → Install (needs ENABLE_APPS=true).

  5. Configure ENTRA_TENANT_ID (GUID or tenant.onmicrosoft.com), ENTRA_CLIENT_ID, ENTRA_CLIENT_SECRET. Tokens are minted server-side; the secret never leaves the instance.

  6. Open the app, add your granted sites by URL (Sites.Selected has no discovery — the app can't list sites, only open ones it was granted), pick libraries or folders, schedule, Sync.

How the sync works

  • setup — per selected library (max 6): first run enumerates via /drives/{id}/root/delta; afterwards the stored @odata cursor returns exactly what changed (~1600 entries/run budget; backlogs drain across runs).
  • per file — feeds concatenated, filtered per item (deleted entries, folders, items outside the selected folders, non-document extensions optional, ~19 MB cap — all with visible skip reasons), deduped on synced/{id}:{eTag}. Then a binary passthrough upload: Cortex GETs /drives/{driveId}/items/{id}/content server-side and follows Graph's one redirect to the tenant download host. Edited files replace their Cortex document in place: the upload carries a stable source_key (sharepoint:{driveId}:{itemId}) plus the previous document id (docmap/{id}), so the document keeps its id and Cortex re-extracts only the parts that changed. On a Cortex backend without in-place replace, the app falls back to the old behaviour (new document, then the previous one is deleted).
  • Auth is entirely config-side: the manifest's auth_header carries an ms_graph_token(...) transform (app-only client credentials, cached, token endpoint pinned to Microsoft). The task and browser hold no credentials.

v1 limitations

  • Deleting a file in SharePoint does not delete it in Cortex.
  • OneNote notebooks are skipped (packages, not files).
  • Files larger than ~19 MB are skipped (platform transfer cap).
  • Client secrets expire (max 24 months) — rotate them in the app config before expiry, or syncs fail with a token-minting error.

Manifest notes

  • keyScope: read_write; endpoints: ["upload", "documents", "collections"]
  • capabilities: http (host-allowlisted to graph.microsoft.com), tasks, storage; the secret's auth_host scopes injection to Graph only

Dev loop

cp .env.example .env   # CORTEX_DEV_URL + a cortex_rw_… key
npm run dev

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages