fix(whatsapp): isolate multi-account inbound state and align shared defaults#65700
Conversation
Greptile SummaryThis PR centralizes WhatsApp inbound policy resolution into Confidence Score: 5/5Safe to merge — logic is correct and well covered by the new focused regression tests All findings are P2 style-level observations. The core fixes (canonical policy resolver, account-scoped session keys, async backfill) are implemented correctly: lastRoutePolicy remains 'session' for group routes after the key scoping (since the scoped key always differs from mainSessionKey), the broadcast path correctly re-scopes per-agent keys after buildBroadcastRouteKeys overwrites them, and the legacy backfill guard prevents double-writes. New tests directly lock in the cross-account isolation properties the PR fixes. No files require special attention Reviews (2): Last reviewed commit: "fix(whatsapp): address inbound policy re..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 59aaf62459
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Follow-up triage on the bot comments and the failing CI is done. What changed in the follow-up:
What I reviewed but did not change:
Verification after the follow-up:
I replied to every open review thread with the fix/triage rationale and resolved them. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2dd3176424
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba2be51a9c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
ba2be51 to
983adc2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 983adc2638
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
983adc2 to
605f876
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 607026d7a2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 74db285b80
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3991b88b8e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
3991b88 to
e5250a2
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e5250a2237
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 03e68f573c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟡 Session-key collision across WhatsApp named accounts due to lossy accountId normalization in thread suffix
DescriptionThe new WhatsApp group session scoping appends a
Vulnerable code: function resolveWhatsAppGroupAccountThreadId(accountId: string): string {
return `whatsapp-account-${normalizeAccountId(accountId)}`;
}This is particularly risky because account IDs are user-controlled configuration keys (Zod schema allows arbitrary strings as RecommendationAvoid lossy normalization for values that define storage/routing boundaries. Options:
Example (collision-resistant thread id): function base64url(input: string) {
return Buffer.from(input, "utf8").toString("base64")
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/g, "");
}
function resolveWhatsAppGroupAccountThreadId(accountId: string): string {
// keep delimiter-safe, collision-resistant
return `whatsapp-account-${base64url(accountId.trim())}`;
}If you keep
2. 🟡 Cross-account group activation state leakage via legacy WhatsApp group session keys
Description
In multi-account WhatsApp setups, this can cause activation state from a different account (or from the former single-account/default setup) to be applied to another account that shares the same Impact:
Vulnerable logic: const legacySessionKey = resolveWhatsAppLegacyGroupSessionKey({ sessionKey, accountId });
const legacyEntry = legacySessionKey ? store[legacySessionKey] : undefined;
...
const activation = scopedEntry?.groupActivation ?? legacyEntry?.groupActivation;
if (activation !== undefined && scopedEntry?.groupActivation === undefined) {
await updateSessionStore(storePath, (nextStore) => {
...
nextStore[sessionKey] = { ...nextScopedEntry, groupActivation: activation };
});
}Data-flow summary:
If an attacker (or merely a user with sufficient command permissions) can cause a legacy activation value to be written for one account, it can inadvertently enable always-on processing for other accounts in the same group. RecommendationDo not apply legacy/unscoped Recommended fixes (pick one):
const multiAccount = hasNamedWhatsAppAccounts(params.cfg);
const activation = scopedEntry?.groupActivation ?? (!multiAccount ? legacyEntry?.groupActivation : undefined);
Also consider avoiding automatic persistence/backfill ( Analyzed PR: #65700 at commit Last updated on: 2026-04-18T04:35:34Z |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6152eb5cc7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b421a6ae0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5922e9d1c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 99e97e162e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
99e97e1 to
2755b57
Compare
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
…efaults (openclaw#65700) * refactor(whatsapp): centralize inbound policy resolution * fix(whatsapp): scope named-account group session keys * fix(whatsapp): preserve legacy group activation during scoped-key migration * fix(whatsapp): wire shared defaults through accounts.default * fix(whatsapp): align schema, helpers, and monitor behavior * fix(whatsapp): restore verbose inbound diagnostics * chore(config): refresh whatsapp changelog and baseline hashes
Summary
accounts.default, debounce fallback breakage, self-chat/mention-gating inconsistencies, and confusing remediation/config paths.channels.whatsapp.accounts.defaultthrough runtime/setup/schema/helpers, and fixes the follow-on regressions needed so those surfaces agree.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
accounts.defaultshared defaults, but not every downstream surface was updated to honor that new contract consistently.accounts.defaultinheritance, setup writes, schema validation, and monitor/runtime behavior.Regression Test Plan (if applicable)
extensions/whatsapp/src/inbound/access-control.test.tsextensions/whatsapp/src/group-session-key.test.tsextensions/whatsapp/src/auto-reply/monitor/group-activation.test.tsextensions/whatsapp/src/auto-reply/web-auto-reply-monitor.test.tsextensions/whatsapp/src/auto-reply.web-auto-reply.connection-and-logging.e2e.test.tsextensions/whatsapp/src/channel.setup.test.tsextensions/whatsapp/src/accounts.test.tssrc/config/config.schema-regressions.test.tssrc/config/io.compat.test.tssrc/commands/doctor-legacy-config.migrations.test.tssrc/channels/plugins/helpers.test.tssrc/plugin-sdk/channel-config-helpers.test.tssrc/auto-reply/reply/session.test.tsUser-visible / Behavior Changes
channels.whatsapp.accounts.defaultnow behaves as a real shared-default source across runtime, setup/finalize writes, and schema validation.Diagram (if applicable)
Security Impact (required)
Yes/No) NoYes/No) NoYes/No) NoYes/No) NoYes/No) NoYes, explain risk + mitigation: N/ARepro + Verification
Environment
allowFrom,groupAllowFrom,accounts.default, and legacy session-store entriesSteps
Expected
accounts.defaultinheritance behaves consistently across runtime/setup/schema.Actual
Evidence
Human Verification (required)
groupActivation, legacy activation-only entries, named-account debounce lookup, andgroupAllowFrom: []falling back toallowFrom.Review Conversations
Compatibility / Migration
Yes/No) YesYes/No) NoYes/No) NoRisks and Mitigations
accounts.defaultinheritance now matters across more surfaces, so future WhatsApp changes can accidentally update only runtime or only validation.