#14789: fix: per-account dmPolicy ignored in checkInboundAccessControl
channel: whatsapp-web
size: XS
Cluster:
WhatsApp Pairing Enhancements
## Summary
`checkInboundAccessControl()` in `src/web/inbound/access-control.ts` reads `dmPolicy` directly from the top-level channel config:
```typescript
const dmPolicy = cfg.channels?.whatsapp?.dmPolicy ?? "pairing";
```
This ignores per-account `dmPolicy` overrides entirely. When no top-level `dmPolicy` is configured, the hardcoded `"pairing"` default kicks in — so accounts with `dmPolicy: "allowlist"` still send pairing PINs to unknown senders.
The fix is a one-line change. `resolveWhatsAppAccount()` (called two lines above) already resolves the correct fallback chain (`accountCfg?.dmPolicy ?? rootCfg?.dmPolicy`), but its result is never used:
```diff
- const dmPolicy = cfg.channels?.whatsapp?.dmPolicy ?? "pairing";
+ const dmPolicy = account.dmPolicy ?? "pairing";
```
## Steps to reproduce
1. Configure multi-account WhatsApp with per-account `dmPolicy`:
```json
"channels": {
"whatsapp": {
"accounts": {
"personal": {
"dmPolicy": "allowlist",
"allowFrom": ["+1234567890"]
}
}
}
}
```
2. Do **not** set a top-level `channels.whatsapp.dmPolicy`
3. Send a message from a number **not** in `allowFrom`
4. **Expected**: message silently rejected (allowlist mode)
5. **Actual**: sender receives a pairing PIN message
## Workaround
Add `dmPolicy` at the top-level channel config to force the value for all accounts:
```json
"channels": {
"whatsapp": {
"dmPolicy": "allowlist",
"accounts": { ... }
}
}
```
## Test plan
- [X ] Verify account-level `dmPolicy: "allowlist"` blocks unknown senders without pairing
- [X ] Verify account-level `dmPolicy: "pairing"` still sends PINs as expected
- [X ] Verify top-level `dmPolicy` still works as fallback when account has none
- [X ] Verify default behavior (`"pairing"`) when neither level is set
- [ ] Add unit test for per-account dmPolicy override in `access-control.pairing-history.test.ts`
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This change updates `checkInboundAccessControl()` (`src/web/inbound/access-control.ts`) to use the already-resolved WhatsApp account config (`resolveWhatsAppAccount`) when determining `dmPolicy`, rather than reading only the top-level channel config. As a result, per-account `dmPolicy` overrides (and the intended fallback chain to the root WhatsApp config) are honored, while the existing hard default of `"pairing"` remains in place when neither account nor root config specifies a policy.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- The change is a one-line fix that switches `dmPolicy` lookup to the already-resolved per-account configuration, matching the intended fallback chain implemented in `resolveWhatsAppAccount()`. No behavioral changes beyond honoring per-account overrides were identified.
- No files require special attention
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#22636: fix(whatsapp): skip pairing store merge when dmPolicy is allowlist (#…
by anillBhoi · 2026-02-21
84.8%
#11249: fix(whatsapp): prevent pairing-mode auto-replies to unknown DMs
by liuxiaopai-ai · 2026-02-07
83.8%
#6567: fix: include paired users in WhatsApp group sender allowlist
by giannisanni · 2026-02-01
83.7%
#4390: fix(whatsapp): allow media from allowlisted groups without groupAllow…
by Sarang19114 · 2026-01-30
82.2%
#11611: feat: separate group-level allowlist from sender-level command auth...
by thisnick · 2026-02-08
80.4%
#17882: fix: drop WhatsApp pairing reply for unconfigured accounts
by adit-negi · 2026-02-16
80.2%
#21893: fix(web): enforce sendPolicy on WhatsApp auto-reply delivery path
by hydro13 · 2026-02-20
80.0%
#5665: fix: match group JIDs in groupAllowFrom allowlist
by koala73 · 2026-01-31
79.8%
#6265: feat(whatsapp): add pairing owner notification
by zote · 2026-02-01
79.4%
#21889: fix(whatsapp): include outbound DMs in agent context for allowed co...
by mactsk · 2026-02-20
79.3%