Skip to content

Keep clone tokens out of operator credential helpers and traces - #2078

Merged
ppXD merged 1 commit into
mainfrom
fix/keep-clone-tokens-out-of-credential-helpers
Oct 6, 2026
Merged

ppXD merged 1 commit into
mainfrom
fix/keep-clone-tokens-out-of-credential-helpers

Conversation

@ppXD

@ppXD ppXD commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Every platform git command whose transport reaches a tokened remote now runs as a TokenedGitCommand (backend/src/CodeSpace.Core/Services/Agents/Workspace/TokenedGitCommand.cs). That covers:
    • the workspace clone with its soft-ref probe and pin fetches
    • the publish lfs push, push and readback ls-remote
    • the launch-base ls-remote
    • the integration clone and push
    • the grader base clone
    • a pack clone from a pasted URL
  • A tokened command does two things:
    • It gets -c credential.<scheme>://<authority>.helper= ahead of its argv. Before this, git's transport handed the URL's password to every helper in system and global config on success, so an operator's store, cache or keychain helper kept each run's token at rest.
    • It runs with GIT_TRACE2, GIT_TRACE2_EVENT and GIT_TRACE2_PERF set to 0. Operator trace2 targets record every command's argv and each child's; git 2.33 writes the password verbatim, and -c cannot override this because git reads trace2 config first.
  • The reset is scoped to the tokened remote, not a global credential.helper=. git asks the same helper list for an authenticating proxy's password (http.proxy=http://user@host or http_proxy) and for an LFS endpoint on another host. A global reset made every tokened command fail there with could not read Password … terminal prompts disabled.
  • Untokened commands keep the operator's helpers and tracing, which may be how they reach a private mirror. The integration clone's checkout, apply and reset stay untokened: they reach the tokened origin only for LFS objects, which git-lfs authenticates from the URL without asking or telling a helper.

Test plan

  • Unit: TokenedGitCommandTests pins the scoped reset and the trace2 environment literally. Call-site pins cover the provider, publish, resolver, integrator, grader and pack clone (TokenedGitSpecs).
  • Unit: full suite, 11878 passed, 1 skipped
  • Integration: TokenedGitCredentialHelperFlowTests uses real git, git-lfs and LocalProcessRunner, a scratch HOME/GIT_CONFIG_GLOBAL and a loopback smart-HTTP remote. It passed 20/20 on git 2.33.0, 2.50.1 and 2.56.0 with git-lfs 3.7.1. Rows:
    • store positive controls for each subcommand
    • a helper-authenticated proxy
    • operator trace2 targets
    • an integration over LFS history
  • The proxy and trace2 rows are red against an unscoped reset without the trace2 environment.
  • Integration: the 39 classes that drive the touched services passed 452/452 on git 2.33.0. On 2.56.0 one known real-process agent stall occurred; that class passed 23/23 on rerun.
  • Worker image: the claim that LFS downloads store nothing is verified with git-lfs 3.7.1 only, not with Debian's git-lfs

Every platform git command that carries a clone token in its URL - the
workspace clone with its soft-ref probe and pin fetches, the publish
push, LFS upload and readback, the launch-base ls-remote, the
integration clone and push, the grader's base clone, and a pack clone
from a pasted URL - still honoured system and global git config. On
success git's transport hands the URL's username and password to every
configured credential helper to store (git lfs push too: it runs that
transport against the URL itself), so an operator's store or cache
helper, or a system keychain, kept each run's token at rest. git also
writes every command's argv, and each child's, to the trace2 targets
that config names, and git 2.33 writes the URL's password verbatim.

A tokened command now runs with `-c credential.<scheme>://<host>.helper=`.
An empty value scoped to the tokened remote clears the helper list git
builds for that remote - global helpers and ones scoped to its URL,
path, user or an included file alike - and a command-line value is read
last, so nothing is stored and nothing is asked: the token is already
in the URL. The reset is scoped rather than global because git asks the
same helpers for other hosts' credentials; an authenticating proxy
named with only a user, or an LFS endpoint on another host, still gets
the operator's password. A tokened command also runs with GIT_TRACE2,
GIT_TRACE2_EVENT and GIT_TRACE2_PERF set to 0, which wins over the
trace2 targets in config; a -c cannot, because git reads those first.

TokenedGitCommand is the one place that decides a command is tokened -
its git transport can reach a remote whose URL embeds a password - and
applies both. Untokened commands keep the operator's helpers and
tracing, which may be how they reach a private mirror. A checkout,
reset or apply in a clone whose origin is tokened stays untokened: it
reaches origin only for LFS objects, and git-lfs authenticates those
from the URL without asking or telling a helper.

Verified against git 2.33.0, 2.50.1 and 2.56.0 with git-lfs 3.7.1.

The remote fixture's port retry reused an HttpListener that a failed
Start had already closed; each attempt now gets a fresh listener.
@ppXD
ppXD merged commit 04a9d5a into main Oct 6, 2026
6 checks passed
@ppXD
ppXD deleted the fix/keep-clone-tokens-out-of-credential-helpers branch October 6, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant