Summary
Add optional per-group allowFrom to channels.whatsapp.groups.<jid> (and account-scoped equivalent), allowing per-group sender authorization that overrides channel-level groupAllowFrom. Same pattern already supported by Feishu, IRC, LINE, Telegram, and Nextcloud-talk group schemas.
Problem to solve
The WhatsApp plugin currently offers only a single, channel-wide sender allowlist (channels.whatsapp.groupAllowFrom) for group messages. There is no way to express different sender-authorization policies per group, even when channels.whatsapp.groups already exists as a per-group config map (holding requireMention, tools, toolsBySender, and systemPrompt since #59553).
This forces operators into a binary choice:
groupAllowFrom: ["*"] — permissive, any sender in any allowlisted group can trigger the agent. Good for community groups, bad for groups where only a subset of members should drive the agent.
groupAllowFrom: ["+15551230001", "+15551230002", ...] — strict, but uniformly applied to every group. Adding/removing one trusted sender affects every group equally. Impossible to express "members of Group A are trusted, but only I am trusted in Group B."
Example real-world setup this blocks:
- Group A (team work): any team member can mention/trigger the bot
- Group B (customer support): only staff can trigger the bot, customers are silently ignored
- Group C (personal/private): only I can trigger the bot
Today, the operator has to choose one channel-level allowlist that covers the union or the intersection — neither is correct.
Proposed solution
Extend the existing channels.whatsapp.groups.<jid> schema with an optional allowFrom field matching the pattern already used by other channels:
{
channels: {
whatsapp: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"], // default-deny at channel scope
groups: {
"[email protected]": { allowFrom: ["*"] }, // all members trusted
"[email protected]": { allowFrom: ["+15551234567", "+15551230001"] }, // subset only
"[email protected]": { requireMention: true, allowFrom: ["+15551234567"] }, // only me, mention-gated
},
},
},
}
Resolution semantics (matching prior-art plugins):
Alternatives considered
1. Channel-level groupAllowFrom only (current behavior)
Too coarse. Any change affects every group. Operators with mixed trust levels across groups cannot express the real policy.
2. denyFrom / blockFrom (PR #63302 / closed #17438)
Solves a different problem (global sender blocklist). Useful, but does not provide per-group granularity — the denied sender is blocked everywhere, and there is still no way to have different allowlists per group.
3. requireMention per group
Does not filter senders. Merely requires the bot's mention before the agent replies. An untrusted member in a group with requireMention: true can still drive the agent by including the mention pattern.
4. toolsBySender per group
Restricts which tools a specific sender can trigger, but does not silence message ingestion. The agent can still reply with text to that sender.
5. Remove problematic groups from channels.whatsapp.groups
Works as a fail-closed option (group no longer handled), but is all-or-nothing. Operators cannot keep a group active for trusted members while silencing others.
Impact
- Affected: Any WhatsApp operator running more than one group with different trust levels. Common in family/work mixed setups, support groups, multi-tenant assistants, and default-deny security postures.
- Severity: Medium. Current behavior is safe when using
groupPolicy: "allowlist" + strict groupAllowFrom, but it forces operators to pick a single policy across all groups, making the security/usability tradeoff worse than it needs to be.
- Frequency: Every inbound group message is gated by the current coarse policy; the pain is structural, not intermittent.
- Consequence: Operators either accept a permissive channel-level allowlist (weaker security) or a strict one (breaks legitimate triggers from other trusted members). No middle ground.
Evidence/examples
Per-group allowFrom already exists in these plugins (verified in v2026.4.9 schema):
| Plugin |
Path |
Keys |
| Feishu |
channels.feishu.groups.<id> |
requireMention, tools, skills, enabled, allowFrom, systemPrompt, ... |
| IRC |
channels.irc.groups.<id> |
requireMention, tools, toolsBySender, skills, enabled, allowFrom, systemPrompt |
| LINE |
channels.line.groups.<id> |
enabled, allowFrom, requireMention, systemPrompt, skills |
| Telegram |
channels.telegram.groups.<id> |
requireMention, ingest, disableAudioPreflight, groupPolicy, tools, toolsBySender, skills, enabled, allowFrom, systemPrompt, topics, ... |
| Nextcloud-talk |
channels.nextcloud-talk.rooms.<id> |
requireMention, tools, skills, enabled, allowFrom, systemPrompt |
Currently WhatsApp accepts only: requireMention, tools, toolsBySender, systemPrompt (the last added by #59553).
Design intent already documented in #59553:
Group admission and sender authorization are separate checks. groups["*"] widens the set of groups that can reach group handling, but it does not by itself authorize every sender in those groups. Sender access is still controlled separately by channels.whatsapp.groupPolicy and channels.whatsapp.groupAllowFrom.
The split is intentional, but the sender-auth side never got per-group granularity like the admission/prompt/tools sides did. This issue tracks closing that gap.
Additional information
Summary
Add optional per-group
allowFromtochannels.whatsapp.groups.<jid>(and account-scoped equivalent), allowing per-group sender authorization that overrides channel-levelgroupAllowFrom. Same pattern already supported by Feishu, IRC, LINE, Telegram, and Nextcloud-talk group schemas.Problem to solve
The WhatsApp plugin currently offers only a single, channel-wide sender allowlist (
channels.whatsapp.groupAllowFrom) for group messages. There is no way to express different sender-authorization policies per group, even whenchannels.whatsapp.groupsalready exists as a per-group config map (holdingrequireMention,tools,toolsBySender, andsystemPromptsince #59553).This forces operators into a binary choice:
groupAllowFrom: ["*"]— permissive, any sender in any allowlisted group can trigger the agent. Good for community groups, bad for groups where only a subset of members should drive the agent.groupAllowFrom: ["+15551230001", "+15551230002", ...]— strict, but uniformly applied to every group. Adding/removing one trusted sender affects every group equally. Impossible to express "members of Group A are trusted, but only I am trusted in Group B."Example real-world setup this blocks:
Today, the operator has to choose one channel-level allowlist that covers the union or the intersection — neither is correct.
Proposed solution
Extend the existing
channels.whatsapp.groups.<jid>schema with an optionalallowFromfield matching the pattern already used by other channels:Resolution semantics (matching prior-art plugins):
groups[<jid>].allowFromis defined, it overrides (not merges with) channel-levelgroupAllowFromfor that specific group.groups[<jid>].allowFromis undefined, sender authorization falls back togroupAllowFrom(existing behavior — fully backward compatible).["*"]accepted, matching current semantics of channel-levelgroupAllowFrom.channels.whatsapp.groupsandchannels.whatsapp.accounts.<id>.groupsscopes, following the inheritance model established in WhatsApp: add group and direct system prompt support #59553 (and the fix in WhatsApp: align multi-accountgroupsinheritance with Telegram's isMultiAccount guard (breaking) #69874).Alternatives considered
1. Channel-level
groupAllowFromonly (current behavior)Too coarse. Any change affects every group. Operators with mixed trust levels across groups cannot express the real policy.
2.
denyFrom/blockFrom(PR #63302 / closed #17438)Solves a different problem (global sender blocklist). Useful, but does not provide per-group granularity — the denied sender is blocked everywhere, and there is still no way to have different allowlists per group.
3.
requireMentionper groupDoes not filter senders. Merely requires the bot's mention before the agent replies. An untrusted member in a group with
requireMention: truecan still drive the agent by including the mention pattern.4.
toolsBySenderper groupRestricts which tools a specific sender can trigger, but does not silence message ingestion. The agent can still reply with text to that sender.
5. Remove problematic groups from
channels.whatsapp.groupsWorks as a fail-closed option (group no longer handled), but is all-or-nothing. Operators cannot keep a group active for trusted members while silencing others.
Impact
groupPolicy: "allowlist"+ strictgroupAllowFrom, but it forces operators to pick a single policy across all groups, making the security/usability tradeoff worse than it needs to be.Evidence/examples
Per-group
allowFromalready exists in these plugins (verified in v2026.4.9 schema):channels.feishu.groups.<id>requireMention,tools,skills,enabled,allowFrom,systemPrompt, ...channels.irc.groups.<id>requireMention,tools,toolsBySender,skills,enabled,allowFrom,systemPromptchannels.line.groups.<id>enabled,allowFrom,requireMention,systemPrompt,skillschannels.telegram.groups.<id>requireMention,ingest,disableAudioPreflight,groupPolicy,tools,toolsBySender,skills,enabled,allowFrom,systemPrompt,topics, ...channels.nextcloud-talk.rooms.<id>requireMention,tools,skills,enabled,allowFrom,systemPromptCurrently WhatsApp accepts only:
requireMention,tools,toolsBySender,systemPrompt(the last added by #59553).Design intent already documented in #59553:
The split is intentional, but the sender-auth side never got per-group granularity like the admission/prompt/tools sides did. This issue tracks closing that gap.
Additional information
allowFromper group continue to use channel-levelgroupAllowFrom.systemPrompt), WhatsApp: align multi-accountgroupsinheritance with Telegram's isMultiAccount guard (breaking) #69874 (multi-accountgroupsinheritance), feat(whatsapp): add denyFrom config for blocking specific contacts #63302 (globaldenyFrom— complementary, not a substitute).groupsinheritance with Telegram's isMultiAccount guard (breaking) #69874 so rootgroups[<jid>].allowFromdoes not silently leak into accounts with their own groups map.