Firewall & IP allowlisting for webhooks
Firewall & IP allowlisting for webhooks
If your organization enforces a firewall, WAF, or IP allowlist in front of your webhook receiver, requests from Bead may be blocked before they reach your application. This page covers how to identify that failure mode and what to allowlist.
This is a narrower case of the general webhook troubleshooting flow — start with Why am I not receiving webhook events? first. Come here specifically when you've confirmed your endpoint is reachable and correctly configured, but requests are still being rejected at the network or WAF layer.
1 — How to recognize a firewall/WAF block
A WAF or IP-based block usually looks different from an application-level failure:
Consistent 403 Forbidden on every request, regardless of method or payload, often with a generic body (e.g. Server: awselb/2.0 or a bare 403 Forbidden HTML page)
Load balancer or WAF rejecting the request before it reaches your application
200 OK status, but the response body is a generic web server error page (e.g. Apache "internal error or misconfiguration") rather than your application's expected response
Request is reaching your web server but failing before your application code executes — check server/WAF config, not your webhook handler logic
Identical error response regardless of whether the request body is empty, a dummy payload, or a real Bead-shaped payload
Confirms the block is happening before payload inspection — rule out payload validation issues and look at network/WAF layer instead
Endpoint works when tested from a browser or one network, but not from Bead's servers
Source-IP-based restriction; Bead's outbound IP(s) are not allowlisted
Consistent block on every request specifically citing a missing or absent User-Agent header (e.g. a WAF rule like "no user agent")
Your WAF rejects requests without a User-Agent header — see Section 3a below
If you're unsure which case you're in, capture the full raw response (status code, headers, and body) for a failing request and compare against the table above.
2 — Bead's outbound webhook IPs
Bead's webhook dispatch egresses from a small, fixed set of addresses per environment. Allowlist all addresses listed for your environment — traffic may originate from any of them.
Sandbox
35.155.201.4
52.10.29.164
Production
35.95.167.220
54.148.110.160
3 — Recommended: verify by signature, not by IP
IP allowlisting is fragile — egress ranges can expand, rotate, or change without notice as infrastructure changes, and a rule scoped to a single captured IP will silently start failing the next time that happens.
Bead signs every webhook payload with an HMAC signature in the x-webhook-signature (payment/terminal) or X-Bead-Signature (onboarding/settlement) header. Verifying that signature confirms a request genuinely came from Bead, independent of source IP. Where your security posture allows it, prefer signature verification over IP allowlisting — see How do I verify that a webhook really came from Bead? for the full implementation guide.
If your organization requires network-layer allowlisting for compliance reasons in addition to signature verification, allowlist every address listed in Section 2 for your environment — not just one — and revisit them periodically as part of your own change-management process.
3a — If your WAF requires a User-Agent header
Some WAFs block any request that lacks a User-Agent header outright, independent of IP allowlisting or signature verification — this is a common default WAF rule, not something specific to your configuration. If your logs show a block for a missing/absent User-Agent, note that every outbound webhook request from Bead (payment/terminal, onboarding, and settlement alike) now sends:
You can allowlist on this value in addition to, or instead of, IP-based rules. As of this writing, this header is confirmed present in the Bead Sandbox/test environment; if you're allowlisting for a production endpoint, confirm with your Bead contact that the same header is present in production before relying on it there.
This header does not replace signature verification (Section 3) as the strongest way to confirm a request came from Bead — it specifically addresses WAF rules that reject requests for missing a User-Agent regardless of any other check.
4 — Common WAF false-positive triggers
Some WAF rulesets flag standard HTTP client behavior as suspicious, which can block legitimate Bead traffic without any IP restriction being involved. If your WAF logs show a request blocked for header content (e.g. a rule matching on user-agent strings, generic client signatures, or patterns resembling command injection), check the following before assuming it's a targeted attack:
Default HTTP client User-Agent strings. Bead's webhook requests send a fixed
User-Agent: Bead-PaymentService/1.0(Section 3a). Confirm your WAF rule isn't matching broadly on client-identifying strings rather than actual malicious content.Standard headers vs. custom rule patterns. Compare the exact header content your WAF flagged against the rule's pattern — overly broad patterns can produce false positives on ordinary requests.
Retry behavior. Bead retries failed webhook deliveries with backoff (see Why am I not receiving webhook events?). A WAF or rate-limiting rule tuned for a single request may flag retries as abuse.
If you see a block you believe is a false positive, capture the exact WAF log entry (rule ID, matched pattern, timestamp) — this is the fastest way for both teams to confirm what triggered it.
5 — Still blocked after allowlisting?
Confirm the allowlist change has actually deployed/propagated on your side — WAF and firewall rule changes are not always instant.
Re-test using a direct request (e.g.
curl) against your endpoint from a known Bead environment, and capture the full verbose output (status, headers, body).Check whether the block is happening at a load balancer/WAF layer (Section 1) versus your application layer — they require different fixes.
Email Bead with: your terminal ID, webhook URL, the exact error/response you're seeing, and a timestamp of a failed attempt so we can correlate it against our dispatch logs.
Related pages
Last updated