fix(x402-buyer): set obol-buy-x402/1.0 User-Agent on outbound HTTP#503
Merged
Conversation
Sellers behind Cloudflare WAF block the Go stdlib default UA
("Go-http-client/1.1") with HTTP 403 + error code 1010. Live evidence
from today's demo against https://inference.v1337.org/services/aeon:
a direct call from inside the litellm pod to the buyer sidecar at
127.0.0.1:8402/v1/chat/completions returned HTTP 403 error code 1010.
c2dddc1 fixed this in buy.py (the agent-side prober/signer) but missed
the x402-buyer sidecar — the in-pod Go relay that makes the actual paid
chat-completions calls to upstream sellers. The buy flow could complete
probe + sign + register (all via buy.py with the good UA), but the paid
request itself failed because the sidecar sent the default Go UA.
Set userAgent = "obol-buy-x402/1.0 (+https://github.com/ObolNetwork/obol-stack)"
(matching the constant from c2dddc1 byte-for-byte) on both:
- firstReq: the initial unpaid probe that triggers the 402 challenge
- retryReq: the paid retry carrying the X-PAYMENT header
Override with OBOL_BUYER_USER_AGENT env var for sellers that require a
different UA shape (mirrors the buy.py override mechanism).
Add two unit tests (TestProxy_UserAgentOnProbeRequest and
TestProxy_UserAgentOnPaidRequest) using httptest.Server to assert the
UA is present on both the probe and the paid request paths.
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
User-Agent: obol-buy-x402/1.0 (+https://github.com/ObolNetwork/obol-stack)on every outbound HTTP request the x402-buyer sidecar makes to upstream sellers (both the initial 402 probe and the paid retry carryingX-PAYMENT), mirroring the pattern and exact UA string from c2dddc1.OBOL_BUYER_USER_AGENTenv override for sellers that require a different UA shape, matching the buy.py mechanism.Why
Cloudflare WAF 1010 release-blocker for sellers like v1337. Live evidence from today's demo against
https://inference.v1337.org/services/aeon:Cloudflare blocks the Go stdlib default UA (
Go-http-client/1.1) with error code 1010. c2dddc1 fixed this inbuy.py(the agent-side prober/signer), but missed the Go sidecar — so probe + sign + register all passed, but the actual paid chat-completions request failed.Files touched
internal/x402/buyer/proxy.go—userAgentvar + twoHeader.Setcalls inreplayableX402Transport.RoundTripinternal/x402/buyer/proxy_test.go— two new tests asserting UA on probe and paid request pathsTest plan
TestProxy_UserAgentOnProbeRequest— httptest server captures probe UA, asserts exact stringTestProxy_UserAgentOnPaidRequest— httptest server captures both probe and paid UA, asserts bothgo test ./internal/x402/buyer/ -count=1— all tests pass (no regressions)go build ./...— clean buildhttps://inference.v1337.org/services/aeonshould succeed end-to-end after this landsRisks
None — UA-only change. No payment logic, routing, or auth handling modified.