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)
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗