macOS: background agent binary lacks bundle ID, causing TCC permission churn on upgrades
Summary
The Claude Code background agent helper (/Users/<user>/.local/share/claude/versions/<version>) is a bare binary with no .app bundle or Info.plist. macOS keys TCC (Privacy & Security) permissions on bundle identifier when available, and falls back to the binary path when not. Without a stable bundle ID, every version upgrade creates a new TCC entry — so users end up re-granting permissions (Accessibility, Automation, Full Disk Access, etc.) after each update, and accumulate orphaned entries in System Settings.
Steps to Reproduce
- Install Claude Code CLI and run a background agent session (
claude agents) - Open System Settings → Privacy & Security → (any TCC category)
- Note the entry appears as
/Users/<user>/.local/share/claude/versions/2.1.147(or current version) rather than "Claude Code" - After a version upgrade, repeat — a new entry appears for the new version path; the old entry remains
Process Tree (from ps aux)
claude agents ← launcher in terminal
claude daemon run --origin transient --spawned-by ... ← daemon
/.../.local/share/claude/versions/2.1.147 --bg-spare ← background session (TCC-visible)
/.../.local/share/claude/versions/2.1.147 --bg-pty-host
Impact
- Permission churn: TCC grants are path-keyed, so each upgrade invalidates prior grants. Users get re-prompted without understanding why.
- Orphaned entries: Old version paths accumulate in Privacy & Security with no way to associate them with Claude Code.
- Trust signal mismatch: Claude Code requests meaningful system access (file reads, Automation for AppleScript, etc.) but presents as an anonymous versioned path — the same visual pattern as malware. Users trained to be cautious will deny; users trained to click through will approve anything. Both outcomes are bad.
Expected Behavior
The background helper should appear as "Claude Code" in Privacy & Security, with a stable identity across version upgrades.
Fix
Wrap the background helper binary in a minimal .app bundle with an Info.plist containing:
<key>CFBundleIdentifier</key>
<string>com.anthropic.claude-code</string>
<key>CFBundleDisplayName</key>
<string>Claude Code</string>
<key>LSUIElement</key>
<true/>
LSUIElement = true suppresses the Dock icon — no user-visible behavior change. The stable CFBundleIdentifier is the load-bearing fix: macOS will key TCC permissions on bundle ID instead of path, so upgrades stop fragmenting grants. Code-signing the bundle with a stable Developer ID completes the fix.
The user-facing claude CLI entrypoint and versioned directory layout don't need to change.
Environment
- macOS (Apple Silicon)
- Claude Code 2.1.147
- Session type: background agent (
claude agents)
5 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Acknowledging #49282 as the likely shared root cause — the TCC path-keying issue on version bumps is the same underlying problem.
That said, keeping this issue open separately because the background agent execution path is a distinct Mach-O invocation that may need explicit fix verification. The chain here is:
The
--bg-spareworker is the process macOS attributes permission prompts to — it's separate from the CLI launcher binary. If a fix ships that only addresses the CLI entry point (~/.local/bin/claude), the agent daemon path would still be broken. Both needInfo.plist/ bundle ID coverage.Leaving this open with
area:agentsto track that the fix is verified against the agent execution path specifically, not just the CLI. Happy to close once confirmed.Feedback ID for internal session telemetry cross-reference:
9d70f4a1-ff17-41a1-9bd7-22a84e50ef8fAddressed by a merged fix. Please reopen with a fresh repro if you still see this on a current version.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.