Skip to main content
The Microsoft 365 Copilot connector pulls tenant-wide Copilot activity into Velatir over Microsoft Graph with admin-consent to a dedicated Velatir Entra app. It captures the things that make Copilot a first-class compliance source — which files Copilot grounded on, with their sensitivity labels, plus jailbreak / XPIA flags, plugin and agent identity, and the surface (Word, Teams, BizChat, …).
The connector is inbound only (read-side) — Velatir never writes back to your tenant.

What it pulls

Auth

  1. Admin grants consent to Velatir’s dedicated Entra app (“Velatir Connector”). The consent URL is the same shape as the existing Entra directory-consent flow (/adminconsent?...&state=<orgId>&redirect_uri=...).
  2. Backend records the consented tenant id on the organisation’s existing EntraConnection row (no new table).
  3. The connector mints app-only client-credentials tokens at sync time against the dedicated app, with the tenant id from step 2 and the dedicated app’s ClientId / ClientSecret (held in Scaleway Secret Manager).
Admin consent is per-app: granting consent to Velatir’s directory-LDAP app does not authorise the Copilot app. The Copilot app’s scopes (below) are intentionally separate so customers who never buy this connector don’t get blanket-re-consented onto the broad Copilot permissions.

Scopes requested

All application permissions (admin consent; no usable delegated equivalents):
  • AiEnterpriseInteraction.Read.All — content via aiInteractionHistory
  • AuditLogsQuery.Read.All — events via the Graph Audit Query API
  • Organization.Read.All — posture: /organization, /subscribedSkus
  • ReportSettings.Read.All — posture: /admin/reportSettings.displayConcealedNames
  • User.Read.All — content fallback (UPN resolution, licensed-user sweep)

What lands on the Activity surface

Every CopilotInteraction audit record becomes a ServiceEvent with:
  • Vendor typemicrosoftcopilot.CopilotInteraction
  • Actor — the audit record’s userPrincipalName (and userId for the Entra object id)
  • Target — the Copilot surface (BizChat, Word, Teams, …) joined to the agent name when one is present
  • Payload (verbatim) — the full auditData object, including:
    • AccessedResources[] — the files Copilot grounded on, with their sensitivity labels, the policy decision, and whether a cross-prompt-injection attack was detected
    • AISystemPlugin[] — plugins used (including BingWebSearch for public-web answers)
    • AgentId / AgentName — agent identity (Microsoft first-party or Copilot Studio)
    • JailbreakDetected per-message
    • DLPEvaluationDeferred — bitmask of what Microsoft DLP could not evaluate
    • isCopilotStudio (added by the connector) — distinguishes first-party from Studio-sourced events
Audit-record availability lags the event. The connector trails the window end by 30 minutes and accepts overlap; the sink’s (org, VendorEventId) idempotency guard absorbs re-pulls.

Conversation content

The connector pulls per-user aiInteractionHistory records for each ContentResourceId surfaced by an audit event. The connector extracts the adaptive-card text per the Graph API contract:
  • body.contentType == "text" → use body.content directly
  • body.contentType == "html" with an <attachment id="…"/> → resolve the matching attachments[] entry, take the first TextBlock.text
  • Otherwise strip tags
The raw body, attachments, links, mentions, and contexts are preserved in Trace.Metadata for re-classification and audit.

Per-connector content toggle

Some organisations want Activity (the event stream) but not Content (the per-message text — e.g. for confidentiality or scope reasons). The connector exposes an isContentEnabled toggle on the connector DTO; when off, the sync worker skips the PullContentAsync lane entirely while the event lane still runs. Toggle via PATCH .../connectors/{id} with {"isContentEnabled": false}.

Deduplication

The connector and the browser extension / desktop agent both surface Copilot under the microsoft-copilot source slug. The connector records carry the audit UPN into TraceContext.Ldap.EmailHash; the existing cross-service dedup (VEL-897) matches connector and device traces on the identity × ±5-minute symmetric window and marks the connector rows as superseded by the device trace. Endpoint wins; the connector row stays on disk for retrospective Data Protector monitoring.

What the connector does not pull

  • AIAppInteraction (third-party AI apps) — opt-in only, pay-as-you-go billed to the customer at 180-day retention
  • ConnectedAIAppInteraction (Copilot Studio / third-party AI apps) — M5, opt-in
  • Copilot usage reports (getMicrosoft365CopilotUsageUserDetail) — no UsageMetric store yet
  • CopilotSettings-LimitedMode — delegated-only API, unreachable app-only
  • CopilotPackages (agent inventory) — requires Microsoft Agent 365 licence, degrades to “unavailable” on 403

Limits

  • Audit results are retrievable for 30 days after the job finishes — a checkpointed job id stays valid across many sync passes.
  • Records per page: 500.
  • Filter window: 6h default, bounded by the 30 min record-availability lag.
  • Default backfill on first sync: 7 days.