Repository navigation
feat(agents): add shared URL policy for web tools - #2526
Merged
Merged
Conversation
|
Contributor
|
✅ agents import sizes: no significant changes ( |
ben-reitz
added this pull request to stack #2528
October 8, 2026 11:55
ben-reitz
force-pushed
the
web-fetch/policy
branch
from
October 8, 2026 12:14
50eef21 to
3971e70
Compare
ben-reitz
force-pushed
the
web-fetch/policy
branch
from
October 8, 2026 12:28
3971e70 to
50eef21
Compare
ben-reitz
force-pushed
the
web-fetch/policy
branch
from
October 8, 2026 12:43
50eef21 to
3b8f5fd
Compare
ben-reitz
force-pushed
the
web-fetch/policy
branch
from
October 8, 2026 12:47
3b8f5fd to
211a4da
Compare
ben-reitz
marked this pull request as ready for review
October 8, 2026 12:47
agents
@cloudflare/ai-chat
@cloudflare/codemode
hono-agents
@cloudflare/shell
@cloudflare/think
@cloudflare/voice
@cloudflare/worker-bundler
commit: |
ben-reitz
force-pushed
the
web-fetch/policy
branch
2 times, most recently
from
October 8, 2026 13:33
1aa6c5d to
0f986d0
Compare
Adds src/web/url-policy.ts (scheme, credentials, length, allowed/blocked host patterns, and a private/local host check over the URL parser's canonical hostnames; a subset of the IANA special-purpose registries, RFC 6890) and moves abortable() from websearch to src/web so both web tools share it. Internal for now; web_fetch is the first consumer.
`[::1]:8080` slipped past the pattern check because the URL parser drops the port, leaving a pattern that matched every port. A bracketed literal must end at its bracket, and nothing is a subdomain of an IP literal.
ben-reitz
force-pushed
the
web-fetch/policy
branch
from
October 8, 2026 14:05
0f986d0 to
c9ec2dc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the URL policy that
web_fetch(next PRs) checks on every hop, and movesabortable()out of websearch so both web tools share it. Internal only; nothing is exported from the package yet.The policy relies on the WHATWG URL parser having already canonicalised the hostname, so there is no hand-written IP parsing:
isPrivateOrLocalHostis a range table — a deliberate subset of the IANA IPv4/IPv6 Special-Purpose Address Registries (RFC 6890): loopback, RFC 1918, CGNAT, link-local (cloud metadata),192.0.0/24,198.18/15, multicast,240/4; IPv6::/96(incl.::,::1), IPv4-mapped (re-checked as v4), NAT64, 6to4,fc00::/7,fe80::/10,fec0::/10,ff00::/8; pluslocalhost,*.localhost,*.internal. Hostnames are not resolved —127.0.0.1.nip.iopasses. In production Workers egress cannot reach private ranges anyway; this exists for local dev, other runtimes, and defence in depth, and the header comment says so.Evidence
Before: no shared policy; Think's
fetch_urlcarried its ownisBlockedHostlist (replaced in refactor(think): share the private-host policy with agents/webfetch #2521).After:
src/tests/web/url-policy.test.ts— one case per class, including the spellings that prove we lean on the parser:vitest run src/tests/web→ 101 passed; typecheck → 132 projects.Merge Danger
Door: two-way
Internal module with no consumers until #2527.
Blast Radius: none
abortablewas never exported fromagents/websearch, so the move is invisible to users. websearch tests unchanged and passing.