Expand description
WhatsApp Cloud API inbound webhook receiver — axum handlers for the one-time verification handshake and the per-event delivery POST.
These are the genuinely new shape versus Discord/Telegram/Slack, which
only ever make outbound connections: this is passive HTTP the public
internet (Meta’s servers) can reach, so every inbound POST must be
authenticated via HMAC signature (spec §3.2/§9) rather than AgentMux’s
own X-AuthKey scheme, which Meta cannot supply. These routes must be
registered outside auth_middleware — see server/mod.rs, merged at
the top level alongside the unauthenticated health router, not inside
authed_routes. Putting them behind X-AuthKey would make Meta’s calls
always fail (spec §8.2).
§Credential handling
Two credentials pass through this module: the webhook verify token
(hub.verify_token on the GET handshake) and the app secret (used to
validate X-Hub-Signature-256 on every POST). Neither is ever logged —
failures log only the fact of a mismatch, never the header value or the
secret. This mirrors the review findings baked into
telegram/rest.rs::redact() and slack/rest.rs::redact_ticket(): any
error string built from a value that might embed a credential must be
redacted (or, here, simply never constructed from the credential in the
first place) before it can reach a log line or an HTTP response body.
Functions§
- handle_
inbound POST /webhook/whatsapp— inbound message delivery.- handle_
verify GET /webhook/whatsapp?hub.mode=subscribe&hub.verify_token=...&hub.challenge=...- verify_
signature 🔒 - Validates
X-Hub-Signature-256: sha256=<hex>= HMAC-SHA256(app_secret, raw_body). UsesMac::verify_slice, which performs a constant-time comparison internally (backed by thesubtlecrate, already present transitively viahmacin this workspace’s dependency graph — no new crate added).