macOS: desktop app's bundled Claude Code uses a version-numbered executable path, causing a burst of TCC permission prompts after every update
Summary
The Claude desktop app on macOS runs its own bundled copy of Claude Code from a version-numbered path:
~/Library/Application Support/Claude/claude-code/<version>/claude.app/Contents/MacOS/claude
macOS TCC keys privacy grants to the executable path. Because the version number is in the path, every desktop app update produces a brand new executable path with zero grants, and the user gets a fresh burst of permission dialogs. This repeats on every single update, indefinitely.
What the user sees
A stack of modal dialogs, typically first thing in the morning after an overnight update:
"2.1.NNN" wants to access files managed by "Dropbox".
It is a burst rather than one dialog, because a new path resets every service independently. In our case that was one kTCCServiceFileProviderDomain prompt per cloud mount (Dropbox, iCloud Drive, Google Drive, CloudMounter), plus SystemPolicyDownloadsFolder, SystemPolicyDesktopFolder, SystemPolicyDocumentsFolder, SystemPolicyNetworkVolumes, MediaLibrary, and Calendar.
The dialog shows a bare version number rather than an app name, so it reads as a mystery process and is easy to mistake for malware.
Reproduction
- Use the Claude desktop app on macOS with files in a cloud provider folder (Dropbox, iCloud Drive, Google Drive).
- Grant access when prompted. Confirm it is quiet.
- Let the desktop app update itself.
- The prompts return in full.
Evidence
Running process after the 2.1.247 update:
/Users/<user>/Library/Application Support/Claude/claude-code/2.1.247/claude.app/Contents/MacOS/claude
Zero rows in the user TCC database for any path under Application Support/Claude/claude-code, while the previous version's grants were still present under its own path.
The bundle is properly Developer ID signed with a stable identity across releases:
Identifier=com.anthropic.claude-code
Authority=Developer ID Application: Anthropic PBC (Q6L2SF6YDW)
TeamIdentifier=Q6L2SF6YDW
So the signing identity is not the problem. Only the path churn is.
Why the obvious workarounds do not work
- Adding
/Applications/Claude.appto Full Disk Access does not help. It was already enabled and the prompts still appeared. FDA on the parent app does not cover the separately-pathed bundled child process. - There is no user-controlled launcher to pin. For the standalone CLI at
~/.local/bin/claudea user can point a symlink at a fixed path and keep grants across updates. That works, and we did it. But the desktop app owns itsclaude-code/<version>/directory and recreates it on update, so the same trick is not available. - The only remaining option is manually cloning TCC rows onto the new path after each update, which is fragile, requires Full Disk Access to perform, and has to be redone every release.
Suggested fix
Launch the bundled Claude Code from a stable path that does not contain the version number, for example ~/Library/Application Support/Claude/claude-code/current/claude.app/..., with the versioned directories kept behind it as an implementation detail. Since the code signing identity is already stable across releases, a stable path would let TCC grants persist across updates the same way they do for any normally-installed application.
A secondary improvement: the prompt currently displays only a version string. Presenting a recognizable application name would stop it reading as an unknown process.
Environment
- macOS 26.x, Apple Silicon
- Claude desktop app, bundled Claude Code 2.1.247
- Cloud providers in use: Dropbox, iCloud Drive, Google Drive, CloudMounter