Skip to content

Derive DPoP-signed request URLs from the HttpApi contract #17600

Description

@juliusmarminge

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-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.

  1. Move the threadSnapshotHttp, boundedThreadSnapshotHttp, threadHistoryHttp, shellSnapshotHttp, session, and deviceHubAccess loaders to makeEnvironmentHttpApiUrlBuilder(httpBaseUrl).<group>.<endpoint>({ params }).
  2. Consider having executeAuthenticatedEnvironmentHttpRequest take the endpoint and params rather than a free-form url callback, so a caller cannot hand-roll a URL.
  3. Keep the test from fix(client): load earlier turns works for MCP threads over T3 Connect #17599 that compares the signed URL with the fetched URL for every loader, not just thread loaders.

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.

Activity

  1. added a commit that references this issue on Oct 9, 2026
    6445712
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions