macOS TCC permissions are bound to versions/<version> instead of the signed bundle, so Screen Recording and Accessibility must be re-granted after every update

Status Open
Reported on v2.1.224
Maintainer reply None cached
Activity 0 comments · opened Aug 7, 2026

Summary

On macOS, Claude Code's Screen Recording and Accessibility (Apple Events) grants are attributed to the per-version executable at ~/.local/share/claude/versions/<version> rather than to the signed app bundle. Two consequences:

  1. The permission dialog is unidentifiable. It names the process 2.1.224, so the user sees a bare version number with no indication it is Claude Code. I denied it initially for exactly this reason — I had no idea what was asking.
  2. The grant does not survive an update. Because the path contains the version, each release is a different executable to TCC, so every update silently loses the permission. Claude Code updates frequently; I have four versions on disk (2.1.2212.1.224) from a short window.

The net effect is that any workflow depending on screen capture or UI scripting breaks after each update, with no error that points at the cause — the tools just start failing.

Why this looks like an attribution bug rather than expected behaviour

The bundle is present and properly signed with a stable identity:

$ codesign -dv ~/.local/share/claude/ClaudeCode.app
Identifier=com.anthropic.claude-code
TeamIdentifier=Q6L2SF6YDW

So a stable TCC subject already exists. The process that actually triggers the prompt is a child of the bundle's main executable:

/bin/zsh
  └─ ~/.local/share/claude/versions/2.1.224              ← TCC attributes here
       └─ ~/.local/share/claude/ClaudeCode.app/Contents/MacOS/claude
            └─ ~/.local/bin/claude

TCC keys on the responsible process. Because the versioned binary is the responsible process rather than the bundle, the grant is recorded against a path that changes on every release, instead of against com.anthropic.claude-code, which does not.

Reproduction

  1. On macOS, run a Claude Code session that calls screencapture, or osascript -e 'tell application "System Events" ...'.
  2. Observe the permission prompt names a bare version number (e.g. 2.1.224), not Claude Code.
  3. Grant it. Restart Claude Code. The tool now works.
  4. Let Claude Code update to a new version.
  5. The same call fails again:
  • screencapture -x out.pngcould not create image from display
  • osascriptexecution error: Not authorized to send Apple events to System Events. (-1743)
  1. System Settings → Privacy & Security shows the previously granted entry still listed under the old version number, now inert.

Suggested fix

Make the bundle the responsible process for TCC, so grants key on com.anthropic.claude-code and persist across updates. Options that would each address it:

  • Launch the versioned binary as a bundled helper (inside ClaudeCode.app/Contents/) with the bundle as its responsible process, rather than from a sibling versions/ directory.
  • Set the responsible process explicitly for the spawned child so TCC attributes to the parent bundle.
  • Failing either, keep a stable path (e.g. versions/current as a symlink target that is itself the executed path) so the TCC subject does not change per release.

A secondary improvement regardless of the above: the prompt should present a recognisable name. Even when attribution is correct, a dialog reading 2.1.224 gives the user nothing to decide on, and the safe default is to deny.

Environment

  • Claude Code 2.1.224
  • macOS 26.6 (build 25G72), Apple silicon
  • Install path: ~/.local/share/claude/, launcher ~/.local/bin/claude
  • Affected APIs: Screen Recording (screencapture), Accessibility / Apple Events (osascript → System Events)

Related

  • #63037 — docs omit the macOS Privacy & Security identity for background agents. Adjacent, but that is a documentation gap; this is that the identity itself is unstable.
  • #74631 — Computer Use per-app request_access. Different mechanism.

View original on GitHub ↗