UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

169 lines (132 loc) • 8.11 kB
--- summary: "Microsoft Teams DM and group policy, team and channel allowlists, and conversation IDs" read_when: - Deciding who may DM or mention the Teams bot - Scoping replies to specific teams and channels - Looking up a Teams team or channel ID title: "Microsoft Teams access control" sidebarTitle: "Access control" --- Who may talk to the Teams bot, which teams and channels it answers in, and where the IDs those rules use come from. ## Config writes By default, Microsoft Teams can write config updates triggered by `/config set|unset` (requires `commands.config: true`). Disable with: ```json5 { channels: { msteams: { configWrites: false } }, } ``` ## Access control (DMs + groups) Microsoft Teams has one account per channel configuration. Set policies directly under `channels.msteams`; an `accounts` map is not supported. **DM access** - Default: `channels.msteams.dmPolicy = "pairing"`. Unknown senders are ignored until approved. - `channels.msteams.allowFrom` should use stable AAD object IDs or static sender access groups such as `accessGroup:core-team`. - Do not rely on UPN/display-name matching for allowlists; they can change. OpenClaw disables direct name matching by default; opt in with `channels.msteams.dangerouslyAllowNameMatching: true`. - The wizard can resolve names to IDs via Microsoft Graph when credentials allow. **Group access** - Default: `channels.msteams.groupPolicy = "allowlist"` (blocked unless you add `groupAllowFrom`). Set `channels.msteams.groupPolicy` explicitly to choose another policy; the root schema default takes precedence over `channels.defaults.groupPolicy`. - `channels.msteams.groupAllowFrom` controls which senders, static sender access groups, or group/channel conversation IDs can trigger in group chats/channels (falls back to `channels.msteams.allowFrom`). Conversation IDs can use `19:...@thread.tacv2`, `19:...@thread.v2`, or `19:...@thread.skype`; preserve the exact ID casing. OpenClaw ignores `;messageid=...` suffixes. Conversation IDs never grant personal-DM access. - Set `groupPolicy: "open"` to allow any member (still mention-gated by default). - To block **all** channels, set `channels.msteams.groupPolicy: "disabled"`. Example: ```json5 { channels: { msteams: { groupPolicy: "allowlist", groupAllowFrom: ["00000000-0000-0000-0000-000000000000", "accessGroup:core-team"], }, }, } ``` **Team + channel allowlist** - Scope group/channel replies by listing teams and channels under `channels.msteams.teams`. - Use stable Teams conversation IDs from Teams links as keys, not mutable display names (see [Team and Channel IDs](#team-and-channel-ids-common-gotcha)). - When `groupPolicy="allowlist"` and a teams allowlist is present, only listed teams/channels are accepted (mention-gated). - `groupAllowFrom` authorizes group senders, not delegated Graph reads of other channels. If an existing configuration only sets `groupAllowFrom`, keep the default `groupPolicy: "allowlist"` and configure the target under `channels.msteams.teams.<team>.channels`. - Alternatively, deliberately set `groupPolicy: "open"` for broader delegated reads. This also admits **any group sender** (still mention-gated by default), so it is less restrictive than a scoped team/channel route. - Direct-operator reads and reads in the current conversation do not require an additional team/channel route. - The configure wizard accepts `Team/Channel` entries and stores them for you. - On startup, OpenClaw resolves team/channel and user allowlist names to IDs (when Graph permissions allow) and logs the mapping. Unresolved names are kept as typed but ignored for routing unless `channels.msteams.dangerouslyAllowNameMatching: true` is set. With compatible core and Teams versions, verified official npm and ClawHub installations can use the existing `read`, `search`, `reactions`, `list-pins`, `member-info`, `channel-info`, and `channel-list` actions under these access rules. Agent reads from an installed plugin require trusted current Teams conversation and account context. Listing a team's channels requires access to the whole team; access to one channel does not grant that permission. [Member lookups](/channels/msteams/cards-and-actions#member-info-action) retain their standard-channel and current-requester restrictions. Subsequent Graph requests and results are rejected when the originating call or plugin loses authority. Example: ```json5 { channels: { msteams: { groupPolicy: "allowlist", groupAllowFrom: ["00000000-0000-0000-0000-000000000000"], teams: { "19:team-id@thread.tacv2": { channels: { "19:channel-id@thread.tacv2": { requireMention: true }, }, }, }, }, }, } ``` ### Mentions in bot-created threads Set `requireMentionInBotThreads: false` to answer without an @mention in channel threads whose root message was sent by this bot. Set it to `true` to require a mention in those threads, including replies that would otherwise count as an implicit mention. Omit it to retain the existing mention behavior. The setting resolves from channel to team to `channels.msteams`, independently of `requireMention`. Parent-channel posts and other people's threads retain their usual mention rules. Group-chat quotes are not channel threads, and sender and team/channel allowlists still apply. ```json5 { channels: { msteams: { requireMention: true, requireMentionInBotThreads: false, }, }, } ``` Ownership uses accepted top-level channel posts recorded by the current bot, including proactive messages. Replies inside existing threads do not establish ownership. Tracking lasts up to 24 hours and is bounded; the newest 1,000 send markers survive restarts. Older or untracked roots retain the ordinary mention rules. Teams must grant `ChannelMessage.Read.Group` in the app manifest to deliver messages without an @mention; see [RSC permissions](/channels/msteams/manifest-and-permissions#current-teams-rsc-permissions-manifest). ## Team and Channel IDs (Common Gotcha) The `groupId` query parameter in Teams URLs is **NOT** the team ID used for configuration. Extract IDs from the URL path instead: **Team URL:** ```text https://teams.microsoft.com/l/team/19%3ABk4j...%40thread.tacv2/conversations?groupId=... └────────────────────────────┘ Team conversation ID (URL-decode this) ``` **Channel URL:** ```text https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?groupId=... └─────────────────────────┘ Channel ID (URL-decode this) ``` **For config:** - Team key = path segment after `/team/` (URL-decoded, e.g., `19:Bk4j...@thread.tacv2`; older tenants may show `@thread.skype`, which is also valid). - Channel key = path segment after `/channel/` (URL-decoded). - **Ignore** the `groupId` query parameter for OpenClaw routing. It is the Microsoft Entra group ID, not the Bot Framework conversation ID used in incoming Teams activities. ## Private channels Bots have limited support in private channels: | Feature | Standard channels | Private channels | | ---------------------------- | ----------------- | ---------------------- | | Bot installation | Yes | Limited | | Real-time messages (webhook) | Yes | May not work | | RSC permissions | Yes | May behave differently | | @mentions | Yes | If bot is accessible | | Graph API history | Yes | Yes (with permissions) | **Workarounds if private channels do not work:** 1. Use standard channels for bot interactions. 2. Use DMs; users can always message the bot directly. 3. Use Graph API for historical access (requires `ChannelMessage.Read.All`).