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
{{ message }}
Repository navigation
Derive DPoP-signed request URLs from the HttpApi contract #17600
executeAuthenticatedEnvironmentHttpRequest (environmentHttpAuth.ts) builds the URL that gets signed separately from the request that gets sent. Callers pass a hand-written url: (httpBaseUrl) => environmentEndpointUrl(...) template next to the typed HttpApi client call, and the two can drift apart.
#17599 was one case: mcp:… thread ids are percent-encoded in the sent path but not in the signed one. Over T3 Connect the environment rejected those requests with url_mismatch, which the client showed as invalid_credential. The fix encoded the id in three templates, but any new path parameter can break the same way, and only DPoP connections catch the mismatch.
Proposal
Build the signed URL from the contract, the same way the request does. makeEnvironmentHttpApiUrlBuilder in rpc/http.ts already wraps HttpApiClient.urlBuilder. It uses the same compilePath as the request client, so the signed path and the sent path match by construction. Its doc comment already says it exists "for authentication proofs", but only pullRequestDiffHttp.ts uses it.
Move the threadSnapshotHttp, boundedThreadSnapshotHttp, threadHistoryHttp, shellSnapshotHttp, session, and deviceHubAccess loaders to makeEnvironmentHttpApiUrlBuilder(httpBaseUrl).<group>.<endpoint>({ params }).
Consider having executeAuthenticatedEnvironmentHttpRequest take the endpoint and params rather than a free-form url callback, so a caller cannot hand-roll a URL.
The environmentEndpointUrl calls in authorization/ and environment/descriptor.ts hit fixed paths before a relay session exists. Check whether they're in scope, but they're not the risky case.
Follow-up to #17599.
Problem
executeAuthenticatedEnvironmentHttpRequest(environmentHttpAuth.ts) builds the URL that gets signed separately from the request that gets sent. Callers pass a hand-writtenurl: (httpBaseUrl) => environmentEndpointUrl(...)template next to the typed HttpApi client call, and the two can drift apart.#17599 was one case:
mcp:…thread ids are percent-encoded in the sent path but not in the signed one. Over T3 Connect the environment rejected those requests withurl_mismatch, which the client showed asinvalid_credential. The fix encoded the id in three templates, but any new path parameter can break the same way, and only DPoP connections catch the mismatch.Proposal
Build the signed URL from the contract, the same way the request does.
makeEnvironmentHttpApiUrlBuilderin rpc/http.ts already wrapsHttpApiClient.urlBuilder. It uses the samecompilePathas the request client, so the signed path and the sent path match by construction. Its doc comment already says it exists "for authentication proofs", but onlypullRequestDiffHttp.tsuses it.threadSnapshotHttp,boundedThreadSnapshotHttp,threadHistoryHttp,shellSnapshotHttp,session, anddeviceHubAccessloaders tomakeEnvironmentHttpApiUrlBuilder(httpBaseUrl).<group>.<endpoint>({ params }).executeAuthenticatedEnvironmentHttpRequesttake the endpoint and params rather than a free-formurlcallback, so a caller cannot hand-roll a URL.The
environmentEndpointUrlcalls inauthorization/andenvironment/descriptor.tshit fixed paths before a relay session exists. Check whether they're in scope, but they're not the risky case.