Firewall Allowlisting
If the endpoints you monitor — or the receivers your webhooks post to — sit behind a firewall, WAF, or IP allowlist, you will need to let CrossCheck's traffic through.
This page covers both directions:
- Inbound to your services — the HTTP requests CrossCheck makes when actively monitoring a URL.
- Inbound to your receivers — the webhooks CrossCheck delivers when something happens.
Both leave from the same place, so one set of rules covers both.
Passive monitoring needs none of this. If your jobs check in to CrossCheck (Arrivals and Quick Flights), the connection is outbound from your side and your firewall already allows it. Allowlisting only matters for Active monitoring, where CrossCheck connects to you, and for webhook delivery.
Match the User-Agent where you can
If your firewall, WAF, or reverse proxy can inspect HTTP headers — Cloudflare, most WAFs, nginx, Apache — match on User-Agent rather than IP address.
| Traffic | User-Agent |
|---|---|
| Active monitoring probes, and Test now | CrossCheck-Monitor/1.0 |
| All webhook delivery | CrossCheck-Webhook/1.0 |
This is the more durable option. It keeps working if our infrastructure changes, which an IP allowlist does not.
A User-Agent is not a secret. Anyone can send the same header, so use it to grant network access, not to establish that a request is genuinely from CrossCheck. See Verifying webhooks below.
Outbound IP addresses
For firewalls that work at the network layer and cannot see HTTP headers, allow these addresses:
152.55.180.240
152.55.180.241
152.55.180.243
162.220.234.241
162.220.234.242
Allow all five. They are a high-availability set and any one of them may be the source of a given request, so allowing a subset produces failures that look intermittent and are painful to trace.
All CrossCheck outbound traffic leaves from this pool: monitoring probes, Test now, and every webhook. You do not need separate rules per feature.
These addresses can change
Treat the list above as current, not permanent. Infrastructure moves, and when these addresses change, a stale allowlist fails in the least helpful way possible — monitoring either goes silent or starts reporting outages that are not real.
If you allowlist by IP, re-check this page periodically, and prefer User-Agent matching wherever your tooling supports it.
What comes from these addresses
Active monitoring probes
| Property | Value |
|---|---|
| Method | GET |
| User-Agent | CrossCheck-Monitor/1.0 |
| Redirects | Followed, up to 5 |
| Timeout | Your flight's timeout setting |
| Frequency | Your flight's monitoring interval |
Each redirect hop is re-validated before it is followed, so a redirect cannot send the probe somewhere the original check did not allow.
Test now
The Test now button in the dashboard runs the same probe, on demand, from the same addresses. It is limited to 5 tests per minute per flight.
This matters for allowlisting: because it shares the pool above, allowing those addresses makes both scheduled monitoring and manual tests work. If Test now fails while scheduled checks succeed, your allowlist is probably missing part of the list.
Webhook delivery
| Property | Value |
|---|---|
| Method | POST |
| Content-Type | application/json |
| User-Agent | CrossCheck-Webhook/1.0 |
| Redirects | Not followed |
| Timeout | 5 seconds |
Your receiver must respond directly with a 2xx. A redirect is treated as a failure, and a response slower than 5 seconds is recorded as a failed delivery.
Webhooks are sent for these events, in the event field of the payload:
event | Meaning |
|---|---|
missed_checkin | A flight missed its expected check-in |
recovery | A flight checked in again after a missed window |
metric_breached | A metric rule crossed its threshold |
metric_recovered | A metric returned within its threshold |
issue_new | A new error was recorded |
issue_regression | A resolved error came back |
issue_storm_summary | Many new errors at once, summarised into one message |
Verifying that a webhook came from CrossCheck
An IP allowlist controls which hosts can reach your receiver. It is not authentication, and it should not be the only thing standing between the public internet and an endpoint that acts on what it receives.
Until request signing is available, the simplest approach that works today is to put a secret in the webhook URL itself. Because you choose the destination URL, you can include a token only you and CrossCheck know:
https://example.com/hooks/crosscheck?token=<a long random string>
Then reject any request to that path without the expected token. Treat the token like a password: keep it out of logs and rotate it by editing the destination.
Troubleshooting
Scheduled monitoring works, but Test now times out. Your allowlist covers some of our addresses but not all of them. Re-check the full list above.
Webhooks fail with no obvious error. Check that your receiver answers in under 5 seconds and returns a 2xx directly, without redirecting. Both show up as delivery failures in alert history.
A probe reports a failure you cannot reproduce. Try the URL from outside your network. A probe that is blocked at the edge is genuinely unreachable from where we sit, and we record it as such rather than guessing.