You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Workflow call_webhook runs SSRF protection that rejects private and reserved address ranges, including 100.64.0.0/10. That range is CGNAT, which is what Tailscale assigns to every node. The practical effect is that a self-hosted relay physically cannot reach any service on the operator's own tailnet, so call_webhook is unusable for a whole class of deployment rather than merely restricted.
To be clear up front: the SSRF policy itself is correct and I'm not asking for it to be weakened. #4884 discusses the same protection for local commands and treats the policy as right, which I agree with. The ask is for an operator-controlled allowlist.
Why CGNAT is different from the other blocked ranges
Blocking RFC1918 and loopback is uncontroversial — those are ambient, attacker-guessable, and mean different things on every host. 100.64.0.0/10 in a Tailscale deployment is not ambient: addresses are assigned by a coordination server, reachable only inside an authenticated mesh the operator controls, and stable per-node.
For self-hosters, that range is the internal network. Tailscale is probably the single most common way people wire self-hosted services together now. So this isn't "webhooks are restricted in some edge case" — for a tailnet-based deployment, call_webhook cannot reach anything the operator actually runs.
Made worse by the failure being silent
#5122 reports call_webhook steps never delivering with no error surfaced, and names restricted egress as one cause. Combined, an operator on a tailnet gets a workflow step that silently does nothing. Nothing in the UI or logs says "this destination is blocked by SSRF policy," so the natural conclusion is that webhooks are broken, not that they're deliberately refusing.
Even without any policy change, surfacing "destination blocked by SSRF policy" as the step's error would save people a lot of time.
What would help
An operator-configurable destination allowlist — an env var of CIDRs or hostnames that check_ssrf permits. Nothing exists for this in .env.example today. Defaulting to empty keeps current behaviour for everyone who doesn't set it, so it's opt-in and the safe default is unchanged.
Summary
Workflow
call_webhookruns SSRF protection that rejects private and reserved address ranges, including100.64.0.0/10. That range is CGNAT, which is what Tailscale assigns to every node. The practical effect is that a self-hosted relay physically cannot reach any service on the operator's own tailnet, socall_webhookis unusable for a whole class of deployment rather than merely restricted.To be clear up front: the SSRF policy itself is correct and I'm not asking for it to be weakened. #4884 discusses the same protection for local commands and treats the policy as right, which I agree with. The ask is for an operator-controlled allowlist.
Why CGNAT is different from the other blocked ranges
Blocking RFC1918 and loopback is uncontroversial — those are ambient, attacker-guessable, and mean different things on every host.
100.64.0.0/10in a Tailscale deployment is not ambient: addresses are assigned by a coordination server, reachable only inside an authenticated mesh the operator controls, and stable per-node.For self-hosters, that range is the internal network. Tailscale is probably the single most common way people wire self-hosted services together now. So this isn't "webhooks are restricted in some edge case" — for a tailnet-based deployment,
call_webhookcannot reach anything the operator actually runs.Made worse by the failure being silent
#5122 reports
call_webhooksteps never delivering with no error surfaced, and names restricted egress as one cause. Combined, an operator on a tailnet gets a workflow step that silently does nothing. Nothing in the UI or logs says "this destination is blocked by SSRF policy," so the natural conclusion is that webhooks are broken, not that they're deliberately refusing.Even without any policy change, surfacing "destination blocked by SSRF policy" as the step's error would save people a lot of time.
What would help
check_ssrfpermits. Nothing exists for this in.env.exampletoday. Defaulting to empty keeps current behaviour for everyone who doesn't set it, so it's opt-in and the safe default is unchanged.Option 1 alone would unblock this entirely for self-hosters, and it puts the decision with the person who owns both ends of the connection.
Possibly related
check_ssrfrejecting private/reserved addresses (lines 745–766) and proposes out-of-band registration. Different remedy, same underlying tension.call_webhooksilently not delivering, restricted egress named as a cause.Environment
Self-hosted
buzz-relay(ghcr.io/block/buzz:main, image built 2026-08-09). All internal services reachable only over Tailscale (100.64.0.0/10).