Skip to content

fix(daemon): run a sandbox git credential helper through sh - #2799

Merged
zfy0701 merged 1 commit into
agentconnect-md:mainfrom
joerideturck:fix/git-credential-helper-via-sh
Oct 5, 2026
Merged

zfy0701 merged 1 commit into
agentconnect-md:mainfrom
joerideturck:fix/git-credential-helper-via-sh

Conversation

@joerideturck

Copy link
Copy Markdown
Contributor

Follow-up to #2794.

Why #2794 is not enough

#2794 made the daemon build emit dist/bin/git-credential, so a daemon installation used as a helper root has
the helper git is pointed at. The build writes it as 0755 and assert-self-contained.mjs checks that, but npm
drops the mode when it packs. Every non-bin file in the tarball is 0644. On a host upgraded to 2.2.0-rc.41 with
agentconnect upgrade:

-rw-r--r-- 1 qai qai 142 Oct 26  1985 ~/.agentconnect/versions/2.2.0-rc.41/dist/bin/git-credential

So a session placed on another daemon still fails every credentialed clone, now with
…/dist/bin/git-credential: Permission denied instead of not found.

The CLI already works around npm's mode loss for the seccomp helpers: repairDaemonBundleModes in
packages/cli/src/install.ts (#666). Adding the wrapper to that list would not fix this, though.
@agentconnect.md/cli is installed separately, and agentconnect upgrade only replaces the daemon payload
(cli-daemon-split.md). A host keeps its CLI until the operator reinstalls it, so the fix would miss hosts with an
older CLI, and it would never reach versions already installed.

Change

  • quotedHelper builds the helper line for a sandbox target as !sh '<helper>' <agentId>, not
    !'<helper>' <agentId>. sh reads the wrapper instead of executing it, so its mode no longer matters. This
    ships with the daemon, so it reaches every host that upgrades.
  • Sandbox targets are POSIX by construction. The image's /opt/agentconnect/bin/git-credential (0555) and
    microsandbox's wrapper work the same through sh.
  • Daemon-target lines (the daemon's own run/ shim, written 0755 on every boot) are unchanged.
  • Repo-local .git/config lines written before this keep the old form. They only matter where the helper is
    executable, which it is in the image.
  • daemon-sandbox-backends.md notes that git runs a sandbox helper through sh.

Tests

  • New: git-injection.test.ts › "runs an installation helper that npm shipped without its executable bit".
    Real git credential fill runs with the env cloneGitEnv builds for an agent whose helper root is a daemon
    installation, with bin/git-credential at 0644. Without the change it fails with the production error
    (…/bin/git-credential: Permission denied); with it, git gets the helper's answer.
  • The three sandbox helper-line expectations in git-injection.test.ts now expect !sh '…'.
  • git-injection, sandbox-credential-helper, gitea-gitcred, host-shim, shim-paths, executor-facet,
    executor-plane, srt-local, daemon-session-hosts, microsandbox-launch: 246 passed. The 2 failures in
    daemon-session-hosts (microsandbox custom TLS) fail identically on main on macOS.
  • Daemon typecheck, eslint and prettier are clean.

Not in this PR

  • assert-self-contained.mjs still checks the wrapper's executable bit in dist. That check is now harmless
    but no longer needed.
  • repairDaemonBundleModes is unchanged. The seccomp helpers have the same old-CLI gap.

🤖 Generated with Claude Code

agentconnect-md#2794 ships dist/bin/git-credential with the daemon, but npm packs every non-bin
file as 0644 and only the CLI's repairDaemonBundleModes restores modes. The CLI is
installed separately and not upgraded with the daemon, so on rc.41 git still fails,
now with 'Permission denied'. Reading the helper with sh makes its mode irrelevant.

@agentconnect-md-test agentconnect-md-test Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed revision 1e6e3a6c; no blocking findings. Invoking the sandbox wrapper through sh fixes the missing executable bit while preserving helper arguments and the daemon-target invocation.

A standalone smoke check using the changed helper formatter and shipped wrapper reproduced the 0644 permission failure before the change and succeeded afterward, including paths containing spaces and apostrophes. The Vitest suite was not run here because pnpm and dependencies are absent.

sent by review-bot (Codex · gpt-6-astra) · open in session

@zfy0701
zfy0701 merged commit 24b2874 into agentconnect-md:main Oct 5, 2026
13 checks passed
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.

2 participants