IP Filtering
Configure IP allowlists and denylists with CIDR notation for sources.
IP filtering adds a network-level gate in front of every source. Use an allowlist to only accept requests from known provider IPs, or a denylist to block specific bad actors. Blocked requests return 403 Forbidden before anything else in the pipeline runs.
Allowlist vs denylist
- Allowlist — "only these IPs are allowed." Best when your provider publishes a fixed IP list (Stripe, Twilio, GitHub webhooks from GitHub.com).
- Denylist — "everyone except these IPs." Best for blocking known abusers while keeping the source open otherwise.
You can set both. The denylist is checked first, then the allowlist.
CIDR notation
Both lists accept single IPs or CIDR ranges for IPv4:
- Single IP:
192.168.1.1 - /24 subnet:
192.168.1.0/24(256 addresses) - /16 subnet:
10.0.0.0/16(65,536 addresses)
IPv6 CIDR matching is not currently supported. If you need to allow IPv6 traffic, leave the allowlist empty for now or reach out.
Configure a source
Collect the IPs
Grab the current IP list from your provider's documentation. For Stripe, that's stripe.com/docs/ips; for GitHub, it's the hooks section of api.github.com/meta.
Store them on the source
The allowlist is stored as a JSON array. Update the source via API:
bashcurl -X PATCH https://hookstream.io/v1/sources/src_abc \ -H "X-API-Key: $HOOKSTREAM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ip_allowlist": ["54.187.174.169", "54.187.205.235", "54.187.216.72/32"] }'
Or open the source in the dashboard and paste comma-separated entries into the IP Filtering section — the UI serializes them for you.
Send a test event
Send a webhook from a known-good IP. A rejected request returns 403 with reason "IP is not in allow list" or "IP is in deny list".
Pipeline evaluation order
IP filtering runs at the very front of the ingest pipeline, before any other check:
- IP filter — 403 if the client IP is blocked. Client IP is read from
CF-Connecting-IP, falling back toX-Forwarded-For. - Signature verification — 401 if the signature doesn't match.
- Deduplication — stored as
duplicateif the dedup window says so. - Schema validation — 422 if reject mode and the payload fails.
- Storage and fan-out — the event is persisted and pushed into connections.
Running IP filtering first means banned IPs never cost you a hash or a database round trip.
Provider IP lists change. Set a calendar reminder (or a cron job) to re-sync them every quarter so legitimate traffic doesn't start getting 403s.