macOS: PhotoKit access blocked — Claude Code missing photos-library entitlement and NSPhotoLibraryUsageDescription

Resolved 💬 1 comment Opened May 1, 2026 by dballesteros7 Closed May 31, 2026

Environment

  • macOS 26.3.1 (Tahoe)
  • Claude Code 2.1.121
  • Tool affected: any PhotoKit-using CLI (e.g. osxphotos) when run via Claude Code's Bash tool

Symptom

Running osxphotos export <dest> --use-photos-export --download-missing ... from Claude Code's Bash tool fails immediately with:

Requesting access to use your Photos library. Click 'Allow Access to All Photos' in the dialog box to grant access.
Error: could not get authorization to access Photos library
Please ensure that your  is granted access in 'System Settings > Privacy & Security > Photos'

No system dialog ever appears, and Claude Code never shows up under System Settings → Privacy & Security → Photos regardless of relaunches or tccutil reset. The Photos pane uses a request-driven model (no + button), so the user cannot pre-grant.

Root cause

The Claude Code app bundle is missing both pieces required for PhotoKit access:

$ codesign -d --entitlements - "~/Library/Application Support/Claude/claude-code/2.1.121/claude.app" | grep "\[Key\]"
        [Key] com.apple.security.cs.allow-jit
        [Key] com.apple.security.cs.allow-unsigned-executable-memory
        [Key] com.apple.security.cs.disable-library-validation
        [Key] com.apple.security.device.audio-input
# (no com.apple.security.personal-information.photos-library)

$ defaults read ".../claude.app/Contents/Info.plist" | grep -iE "Usage|Description"
    NSMicrophoneUsageDescription = "Claude Code uses the microphone for voice dictation.";
# (no NSPhotoLibraryUsageDescription)

Without the usage description string, macOS silently refuses to show the consent dialog (same TCC behavior pattern as #52524).

Asymmetry with Claude Desktop

Claude Desktop (/Applications/Claude.app, bundle ID com.anthropic.claudefordesktop) does declare the photos-library entitlement:

$ codesign -d --entitlements - "/Applications/Claude.app" | grep -i photo
        [Key] com.apple.security.personal-information.photos-library

So this looks like an unintentional omission in the Claude Code bundle (com.anthropic.claude-code) rather than a deliberate policy difference.

Workaround (current)

osxphotos has an AppleScript fallback (--download-missing without --use-photos-export) which uses Apple Events instead of PhotoKit. Apple Events is granted, so this path works for items already on disk. For cloud-only items, the AppleScript path repeatedly fails with AppleScript export has failed 10 consecutive times, restarting Photos app and most items end up missing. Users have to fall back to running osxphotos in Terminal.app for any bulk export of cloud-only items.

Requested fix

Add to Claude Code's app bundle:

  1. Entitlement: com.apple.security.personal-information.photos-library
  2. Info.plist key: NSPhotoLibraryUsageDescription with a string like "Claude Code accesses your Photos library when you run a tool (e.g. osxphotos) that needs to read or export photos."

This unblocks the entire ecosystem of PhotoKit-using CLIs — most relevantly osxphotos, which is the de-facto tool for scripted Photos library access on macOS. Without it, Claude Code can read the SQLite database (with FDA) and download already-local items, but cannot reliably pull cloud-only originals at scale, which defeats much of the value of running osxphotos through Claude on a small-disk Mac with iCloud Optimize Storage enabled.

Related

  • #52524 — same pattern (missing speech-recognition entitlement on Claude Desktop, closed as wrong-repo)
  • #54691 — TCC grants not preserved across Claude Code versions (the versioned bundle path means even granted permissions break on each update)

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗