From 1b45732930e6c55195ea867c3b0e5b2e3a4825b1 Mon Sep 17 00:00:00 2001 From: Sam Morrow Date: Wed, 19 Aug 2026 14:21:03 +0200 Subject: [PATCH 1/3] fix(http): make server lockdown mode an upper bound over requests In HTTP mode, RequestDeps.GetFlags previously combined the server operator's --lockdown-mode / GITHUB_LOCKDOWN_MODE configuration with the per-request X-MCP-Lockdown header using AND logic. This meant a request that omitted the header silently disabled lockdown mode even when the operator had explicitly enabled it server-wide. Change the combination to OR (server-enabled OR request-enabled), so server configuration is an upper bound: the operator's setting can never be relaxed by a request, while a request may still opt itself into lockdown mode when the operator has not already enabled it. This mirrors the existing upper-bound pattern already used for read-only mode in HTTP mode. Also align GetRepoAccessCache's cache-construction condition with the same effective-lockdown check so request-only lockdown mode has a working cache instead of failing closed with a "lockdown cache is not configured" error. Add focused tests covering server-only, request-only, both, and neither lockdown configurations, plus a regression test for the specific bug (server-enabled lockdown surviving a request that omits the header). Update README and the server-configuration/remote-server docs to describe the upper-bound semantics and reiterate that lockdown mode is a best-effort content filter, not a security boundary. Fixes #3104 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- README.md | 4 +- docs/remote-server.md | 3 +- docs/server-configuration.md | 6 +- pkg/github/dependencies.go | 14 +++- pkg/github/dependencies_test.go | 120 ++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 67943bc5c4..7db619448e 100644 --- a/README.md +++ b/README.md @@ -1600,7 +1600,7 @@ docker run -i --rm \ ## Lockdown Mode -Lockdown mode limits the content that the server will surface from public repositories. When enabled, the server checks whether the author of each item has push access to the repository. Private repositories are unaffected, and collaborators keep full access to their own content. +Lockdown mode limits the content that the server will surface from public repositories. When enabled, the server checks whether the author of each item has push access to the repository. Private repositories are unaffected, and collaborators keep full access to their own content. Lockdown mode is a best-effort content filter, not a security boundary. ```bash ./github-mcp-server --lockdown-mode @@ -1615,6 +1615,8 @@ docker run -i --rm \ ghcr.io/github/github-mcp-server ``` +In HTTP mode, this flag (or `GITHUB_LOCKDOWN_MODE`) is an upper bound: the `X-MCP-Lockdown` request header can enable lockdown mode when the operator has not, but it cannot disable lockdown mode the operator has already enabled. See the [Server Configuration Guide](docs/server-configuration.md#lockdown-mode) for details. + The behavior of lockdown mode depends on the tool invoked. Following tools will return an error when the author lacks the push access: diff --git a/docs/remote-server.md b/docs/remote-server.md index 04d3ceefae..d8587a3116 100644 --- a/docs/remote-server.md +++ b/docs/remote-server.md @@ -67,9 +67,10 @@ The Remote GitHub MCP server has optional headers equivalent to the Local server - `X-MCP-Readonly`: Enables only "read" tools. - Equivalent to `GITHUB_READ_ONLY` env var for Local server. - If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true. -- `X-MCP-Lockdown`: Enables lockdown mode, hiding public issue details created by users without push access. +- `X-MCP-Lockdown`: Enables lockdown mode, hiding public issue details created by users without push access. Lockdown mode is a best-effort content filter, not a security boundary. - Equivalent to `GITHUB_LOCKDOWN_MODE` env var for Local server. - If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true. + - Server-side lockdown configuration is an upper bound: if the operator has already enabled lockdown mode, this header cannot disable it for a request. The header can only enable (or redundantly re-enable) lockdown mode; it cannot relax lockdown mode below the operator's configuration. - `X-MCP-Insiders`: Enables insiders mode for early access to new features. - Equivalent to `GITHUB_INSIDERS` env var or `--insiders` flag for Local server. - If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true. diff --git a/docs/server-configuration.md b/docs/server-configuration.md index 500c4bb868..21429ebc3d 100644 --- a/docs/server-configuration.md +++ b/docs/server-configuration.md @@ -29,6 +29,8 @@ Note: **read-only** mode acts as a strict security filter that takes precedence Note: **excluded tools** takes precedence over toolsets and individual tools — listed tools are always excluded, even if their toolset is enabled or they are explicitly added via `--tools` / `X-MCP-Tools`. +Note: server-side **lockdown mode** (`--lockdown-mode` / `GITHUB_LOCKDOWN_MODE`) is an upper bound in HTTP mode — once an operator enables it, the `X-MCP-Lockdown` header can no longer disable it for a given request. A request may still use the header to enable lockdown mode for itself when the operator has not already enabled it server-wide, but it can never relax lockdown mode below what the operator configured. Lockdown mode remains a best-effort content filter, not a security boundary. + --- ## Configuration Examples @@ -290,7 +292,9 @@ When active, this mode will disable all tools that are not read-only even if the **Best for:** Public repositories where you want to limit content from users without push access. -Lockdown mode ensures the server only surfaces content in public repositories from users with push access to that repository. Private repositories are unaffected, and collaborators retain full access to their own content. +Lockdown mode ensures the server only surfaces content in public repositories from users with push access to that repository. Private repositories are unaffected, and collaborators retain full access to their own content. Lockdown mode is a best-effort content filter, not a security boundary. + +> In HTTP mode, server-side lockdown mode (`--lockdown-mode` / `GITHUB_LOCKDOWN_MODE`) is an upper bound: the `X-MCP-Lockdown` header can enable lockdown mode for a request when the operator has not enabled it server-wide, but it cannot disable lockdown mode the operator has already enabled. **Example:** diff --git a/pkg/github/dependencies.go b/pkg/github/dependencies.go index c13f248c56..12fc842b57 100644 --- a/pkg/github/dependencies.go +++ b/pkg/github/dependencies.go @@ -439,9 +439,19 @@ func (d *RequestDeps) GetRawClient(ctx context.Context) (*raw.Client, error) { return rawClient, nil } +// effectiveLockdownMode reports whether lockdown mode is active for the current +// request. Server-side configuration (d.lockdownMode) is an upper bound: once the +// operator has enabled lockdown mode, no request can disable it. Request-scoped +// configuration (the X-MCP-Lockdown header, surfaced via ghcontext.IsLockdownMode) +// may only tighten restrictions by enabling lockdown when the operator has not +// already done so; it can never be used to relax server-enforced lockdown. +func (d *RequestDeps) effectiveLockdownMode(ctx context.Context) bool { + return d.lockdownMode || ghcontext.IsLockdownMode(ctx) +} + // GetRepoAccessCache implements ToolDependencies. func (d *RequestDeps) GetRepoAccessCache(ctx context.Context) (*lockdown.RepoAccessCache, error) { - if !d.lockdownMode { + if !d.effectiveLockdownMode(ctx) { return nil, nil } @@ -466,7 +476,7 @@ func (d *RequestDeps) GetT() translations.TranslationHelperFunc { return d.T } // GetFlags implements ToolDependencies. func (d *RequestDeps) GetFlags(ctx context.Context) FeatureFlags { return FeatureFlags{ - LockdownMode: d.lockdownMode && ghcontext.IsLockdownMode(ctx), + LockdownMode: d.effectiveLockdownMode(ctx), } } diff --git a/pkg/github/dependencies_test.go b/pkg/github/dependencies_test.go index 0ff3f3520a..cf8f09772b 100644 --- a/pkg/github/dependencies_test.go +++ b/pkg/github/dependencies_test.go @@ -198,6 +198,126 @@ func TestIsFeatureEnabled_EmptyFlagName(t *testing.T) { assert.False(t, result, "Expected false for empty flag name") } +// TestRequestDepsLockdownModeIsUpperBound verifies that, in HTTP mode, the +// server operator's --lockdown-mode / GITHUB_LOCKDOWN_MODE configuration is an +// upper bound: request-scoped configuration (the X-MCP-Lockdown header, +// surfaced as ghcontext.WithLockdownMode) may enable or tighten lockdown, but +// can never disable lockdown the operator has already turned on. Lockdown mode +// remains a best-effort content filter, not a security boundary — this test +// only asserts the on/off decision, not any content-filtering guarantee. +func TestRequestDepsLockdownModeIsUpperBound(t *testing.T) { + t.Parallel() + + resolver := newRequestDepsAPIHostResolver(t, "https://example.com") + + newDeps := func(serverLockdown bool) *github.RequestDeps { + return github.NewRequestDeps( + resolver, + "test", + serverLockdown, + nil, + translations.NullTranslationHelper, + 0, + nil, + testExporters(), + ) + } + + tokenCtx := func(requestLockdown bool) context.Context { + ctx := ghcontext.WithTokenInfo(context.Background(), &ghcontext.TokenInfo{Token: "request-token"}) + if requestLockdown { + ctx = ghcontext.WithLockdownMode(ctx, true) + } + return ctx + } + + tests := []struct { + name string + serverLockdown bool + requestLockdown bool + wantLockdownMode bool + }{ + { + name: "neither server nor request enable lockdown", + serverLockdown: false, + requestLockdown: false, + wantLockdownMode: false, + }, + { + name: "server-only lockdown is enforced without a request header", + serverLockdown: true, + requestLockdown: false, + wantLockdownMode: true, + }, + { + name: "request-only lockdown can enable it when the server has not", + serverLockdown: false, + requestLockdown: true, + wantLockdownMode: true, + }, + { + name: "server and request both enabling lockdown stays enabled", + serverLockdown: true, + requestLockdown: true, + wantLockdownMode: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + deps := newDeps(tt.serverLockdown) + ctx := tokenCtx(tt.requestLockdown) + + flags := deps.GetFlags(ctx) + assert.Equal(t, tt.wantLockdownMode, flags.LockdownMode, "GetFlags().LockdownMode") + + cache, err := deps.GetRepoAccessCache(ctx) + require.NoError(t, err) + if tt.wantLockdownMode { + assert.NotNil(t, cache, "expected a repo access cache to be built when lockdown mode is effectively enabled") + } else { + assert.Nil(t, cache, "expected no repo access cache when lockdown mode is effectively disabled") + } + }) + } +} + +// TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader is a focused +// regression test for the specific bug in #3104: previously, server-enabled +// lockdown mode was disabled for any request that did not also send the +// X-MCP-Lockdown header, letting a request silently opt out of an operator's +// security posture. A request simply omitting the header (as opposed to +// explicitly disabling it, which the header format does not support) must not +// relax lockdown mode below what the operator configured. +func TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader(t *testing.T) { + t.Parallel() + + resolver := newRequestDepsAPIHostResolver(t, "https://example.com") + deps := github.NewRequestDeps( + resolver, + "test", + true, // server operator enabled lockdown mode + nil, + translations.NullTranslationHelper, + 0, + nil, + testExporters(), + ) + + // No ghcontext.WithLockdownMode call: this is what happens when a request + // does not send the X-MCP-Lockdown header at all. + ctx := ghcontext.WithTokenInfo(context.Background(), &ghcontext.TokenInfo{Token: "request-token"}) + + flags := deps.GetFlags(ctx) + assert.True(t, flags.LockdownMode, "server-enabled lockdown mode must remain enabled when a request omits the lockdown header") + + cache, err := deps.GetRepoAccessCache(ctx) + require.NoError(t, err) + assert.NotNil(t, cache, "repo access cache must still be built so server-enabled lockdown mode can be enforced") +} + func TestIsFeatureEnabled_CheckerError(t *testing.T) { t.Parallel() From 9b67dac07c0501c1ee0a1f0cb1b5969c91e096b8 Mon Sep 17 00:00:00 2001 From: Sam Morrow Date: Wed, 19 Aug 2026 14:52:00 +0200 Subject: [PATCH 2/3] test(transport): stop sharing http.DefaultTransport across parallel tests httptest.Server.Close closes the idle connections of the process-global http.DefaultTransport, whichever server is being shut down. Every test in this package runs in parallel, issues a live request through http.DefaultTransport and shuts down its own server, so one test's cleanup could break another test's in-flight request with: net/http: HTTP/1.x transport connection broken: http: CloseIdleConnections called That flake failed build (ubuntu-latest) on this branch, and reproduces on unmodified main under `go test ./pkg/http/transport -race -count=800`, hitting both bearer_test.go and graphql_features_test.go. It is unrelated to the lockdown change in this PR. Give each test its own http.Transport so the global side effect cannot reach it. TestGraphQLFeaturesTransport_NilTransport asserts the documented nil to http.DefaultTransport fallback, so it keeps using that global and now runs serially instead. Assertions and coverage are unchanged. The same stress run that reproduced the failure now passes 2500 iterations under -race. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- pkg/http/transport/bearer_test.go | 10 ++++---- pkg/http/transport/graphql_features_test.go | 11 +++++---- pkg/http/transport/helpers_test.go | 26 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 pkg/http/transport/helpers_test.go diff --git a/pkg/http/transport/bearer_test.go b/pkg/http/transport/bearer_test.go index 0bf3549fc5..49f50710d0 100644 --- a/pkg/http/transport/bearer_test.go +++ b/pkg/http/transport/bearer_test.go @@ -58,7 +58,7 @@ func TestBearerAuthTransport(t *testing.T) { defer server.Close() rt := &BearerAuthTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), Token: tc.token, TokenProvider: tc.tokenProvider, } @@ -91,7 +91,7 @@ func TestBearerAuthTransport_TokenProviderResolvedPerRequest(t *testing.T) { current := "" rt := &BearerAuthTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), TokenProvider: func() string { return current }, } @@ -126,7 +126,7 @@ func TestBearerAuthTransport_PassesGraphQLFeaturesHeader(t *testing.T) { defer server.Close() rt := &BearerAuthTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), Token: "token", } @@ -150,7 +150,7 @@ func TestBearerAuthTransport_DoesNotMutateOriginalRequest(t *testing.T) { defer server.Close() rt := &BearerAuthTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), Token: "token", } @@ -356,7 +356,7 @@ func TestBearerAuthTransport_RedirectHostScoping(t *testing.T) { require.NoError(t, err) client := &http.Client{Transport: &BearerAuthTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), Token: "secret-token", AllowedHosts: []string{sourceURL.Host, allowedTargetURL.Host}, }} diff --git a/pkg/http/transport/graphql_features_test.go b/pkg/http/transport/graphql_features_test.go index 1a0dc4214f..531eb9c679 100644 --- a/pkg/http/transport/graphql_features_test.go +++ b/pkg/http/transport/graphql_features_test.go @@ -65,7 +65,7 @@ func TestGraphQLFeaturesTransport(t *testing.T) { // Create the transport transport := &GraphQLFeaturesTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), } // Create a request @@ -91,9 +91,12 @@ func TestGraphQLFeaturesTransport(t *testing.T) { } } +// TestGraphQLFeaturesTransport_NilTransport asserts the documented fallback to +// http.DefaultTransport, so it must exercise that global rather than an +// isolated transport. It therefore runs serially: httptest.Server.Close closes +// http.DefaultTransport's idle connections, so a parallel test shutting down +// its own server would otherwise be able to break this request. func TestGraphQLFeaturesTransport_NilTransport(t *testing.T) { - t.Parallel() - var capturedHeader string // Create a test server @@ -133,7 +136,7 @@ func TestGraphQLFeaturesTransport_DoesNotMutateOriginalRequest(t *testing.T) { // Create the transport transport := &GraphQLFeaturesTransport{ - Transport: http.DefaultTransport, + Transport: newIsolatedTransport(t), } // Create a request with features diff --git a/pkg/http/transport/helpers_test.go b/pkg/http/transport/helpers_test.go new file mode 100644 index 0000000000..91027c4db8 --- /dev/null +++ b/pkg/http/transport/helpers_test.go @@ -0,0 +1,26 @@ +package transport + +import ( + "net/http" + "testing" +) + +// newIsolatedTransport returns an http.Transport owned by a single test. +// +// httptest.Server.Close closes the idle connections of the process-global +// http.DefaultTransport, regardless of which server is being shut down. Tests +// here run in parallel and each shut down a server, so sharing +// http.DefaultTransport lets one test's cleanup break another test's request +// with "http: CloseIdleConnections called". Giving every test its own +// transport keeps that global side effect out of reach. +// +// Use this wherever a test just needs a working transport. Tests that assert +// behaviour specific to http.DefaultTransport must use it directly and must +// not run in parallel. +func newIsolatedTransport(t *testing.T) *http.Transport { + t.Helper() + + transport := &http.Transport{} + t.Cleanup(transport.CloseIdleConnections) + return transport +} From 5a1863bcb69eb182b676d3708e8857324c14ff3f Mon Sep 17 00:00:00 2001 From: Sam Morrow Date: Wed, 19 Aug 2026 15:10:40 +0200 Subject: [PATCH 3/3] refactor: trim excessive comments from lockdown upper-bound PR Condense multi-line narration into short, focused comments. Keep only the non-obvious invariants (lockdown precedence, isolated transport rationale) and drop restated code/step-by-step prose. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- pkg/github/dependencies.go | 10 ++++----- pkg/github/dependencies_test.go | 24 ++++++--------------- pkg/http/transport/graphql_features_test.go | 8 +++---- pkg/http/transport/helpers_test.go | 14 ++++-------- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/pkg/github/dependencies.go b/pkg/github/dependencies.go index 12fc842b57..dfa5d96ed5 100644 --- a/pkg/github/dependencies.go +++ b/pkg/github/dependencies.go @@ -439,12 +439,10 @@ func (d *RequestDeps) GetRawClient(ctx context.Context) (*raw.Client, error) { return rawClient, nil } -// effectiveLockdownMode reports whether lockdown mode is active for the current -// request. Server-side configuration (d.lockdownMode) is an upper bound: once the -// operator has enabled lockdown mode, no request can disable it. Request-scoped -// configuration (the X-MCP-Lockdown header, surfaced via ghcontext.IsLockdownMode) -// may only tighten restrictions by enabling lockdown when the operator has not -// already done so; it can never be used to relax server-enforced lockdown. +// effectiveLockdownMode reports whether lockdown mode is active for the +// request. d.lockdownMode is an operator-set upper bound: the per-request +// X-MCP-Lockdown header (ghcontext.IsLockdownMode) can only enable lockdown, +// never disable one the operator already turned on. func (d *RequestDeps) effectiveLockdownMode(ctx context.Context) bool { return d.lockdownMode || ghcontext.IsLockdownMode(ctx) } diff --git a/pkg/github/dependencies_test.go b/pkg/github/dependencies_test.go index cf8f09772b..7b7abaa62d 100644 --- a/pkg/github/dependencies_test.go +++ b/pkg/github/dependencies_test.go @@ -198,13 +198,8 @@ func TestIsFeatureEnabled_EmptyFlagName(t *testing.T) { assert.False(t, result, "Expected false for empty flag name") } -// TestRequestDepsLockdownModeIsUpperBound verifies that, in HTTP mode, the -// server operator's --lockdown-mode / GITHUB_LOCKDOWN_MODE configuration is an -// upper bound: request-scoped configuration (the X-MCP-Lockdown header, -// surfaced as ghcontext.WithLockdownMode) may enable or tighten lockdown, but -// can never disable lockdown the operator has already turned on. Lockdown mode -// remains a best-effort content filter, not a security boundary — this test -// only asserts the on/off decision, not any content-filtering guarantee. +// TestRequestDepsLockdownModeIsUpperBound verifies the X-MCP-Lockdown header +// can only enable lockdown, never disable the operator's server-side setting. func TestRequestDepsLockdownModeIsUpperBound(t *testing.T) { t.Parallel() @@ -284,13 +279,9 @@ func TestRequestDepsLockdownModeIsUpperBound(t *testing.T) { } } -// TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader is a focused -// regression test for the specific bug in #3104: previously, server-enabled -// lockdown mode was disabled for any request that did not also send the -// X-MCP-Lockdown header, letting a request silently opt out of an operator's -// security posture. A request simply omitting the header (as opposed to -// explicitly disabling it, which the header format does not support) must not -// relax lockdown mode below what the operator configured. +// TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader is a regression +// test for #3104: omitting the X-MCP-Lockdown header must not disable +// server-enabled lockdown mode. func TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader(t *testing.T) { t.Parallel() @@ -298,7 +289,7 @@ func TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader(t *testing.T) { deps := github.NewRequestDeps( resolver, "test", - true, // server operator enabled lockdown mode + true, // server-enabled lockdown nil, translations.NullTranslationHelper, 0, @@ -306,8 +297,7 @@ func TestRequestDepsLockdownModeCannotBeDisabledByOmittingHeader(t *testing.T) { testExporters(), ) - // No ghcontext.WithLockdownMode call: this is what happens when a request - // does not send the X-MCP-Lockdown header at all. + // No X-MCP-Lockdown header sent. ctx := ghcontext.WithTokenInfo(context.Background(), &ghcontext.TokenInfo{Token: "request-token"}) flags := deps.GetFlags(ctx) diff --git a/pkg/http/transport/graphql_features_test.go b/pkg/http/transport/graphql_features_test.go index 531eb9c679..8c814fd6f2 100644 --- a/pkg/http/transport/graphql_features_test.go +++ b/pkg/http/transport/graphql_features_test.go @@ -91,11 +91,9 @@ func TestGraphQLFeaturesTransport(t *testing.T) { } } -// TestGraphQLFeaturesTransport_NilTransport asserts the documented fallback to -// http.DefaultTransport, so it must exercise that global rather than an -// isolated transport. It therefore runs serially: httptest.Server.Close closes -// http.DefaultTransport's idle connections, so a parallel test shutting down -// its own server would otherwise be able to break this request. +// TestGraphQLFeaturesTransport_NilTransport exercises the real +// http.DefaultTransport fallback, so it can't run in parallel with tests that +// close their own servers (that closes DefaultTransport's idle conns too). func TestGraphQLFeaturesTransport_NilTransport(t *testing.T) { var capturedHeader string diff --git a/pkg/http/transport/helpers_test.go b/pkg/http/transport/helpers_test.go index 91027c4db8..5d509275bf 100644 --- a/pkg/http/transport/helpers_test.go +++ b/pkg/http/transport/helpers_test.go @@ -7,16 +7,10 @@ import ( // newIsolatedTransport returns an http.Transport owned by a single test. // -// httptest.Server.Close closes the idle connections of the process-global -// http.DefaultTransport, regardless of which server is being shut down. Tests -// here run in parallel and each shut down a server, so sharing -// http.DefaultTransport lets one test's cleanup break another test's request -// with "http: CloseIdleConnections called". Giving every test its own -// transport keeps that global side effect out of reach. -// -// Use this wherever a test just needs a working transport. Tests that assert -// behaviour specific to http.DefaultTransport must use it directly and must -// not run in parallel. +// Sharing http.DefaultTransport across parallel tests is unsafe: closing one +// test's httptest.Server also closes DefaultTransport's idle connections, +// breaking other tests still using it. Tests asserting DefaultTransport +// fallback behavior specifically must use it directly and not run in parallel. func newIsolatedTransport(t *testing.T) *http.Transport { t.Helper()