macOS TCC Automation grants not preserved across CC versions — Settings panel accumulates one row per release
Summary
On macOS, every new release of Claude Code registers as a separate app
in System Settings → Privacy & Security → Automation. Old entries
from binaries that no longer exist persist indefinitely. The list
grows by roughly one row per CC release where the Bash tool invokesosascript.
Reproduction
- Run CC version A (e.g. 2.1.90) and execute a Bash call that uses
osascript to control an app (Reminders, Photos, Calendar, etc.).
macOS prompts for Automation permission; user clicks Allow.
- CC auto-updates to version B (2.1.91).
- Run the same osascript action. macOS prompts again — TCC treats it
as a new app.
- Repeat for every subsequent release.
After ~30 releases, the Automation panel shows one row per version
(2.1.90, 2.1.91, … 2.1.121), each expandable to a list of
controlled apps. None can be deleted via the GUI in current macOS.
Expected
CC releases should share a stable code-signing identity / designated
requirement so TCC matches them as the same app. A user who grants
Automation to one CC version should not be re-prompted on every
update, and the panel should show a single Claude Code row.
Actual
Each version registers separately. Stale entries persist after the
binary is gone. Users see repeat prompts and accumulating clutter.
Environment
- macOS 26.4.1 (build 25E253)
- Claude Code 2.1.121, with stale Automation entries back to 2.1.90
- Bash tool calling
/usr/bin/osascript
Impact
- Repeat consent prompts erode the trust signal — users start
clicking Allow reflexively, defeating TCC's purpose.
- The Automation panel becomes unusable for auditing what CC can
actually control today versus historically.
- Cleanup paths are unattractive:
tccutil reset Automationnukes
all Automation grants for every app on the system; direct edits
to TCC.db require Full Disk Access and are unsupported.
Likely cause
CC's signature designated requirement appears to be version-pinned
rather than identifier-based. TCC uses the designated requirement to
decide whether two binaries are the same app. If the requirement
references the exact code signature or version, every release looks
new.
Suggested fix
Audit the CC code-signing setup. The designated requirement in the
signature should match by Team ID + bundle identifier (e.g.identifier "com.anthropic.claude-code" and anchor apple generic and), not by exact binary
certificate leaf[subject.OU] = "<TEAM_ID>"
hash, so TCC sees 2.1.90 and 2.1.121 as the same app.
6 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
+1 — seeing the exact same pattern on macOS, with one important nuance: I think the suggested fix above is mis-aimed.
Empirical evidence (one machine, ~17 days)
Direct query of
~/Library/Application Support/com.apple.TCC/TCC.db:14+ rows total over 17 days, one per release, each storing the literal versioned path as
client. That's the same pattern your Automation grants are showing — TCC storesclient_pathliterally and treatsversions/2.1.122andversions/2.1.123as different clients.The DR is already Team-ID-anchored — code signing isn't the problem
codesign -d -r-on the currentclaude(2.1.123) returns:That already matches by Team ID + bundle identifier (not by cdhash) — which is what your "suggested fix" recommends. So the DR isn't the obstruction; this DR is correct and would let TCC see two CC versions as the same app for app-bundle-keyed services.
The reason it doesn't help for command-line
claudeis that TCC keys grants onclient_pathfor non-bundled binaries, and the install layout produces a new path on every release (~/.local/share/claude/versions/<v>/). The DR isn't being consulted to merge old/new paths because nothing is asking it to — TCC just sees an unfamiliar client path and prompts.Real fix is the install layout, not the signature
The path needs to be stable across releases. Options:
~/.local/share/claude/current/claude), keep version directories around for rollback but expose only the stable name to TCC..appso TCC keys on bundle ID + DR rather than path.versions/<old>row to the newversions/<new>row inTCC.db). Requires FDA, ugly, but unblocks today's installs without changing the layout.Cross-references that all describe the same path-keying problem with different symptoms:
Workaround for users hitting this today
Set
DISABLE_AUTOUPDATER=1(orDISABLE_UPDATES=1for stricter), pin to a version, re-grant once. Stops the daily-grant churn until the install layout is fixed upstream. Trade-off is manualclaude updatecadence.Same root cause here — macOS Sequoia (Darwin 25.4), Claude Code via npm.
Beyond Automation, this also affects Files and Folders. Each release registers a separate entry under Privacy & Security > Files and Folders with its own toggles for Desktop, Documents, and Downloads. Versions 2.1.117 through 2.1.129 each appear as distinct rows; granting folder access to one version does not carry over to the next.
Affected TCC scopes observed so far:
kTCCServiceAppleEvents(Automation — as described in this issue)kTCCServiceSystemPolicyDesktopFolderkTCCServiceSystemPolicyDocumentsFolderkTCCServiceSystemPolicyDownloadsFolderThe suggested fix (DR anchored on Team ID + bundle identifier) should cover all of these since TCC uses the same designated-requirement matching across scopes. Worth confirming the scope of any signing change covers Files and Folders in addition to Automation.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
Bumping this
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.