Skip to content

[Microsoft Teams] Rewrite connector to use application-only permissions - #4257

Draft
Jan-Kazlouski-elastic wants to merge 5 commits into
mainfrom
jan-kazlouski/microsoft-teams-connector
Draft

[Microsoft Teams] Rewrite connector to use application-only permissions#4257
Jan-Kazlouski-elastic wants to merge 5 commits into
mainfrom
jan-kazlouski/microsoft-teams-connector

Conversation

@Jan-Kazlouski-elastic

Copy link
Copy Markdown
Contributor

Closes #4145

Rewrites the Microsoft Teams connector to authenticate with application-only credentials (client secret or certificate) using a least-privilege permission model, and removes the legacy dual (delegated + username/password) authentication that is unsuitable for a headless connector.

Because Microsoft only exposes read access to Teams messages through either broad *.All "protected" permissions or the narrower resource-specific consent (RSC) / WhereInstalled permissions, the connector uses the latter: its Entra app is packaged as a Teams app and installed into the teams/chats to sync. Shared Microsoft Graph auth/HTTP plumbing was extracted into connectors/sources/shared/microsoft/graph.py and is now reused by both the Teams and SharePoint Online connectors.

What changed

Auth & permissions

  • Application-only auth via client secret (GraphAPIToken) or certificate (EntraAPIToken); legacy username/password/delegated auth removed.
  • Least-privilege model documented in the Teams app manifest README (RSC + WhereInstalled), including the unavoidable Team.ReadBasic.All / Channel.ReadBasic.All discovery permissions and the attachment-only Files.Read.All.
  • Shared Graph module extracted and consumed by SharePoint Online (no behavioral change there).

Correctness & robustness

  • get_docs restructured to schedule a single enumeration orchestrator and consume the queue concurrently, fixing a stall/deadlock on large tenants (previously all producers were enumerated before draining, exhausting the MemQueue / MAX_CONCURRENCY).
  • Refuses to report a "successful" sync when both team and chat enumeration fail with PermissionsMissing, preventing a silent wipe of previously indexed content. A genuinely empty tenant still completes normally.
  • Attachment-only messages (no text, but with attachments) are now indexed; truly empty messages are still dropped.
  • Guards an explicit "body": null so it can no longer raise AttributeError.
  • get_access_control tolerates PermissionsMissing during enumeration (warn + continue), matching get_docs.
  • incremental_sync_enabled set to False (there is no incremental crawl path; the flag was misleading).

Observability

  • Per-resource 403/404s remain at debug, but are counted and surfaced as a single aggregate WARNING at the end of each sync, so an under-installed tenant is visible instead of producing a quiet, near-empty sync.

Config validation

  • validate_config raises a clear ConfigurableFieldValueError when the selected auth method is missing its credentials, instead of surfacing a low-level token error.

Checklists

Pre-Review Checklist

  • this PR does NOT contain credentials of any kind, such as API keys or username/passwords (double check config.yml.example)
  • this PR has a meaningful title
  • this PR links to all relevant github issues that it fixes or partially addresses
  • this PR has a thorough description
  • Covered the changes with automated tests
  • Tested the changes locally
  • Considered corresponding documentation changes

Changes Requiring Extra Attention

  • Security-related changes (encryption, TLS, SSRF, etc) — authentication model reworked to application-only (client secret / certificate); credentials handling and least-privilege permissions.

Related Pull Requests

  • N/A

Release Note

Rewrote the Microsoft Teams connector to use application-only authentication (client secret or certificate) with a least-privilege permission model, replacing the previous username/password + delegated authentication.

Made with Cursor

Jan-Kazlouski-elastic and others added 2 commits July 22, 2026 12:57
…ns (#4145)

Replace the dual delegated + username/password auth model with application-only
authentication (client secret or certificate), mirroring SharePoint Online.

- Extract shared Microsoft Graph auth + HTTP layer into
  connectors/sources/shared/microsoft/graph.py, reused by SharePoint Online and Teams.
- Adopt the least-privilege WhereInstalled/RSC permission model; per-resource
  message/member calls skip teams/chats where the app is not installed.
- Trim synced entities to Teams, Channels (+ messages/replies/attachments),
  TeamMembers, and Chats (+ messages/attachments); drop calendars, tabs and
  meeting recordings.
- Add Document Level Security based on team/chat membership, creating identities
  only for users that participate in Teams.
- Ship a Teams app manifest template and setup docs for RSC installation.
- Rewrite unit tests and the functional-test fixture accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>
…lity

Fix large-tenant get_docs stall via concurrent enumeration, refuse silent
index wipe on total permission failure, index attachment-only messages,
and surface skipped resources at end of sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
elasticmachine and others added 3 commits July 22, 2026 17:27
Make resource enumeration failure-safe: unexpected (non-permission) errors
are recorded and re-raised from get_docs instead of stranding the consumer,
with ENUMERATION_FINISHED always emitted in a finally. Process channels
inline within team_producer to remove the nested fetchers scheduling that
could deadlock the bounded task pool on large tenants, and always emit each
producer's end signal via finally. Also add a return annotation to the
recursive get_channel_drive_children to satisfy the type checker.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Microsoft Teams] Rewrite Microsoft Teams connectors to only depend on application permissions

2 participants