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
Type: documentation / example request Area:examples/ (signing side)
Summary
The repo has good coverage of verifying web-bot-auth on the edge (examples/verification-workers, examples/caddy-plugin) and signing from a browser (examples/browser-extension) or a hardcoded Rust request (examples/rust). What’s missing is the case that’s becoming common: a Cloudflare Agent signing its own outbound HTTP requests so they can be verified by an origin the operator controls (e.g. a self-hosted backend behind Caddy/the existing caddy-plugin).
This is non-obvious enough to be worth an example, for two reasons specific to the Agents SDK:
Durable Object outbound fetch isn’t interceptable. Cloudflare Agents run on Durable Objects, and outbound fetch() from a DO is not intercepted by Outbound Workers, proxies, or mTLS bindings (see Outbound Workers and Durable Objects workers-sdk#13946). So there is no transparent layer to attach a signature — it has to be signed inline, at the point the request leaves the agent.
The correct injection point is the MCP client transport. When the agent reaches the origin via its built-in MCP client (this.mcp), the developer never holds the Request object directly, so signatureHeaders(request, …) can’t be called at a call site. The clean hook is the transport’s custom fetch.
The pattern (verified against types, not yet a built example)
agents (MCPTransportOptions) forwards to the MCP TypeScript SDK’s StreamableHTTPClientTransportOptions, which exposes:
/** Custom fetch implementation used for all network requests. */
fetch?: FetchLike;// @modelcontextprotocol/sdk/shared/transport
So a signing wrapper can be passed straight through:
The same makeSigningFetch works for a hand-written tool that calls fetch directly, not just the MCP path.
Why it’s useful in the repo
It closes the loop with the existing verify-side examples: examples/caddy-plugin / examples/verification-workers show the origin verifying; this would show a Cloudflare-native client producing the signatures they verify.
The DO-outbound and MCP-transport details are easy to get wrong and aren’t discoverable from the current examples.
It demonstrates web-bot-auth for the agent-to-self-hosted-origin topology (the operator owns both ends, so the directory is just their own public key), which is distinct from the public-crawler framing.
Proposal
Add examples/cloudflare-agents-signing/ (or a docs section) containing:
A minimal Agent that signs outbound calls via transport.fetch.
Key generation + how the public JWK maps to a /.well-known/http-message-signatures-directory consumed by the caddy-plugin example.
A note on the DO-outbound-interception constraint and why signing is inline.
Caveats / open questions
I’ve verified the transport.fetch hook against agents@0.14.1 and @modelcontextprotocol/sdk@1.29.0 types, but have not built/run the end-to-end example, so the streamable-http vs SSE auto-probe path and the exact covered-component set should be exercised against the live test directory before this is published.
If maintainers feel the signing side is already represented by browser-extension, the differentiator here is purely the Agents-SDK / MCP-transport specifics — happy to scope it down to a docs snippet rather than a full example if preferred.
Type: documentation / example request
Area:
examples/(signing side)Summary
The repo has good coverage of verifying web-bot-auth on the edge (
examples/verification-workers,examples/caddy-plugin) and signing from a browser (examples/browser-extension) or a hardcoded Rust request (examples/rust). What’s missing is the case that’s becoming common: a Cloudflare Agent signing its own outbound HTTP requests so they can be verified by an origin the operator controls (e.g. a self-hosted backend behind Caddy/the existing caddy-plugin).This is non-obvious enough to be worth an example, for two reasons specific to the Agents SDK:
fetch()from a DO is not intercepted by Outbound Workers, proxies, or mTLS bindings (see Outbound Workers and Durable Objects workers-sdk#13946). So there is no transparent layer to attach a signature — it has to be signed inline, at the point the request leaves the agent.this.mcp), the developer never holds theRequestobject directly, sosignatureHeaders(request, …)can’t be called at a call site. The clean hook is the transport’s custom fetch.The pattern (verified against types, not yet a built example)
agents(MCPTransportOptions) forwards to the MCP TypeScript SDK’sStreamableHTTPClientTransportOptions, which exposes:So a signing wrapper can be passed straight through:
The same
makeSigningFetchworks for a hand-written tool that callsfetchdirectly, not just the MCP path.Why it’s useful in the repo
examples/caddy-plugin/examples/verification-workersshow the origin verifying; this would show a Cloudflare-native client producing the signatures they verify.Proposal
Add
examples/cloudflare-agents-signing/(or a docs section) containing:Agentthat signs outbound calls viatransport.fetch./.well-known/http-message-signatures-directoryconsumed by the caddy-plugin example.Caveats / open questions
transport.fetchhook againstagents@0.14.1and@modelcontextprotocol/sdk@1.29.0types, but have not built/run the end-to-end example, so the streamable-http vs SSE auto-probe path and the exact covered-component set should be exercised against the live test directory before this is published.browser-extension, the differentiator here is purely the Agents-SDK / MCP-transport specifics — happy to scope it down to a docs snippet rather than a full example if preferred.Happy to contribute the PR.