Skip to content

fix(whatsapp): honor group allowlist in bridge - #43929

Open
mgonto wants to merge 3 commits into
NousResearch:mainfrom
mgonto:fix/whatsapp-bridge-group-allowlist
Open

fix(whatsapp): honor group allowlist in bridge#43929
mgonto wants to merge 3 commits into
NousResearch:mainfrom
mgonto:fix/whatsapp-bridge-group-allowlist

Conversation

@mgonto

@mgonto mgonto commented Jun 11, 2026

Copy link
Copy Markdown

Summary

  • pass WhatsApp group allowlist policy from the Python adapter into the Node bridge
  • let explicitly allowlisted group messages pass the bridge without allowlisting every sender for DMs
  • keep DMs and self-chat protected by the existing sender/self-chat gates
  • align Node/Python group ID matching, including bare group IDs and wildcard allowlists

Test Plan

  • node --check scripts/whatsapp-bridge/allowlist.js
  • node --check scripts/whatsapp-bridge/bridge.js
  • node --test scripts/whatsapp-bridge/allowlist.test.mjs
  • python3 -m py_compile gateway/platforms/whatsapp.py tests/gateway/test_whatsapp_connect.py tests/gateway/test_whatsapp_group_gating.py
  • python3 -m pytest -q tests/gateway/test_whatsapp_connect.py tests/gateway/test_whatsapp_group_gating.py

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/whatsapp WhatsApp Business adapter labels Jun 11, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Fix: Honor group allowlist in WhatsApp bridge

  • Problem: Group IDs in the allowlist had to be specified with exact @g.us suffix, but the adapter sometimes received them without it, causing mismatches.
  • Fix: _is_group_allowed now normalizes IDs by checking with/without @g.us suffix, plus support for bare group IDs and * wildcard.
  • Environment variable support: Reads WHATSAPP_GROUP_ALLOWED_USERS env var in addition to config file. Passes both WHATSAPP_GROUP_POLICY and WHATSAPP_GROUP_ALLOWED_USERS to the Node bridge subprocess.
  • Node bridge: Added matchesAllowedIdentifier() in allowlist.js that handles the same normalization logic in JavaScript.
  • Tests cover bare group IDs, wildcard, and env var passthrough to the bridge.

Reviewed by Hermes Agent

@sukritgoyal

Copy link
Copy Markdown

Hey maintainers, can I be assigned on this? @tonydwb

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the group-scoped authorization gap. The underlying problem is still present on current main: scripts/whatsapp-bridge/bridge.js:637 applies the DM sender allowlist to external group traffic, and gateway/authz_mixin.py:467 only trusts an adapter group policy when no environment allowlist is configured.

Problems

  • The adapter changes target deleted gateway/platforms/whatsapp.py; WhatsApp moved to plugins/platforms/whatsapp/adapter.py in 560010547.
  • The proposed bridge fallback at scripts/whatsapp-bridge/bridge.js:350 would drop pairing DMs. Current main intentionally bypasses sender-list enforcement for WHATSAPP_DM_POLICY === 'pairing' at scripts/whatsapp-bridge/bridge.js:637.
  • The proposed auth helper reads self.adapters directly at gateway/authz_mixin.py:192 in this PR. Current main's gateway/authz_mixin.py:34 resolves the adapter by SessionSource.profile; a salvage must preserve that multiplex isolation.

Suggested changes

  • Port the adapter/test work to the bundled plugin and preserve the current pairing branch.
  • Use _authorization_adapter(source.platform, source.profile) for the group authorization decision and add a profile-scoped regression test.

Automated hermes-sweeper review.

} catch {}
continue;
}
} else if (!matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A current-main port must retain the WHATSAPP_DM_POLICY !== 'pairing' guard before applying the sender allowlist here. scripts/whatsapp-bridge/bridge.js:637 deliberately forwards pairing DMs for the gateway pairing handshake; this unconditional fallback would drop them.

Comment thread gateway/authz_mixin.py
if not self._adapter_enforces_own_access_policy(source.platform):
return False

adapters = getattr(self, "adapters", None) or {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Port this through current main's _authorization_adapter(source.platform, source.profile) rather than self.adapters. The current resolver is profile-aware, so direct lookup can read the default profile's WhatsApp policy for a secondary-profile message.

@teknium1 teknium1 added sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@eduardo

eduardo commented Jul 28, 2026

Copy link
Copy Markdown

I hit the same bridge-level failure on current main: the Node bridge applies the DM sender allowlist before Python can evaluate the configured group JID policy.

I opened #73465 as a narrow current-main salvage of this PR's bridge portion because this branch is now conflict-dirty and also carries gateway changes that have since moved/landed through adjacent work. The replacement is one commit touching only the three bridge policy/test files, and credits Martin Gontovnikas as co-author.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/whatsapp WhatsApp Business adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants