[BUG] Background git fetch bypasses permissions.deny and sandbox SSH_AUTH_SOCK denial, using the ssh-agent key on every window focus
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Background git fetch ignores permission and sandbox settings, triggers
Secure Enclave key prompts on window focus
Summary
The Claude Code desktop app runs git fetch against the project's remote in the
background, apparently on window focus and periodically. On a machine where the
SSH key is held in the Secure Enclave (Secretive/SecretAgent) with authentication
required, this produces a Touch ID prompt every time.
This happens despite ~/.claude/settings.json explicitly denying both Bash(git *)
and the SSH_AUTH_SOCK environment variable. Those settings correctly constrain
the agent's tool calls, but the app's own git activity bypasses them entirely.
There is no setting anywhere in the app to disable it.
Environment
- Claude Code desktop app version: Claude 2.7032.0 (6c468a) 2026-09-22T05:53:19.000Z
- macOS Version 27.0 (26A428), Apple Silicon
- git: /opt/homebrew/bin/git
- SSH agent: Secretive / SecretAgent, key in Secure Enclave, auth required per use
- Remote: SSH on a non-standard port (GitLab self-hosted)
What happens
A Touch ID prompt appears reading:
SecretAgent is trying to sign a request from "Claude" using secret
"<key name>"
It appears on app launch, on switching to the Claude window, and at seemingly
random intervals. Approving it lets the fetch proceed; denying it makes the fetch
fail silently.
Evidence
Full process ancestry, captured while the prompt was open:
ssh 72454 ← 72453 ssh -o BatchMode=yes -o SendEnv=GIT_PROTOCOL -p 1764 \
git@<git-host> git-upload-pack '/<group>/<repo>.git'
git 72453 ← 13481 /opt/homebrew/bin/git -c core.hooksPath=/dev/null \
-c safe.directory=* -c core.fsmonitor=false \
-c branch.autoSetupMerge=false -c gc.auto=0 \
-c maintenance.auto=false -c submodule…
app 13481 ← 13440 /Applications/Claude.app/Contents/Frameworks/
Claude Helper.app/Contents/MacOS/Claude Helper
--type=utility --utility-sub-type=node.mojom.NodeService
app 13440 ← 1 /Applications/Claude.app/Contents/MacOS/Claude
The git process is spawned directly by the app's node utility helper, with the
app's own hardening flags — not by any user command or agent tool call.
Note the git process exits within roughly a second while ssh blocks on the
agent prompt and is reparented to PID 1. This makes the cause hard to find:
watching for git fetch in ps usually catches nothing, because by the time the
prompt is visible only the orphaned ssh remains.
Relevant settings (all respected by the agent, all bypassed here)
"permissions": {
"deny": ["Bash(git )", "Bash(git:)", "Read(~/.ssh/**)", ...]
},
"sandbox": {
"credentials": {
"files": [{ "path": "~/.ssh", "mode": "deny" }],
"envVars": [{ "name": "SSH_AUTH_SOCK", "mode": "deny" }]
}
}
Verified working for agent tool calls: agent git commands were refused, and the
agent's shell has no agent socket. The app's own fetch has the full user
environment, agent socket included.
Why this matters
The key being used grants root access to production servers. The prompt is the
only thing standing between a background process and that key, and it fires often
enough to train users into approving reflexively. A user who has explicitly denied
git and denied agent access in configuration would reasonably expect the app not
to use their SSH key at all.
There is also no way to audit what the fetch is for, and no way to turn it off.
Steps to reproduce
- Store an SSH key in the Secure Enclave via Secretive, with authentication
required for each use.
- Add that key to a git host and use an SSH remote.
- Open a Claude Code session in that repository.
- Switch away from the Claude window and back.
- Observe the SecretAgent prompt naming "Claude".
To capture the ancestry:
while :; do P=$(pgrep -f git-upload-pack | head -1); [ -z "$P" ] && \
{ sleep 0.05; continue; }; X=$P; while [ -n "$X" ] && [ "$X" != "1" ]; do \
ps -p $X -o pid,ppid,command=; X=$(ps -p $X -o ppid= | tr -d ' '); done; \
break; done
Leave the Touch ID prompt open while reading the output.
Related issues
- #92679 — same subsystem and triggers (startup, window focus, periodic refresh),
same lack of an opt-out, different symptom (remote tags re-fetched, ignoring
remote.<name>.tagOpt --no-tags). That report states no git.exe is spawned
on Windows, whereas the macOS trace above shows a spawned
/opt/homebrew/bin/git — possibly two mechanisms, or platform divergence.
- #68057 (closed) — the app resolves and sets
SSH_AUTH_SOCKitself, which is
consistent with it reaching the agent despite the user denying that variable
in sandbox.credentials.envVars.
What Should Happen?
Requested
- A setting to disable background remote git operations.
- Failing that, have the app honour the existing
permissions.denyand
sandbox.credentials.envVars settings for its own git invocations, or at
minimum not inherit SSH_AUTH_SOCK when the user has denied it.
- Documentation of what the background fetch is for and how often it runs.
Error Messages/Logs
Steps to Reproduce
Claude code session on macOS which is a git repo
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 2.7032.0 (6c468a) 2026-09-22T05:53:19.000Z
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
_No response_
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗