Repository navigation
feat(host-cloudflare): route configured internal hosts to service bindings - #13
Merged
Merged
Conversation
…e the SSRF guard HostedHttpClientOptions and HostConfig gain internalHosts: an exact hostname match goes to its fetcher; any other *.internal host is refused, and the guard rejects redirects into one. Applies to the MCP transport and the plain fetch.
…llow a redirect from an internal binding host-cloudflare config validates INTERNAL_MCP_HOSTS with the same helpers. Requests to a binding carry redirect: manual so the runtime cannot follow a Location past the SSRF guard. UPSTREAM.md splits 3ba849c; README documents the trust boundary.
…ice bindings Validates host=BINDING pairs at config load and fails loudly (503) when a mapped binding is absent or a host does not end in .internal. Passes the mapping to the hosted HTTP client, documents the trust boundary and the deploy path, ignores generated wrangler configs, and makes the e2e worker ignore a developer's local .dev.vars.
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.
What
A private MCP server in another Worker can now be reached over a service binding instead of the internet.
internalHostson the hosted HTTP client and host config. An exact hostname match goes to its binding, outside the SSRF guard. Any other*.internalhost is refused, a redirect from an external server into*.internalis refused, and requests to a binding go out withredirect: "manual"so a 3xx from the bound Worker is never followed. Covers the MCP transport and the plain fetch.INTERNAL_MCP_HOSTS(host=BINDINGpairs) is validated at config load. A host naming a binding that is absent, or a host not ending in.internal, fails config load, so the Worker answers 503 with a message naming the host and binding instead of silently leaving an unreachable integration. Unset means no internal hosts and no behaviour change..gitignorefor generated wrangler configs; e2e workers ignore a developer's local.dev.vars.Tests
hosted-http-client.test.ts: exact host match (no suffix match), unknown*.internalrefused, external redirect into*.internalrefused, manual redirect to a binding returned untouched.internal-host.test.ts: MCP discovery against a real MCP server behind a binding.config.test.ts: mapping, trailing dot, unset, missing binding, non-.internalhost.