0011 — Coexist with Microsoft Teams; Do Not Promise a Production Matrix Bridge¶
Status: Proposed
Customer validation is required before acceptance. Related work: milestone M7, issue #49.
The general beside/bridge/migrate decision framework now lives in the incumbent-chat coexistence guide. This ADR remains the evidence-backed Microsoft Teams worked example.
Context¶
Many target organizations standardize on Microsoft Teams. A bidirectional Teams↔Matrix bridge would appear to remove adoption friction, but the useful question is whether a supportable, tenant-approved integration preserves identity, threads, edits, files, retention, and security semantics. A demo that scrapes Teams or forwards a webhook is not that bridge.
This review distinguishes three products that are often conflated:
- A full room bridge mirrors conversations and remote users into Matrix, with event updates, membership, threads, attachments, deletion, and stable identity mapping.
- A Teams-native agent app lets a Teams user invoke selected Fgentic A2A agents without mirroring a Teams room into Matrix.
- A notification webhook posts one-way status into a channel; it is neither an identity nor a conversation bridge.
Evidence reviewed 2026-07-11¶
This is a current 2026 snapshot, not a forecast of what will exist in 2027. Re-run the evidence check before opening any Teams implementation issue and, if no event trigger fires sooner, by 2027-01-15.
Supported Microsoft surfaces¶
| Surface | What Microsoft documents | Why it is not a full bridge |
|---|---|---|
| Teams bot/agent with mentions | A Teams app can receive an explicitly mentioned message and reply in that context. Microsoft also documents proactive messages after the app is installed in the target user, chat, or team scope. | The sender is the application, not a Matrix puppet. Installation, tenant policy, consent, and Teams-native conversation semantics remain. |
| Resource-specific consent (RSC) | An authorized installer can grant an app access to one team, chat, meeting, or user resource rather than every resource in the tenant. The documented application permissions include ChannelMessage.Read.Group, ChannelMessage.Send.Group, and ChatMessage.Read.Chat; a bot or agent can receive all messages in the installed resource. |
RSC is a supported basis for a purpose-built Teams agent, but it does not define Matrix event/identity mapping, complete backfill, redaction, or cross-tenant behavior. Who may install and consent is still governed by the customer's Teams and Entra policies. |
| Outgoing webhook | A team-scoped webhook receives an HMAC-authenticated request only when explicitly mentioned in a public channel and has five seconds to return a synchronous reply in the same chain. | It cannot receive personal/private messages or call other Teams APIs such as roster/channel listing. It is a narrow invocation endpoint, not a room bridge. |
| Workflows incoming webhook | Power Automate can post webhook payloads through the Workflows bot. | The flow is user-owned and can become orphaned without co-owners; posts use the Workflows bot identity, whose name/icon cannot be customized. This is suitable only for explicitly labeled notifications. |
| Microsoft Graph messages | Change notifications cover message create/update/delete and can include resource data. Resource-scoped and tenant-wide subscriptions have different permissions, and subscriptions require lifecycle renewal. | General app-only message sending is migration-only; normal send message calls use delegated or RSC permissions. A custom bridge still owns subscription lifecycle, consent, throttling, identity, files, edits/deletes, threads, replay, and reconciliation. |
| Graph migration mode | Teamwork.Migrate.All can import historical third-party messages into a chat or channel in migration mode and preserve an original author and timestamp within documented constraints. |
Microsoft defines it as migration, not continuous synchronization. The caller must use app-only permission, and only the application that started a migration session can import until it completes the session. |
The legacy Office 365 Connector path is retired, not a basis for new work. Microsoft's final retirement notice says the disabling rollout ran from 18–22 May 2026 and that connector-based webhooks no longer function afterward. The current incoming-webhook guidance directs new scenarios to Power Automate Workflows; its documented owner/co-owner lifecycle is an operational dependency.
For any later adapter research, prefer Microsoft's resource-specific consent model and its bot/agent message guidance over tenant-wide export permissions. Microsoft states that the Teams APIs formerly listed as metered stopped requiring billing configuration on 25 August 2025; meeting AI-insight and DLP operations retain specific license rules. Customer licensing, tenant policy, and any API-specific charge remain validation questions, but this ADR does not invent a Graph usage charge or include one in Fgentic's reference infrastructure budget.
Matrix bridge candidates¶
No reviewed project meets an enterprise production bar. Activity and release facts below come from each repository's default branch and GitHub release metadata as queried on 2026-07-11; repository page updates, stars, and forks are not treated as source activity.
| Project | Source/release evidence | Technical and support boundary |
|---|---|---|
neilsb/mx-puppet-teams |
The project declares itself unmaintained; its last default-branch commit was 2022-04-21, with no tags or releases. | It used delegated Graph beta permissions and implemented only part of its chat-focused feature list. Its own README says Graph and default tenant policy defeated the goal. |
gekiclaws/matrix-teams |
Created 2025-12-17; last default-branch commit 2026-04-10; no tags or releases. | Its README calls it experimental and consumer-only. It polls reverse-engineered teams.live.com APIs, extracts Teams web storage in an embedded login, and explicitly excludes enterprise or tenant-managed support. |
YourSandwich/mautrix-teams |
Created 2026-04-22; six releases through v28.1 on 2026-06-17; GitHub lists one contributor. |
This is the strongest functional experiment reviewed, but its README says it reimplements the undocumented Teams web-client protocol with web-client tokens, and its maintainer is seeking a successor. No second public contributor or GitHub-recognized security policy is visible. |
palpo-im/matrix-bridge-teams |
Created 2026-03-02; last default-branch commit 2026-03-18; no tags or releases; one listed contributor. | Its README requests tenant-wide Chat.Read*.All, ChannelMessage.Read*.All, Team.ReadBasic.All, and User.Read.All application permissions while marking Graph integration and every message-bridge feature incomplete. |
fossteams/matrix-teams-as and fossteams/teams-api |
The appservice's last commit was 2021-06-16; the unofficial API wrapper's was 2022-10-13. Neither has a release. | The appservice README says it “doesn't do much”; the API wrapper says it is far from ready and requires extracted Teams tokens. These are inactive prototypes, not current forks to adopt. |
42wim/matterbridge |
Mature general relay, but its latest release is v1.26.0 from 2023-01-29 and its last default-branch commit is from 2024-08-27. |
The Teams backend uses delegated device authorization, broad Group.Read*.All, Graph beta, and five-second polling. Matterbridge relays content through a Matrix bot; it is not a Matrix appservice that preserves Teams identities/rooms. |
kernelpanic700/teams-matrix-bridge |
One contributor and one day of source activity on 2026-05-07; no license, tag, or release. | Its three-file example accepts arbitrary JSON without Microsoft's required outgoing-webhook HMAC verification and hard-codes Matrix credential placeholders. It is an unsafe notification sketch, not bridge evidence. |
None of the four primary Matrix-specific candidates (neilsb, gekiclaws, YourSandwich, palpo-im) exposed a GitHub-recognized security policy on the review date. Releases alone do not establish supported APIs, tenant-safe credentials, maintainership, security response, upgrade compatibility, or production references.
Reverse-engineered web APIs are excluded from the reference platform even when an experiment is open source. Microsoft's Developer Agreement prohibits reverse engineering or working around technical limitations except where applicable law overrides that restriction. The Microsoft API terms also make documented permissions, throttling, changes, and termination part of the operating contract. A customer-specific legal opinion, not this ADR, decides any exception.
Options considered¶
- Ship an unofficial puppeting bridge. This produces the most compelling demo but puts enterprise communication on reverse-engineered endpoints, user web tokens, a one-maintainer project, and incomplete deletion/identity semantics. Rejected.
- Build a full Graph-based Teams↔Matrix bridge. Supported APIs reduce terms risk, but Fgentic would own a second major bridge product, tenant consent, subscription lifecycle, semantic reconciliation, compliance exports, and Microsoft API churn. There is no evidence that this effort beats a Teams-native adapter for the actual agent-invocation need. Deferred unless a funded customer requires mirrored rooms and accepts the permission/data boundary.
- Use Workflows/webhooks as the bridge. Simple for one-way notifications or a constrained mention/reply command, but it erases sender/room semantics and lifecycle ownership. Rejected as a bridge; allowed as an explicitly labeled notification integration.
- Coexist; research a Teams-native A2A adapter only when demanded. Keep sovereign agent rooms in Matrix/Element. Teams remains the customer's existing collaboration product. If customer evidence justifies separate work, a tenant-installed bot/agent could map a Teams invocation directly to selected Fgentic A2A agents through agentgateway without pretending Teams is Matrix. Selected as the proposed posture; the adapter is not promised or authorized here.
Proposed decision¶
Do not deploy or advertise a production Teams↔Matrix bridge. The default evaluation and reference architecture use Element for agent rooms. Teams users can coexist by opening Element/web for sovereign agent collaboration. M7 separately evaluates Slack interop, and a customer-owned Teams Workflow may be configured only as a clearly labeled one-way notification path.
If validated customer research says that invoking agents inside Teams is mandatory, scope a separate Teams-native adapter with these boundaries:
- Use the current supported Teams bot/agent and RSC surfaces only—no browser-token capture, internal endpoint, or client emulation.
- Route requests directly to agentgateway/A2A; do not mirror arbitrary room history into Matrix unless a later full-bridge decision is approved.
- Use one immutable tuple
(tenant ID, Teams user ID, conversation ID, Teams message ID)for attribution and deduplication. Display names and email addresses are not identifiers. - Require explicit installation/consent per team or chat and the narrowest RSC permissions.
- Apply the same agent allowlists, rate/budget controls, prompt-injection boundary, content-free audit schema, and
m.notice-equivalent bot-loop rule as the Matrix bridge. - Document that Microsoft receives and retains the Teams-side content and metadata; this path is not the fully self-hosted sovereignty tier.
The adapter is not authorized by this ADR. It needs its own approved issue, threat-model delta, Microsoft tenant for deterministic integration tests, and customer acceptance criteria.
Revisit triggers¶
Reassess a full bridge only when all applicable conditions hold:
- A supported Microsoft API exposes the required messages, subscriptions, edits, deletes, reactions, threads, files, and scoped identities for standard, private, shared, meeting, and cross-tenant conversations used by the customer.
- An upstream Matrix bridge uses only documented APIs, has at least two active maintainers, versioned releases, a security policy, deterministic Matrix↔Teams integration fixtures, upgrade/retention runbooks, and production references.
- The customer explicitly needs mirrored rooms rather than a Teams-native agent adapter and approves the exact Entra/Graph permissions, licensing and API-specific payment, data residency, retention, support ownership, and outage behavior.
- Legal review accepts the Microsoft API/developer terms for the proposed implementation.
- A threat-model update proves remote identity mapping, edits/deletes, loops, replay/dedup, tenant isolation, offboarding, attachments, and audit joins without broad tenant credentials.
- The evidence snapshot is older than six months, Microsoft changes the RSC/bot/Graph/connector contract, or a reviewed bridge changes maintainers, authentication method, release/security posture, or supported API surface.
Human decision required¶
Before accepting this ADR, record answers from at least one named target customer or design partner:
- Is opening Element/web for agent rooms acceptable, or must agent invocation happen in Teams?
- Is a mention-driven Teams agent sufficient, or is bidirectional room/history mirroring a hard requirement?
- Which scopes—personal chat, group chat, standard/private/shared channels, meetings, or external tenants—are actually required?
- Which tenant/app policies govern custom app upload, installation, RSC consent, and Entra admin approval, and which role is authorized to perform each step?
- Which Microsoft cloud and license, geography, retention, eDiscovery, DLP, legal-hold, and support constraints apply?
- What peak invocation volume, response latency, attachment size, deletion/edit synchronization, availability, and offboarding behavior is required?
- Are external guests, shared channels, cross-tenant chats, meetings, or regulated data in scope?
The answer selects the next action rather than silently widening this ADR:
- If Element/web is acceptable, accept coexistence and build no Teams component.
- If mention-driven agent invocation inside Teams is mandatory but room mirroring is not, open a separate adapter issue only after the customer supplies a test tenant, approves the exact permission manifest, and agrees to data/residency and support boundaries.
- If bidirectional room/history mirroring is mandatory, keep this ADR Proposed and make no sales promise; either qualify a bridge against every revisit criterion above or explicitly decline that requirement.
Until those answers exist, README and sales material may say “Teams coexistence under review,” not “Teams bridge,” “Teams-compatible rooms,” or “coming soon.”