[BUG] macOS native install: `claude` reads its own credentials via `/usr/bin/security`, but the keychain item's partition list lacks `apple-tool:` — endless XARA keychain prompts, "Always Allow" never persists

Resolved 💬 3 comments Opened Jun 11, 2026 by izumis007 Closed Jun 14, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

What's Wrong?

On macOS, Claude Code (native install) repeatedly triggers the system keychain dialog:

security wants to access key "Claude Code-credentials" in your keychain.

Clicking Always Allow (and entering the login keychain password) silences it only temporarily. The prompt returns after a while — apparently after each OAuth token refresh — making it effectively endless. No third-party tools, statusline scripts, or hooks are involved: the process requesting access is claude itself.

Root Cause Analysis

The Claude Code-credentials keychain item appears to be written via Security.framework (partition list contains only the teamid: partition), while Claude Code reads it by spawning /usr/bin/security (CLI), which requires the apple-tool: partition. Since the item's partition list does not include apple-tool:, every CLI read triggers a XARA partition check and a user-facing prompt.

When the user clicks "Always Allow", macOS adds apple-tool: to the partition list and the prompts stop. But on the next OAuth token refresh, Claude Code rewrites the keychain item, resetting the partition list — and the cycle restarts:

  1. Token refresh → item rewritten → partition list resets (no apple-tool:)
  2. claude spawns /usr/bin/security to read credentials → XARA mismatch → prompt
  3. User clicks "Always Allow" → apple-tool: added → quiet for a few hours
  4. GOTO 1

This is the inverse of the failure mode described in steipete/CodexBar#458 (where the item is created with apple-tool: only and teamid:-partitioned third-party apps get rejected). Here, Claude Code's own read path is the one being rejected — the write path and read path of the same application use mismatched keychain partitions.

Evidence

1. The requesting process is claude itself

Polling loop run while the dialog was on screen (while :; do for p in $(pgrep -x security); do ...):

11:53:38 security(<pid1>) ← parent(<ppid>): claude
11:53:38 security(<pid2>) ← parent(<ppid>): claude
11:53:39 security(<pid1>) ← parent(<ppid>): claude
...

Two concurrent security child processes, both parented by the single claude process. No other tool on the system accesses this keychain item.

2. securityd logs showing the partition mismatch

securityd: [com.apple.securityd:integrity] ACL partition mismatch: client apple-tool: ACL (
securityd: [com.apple.securityd:integrity] asking user about XARA partition for 'apple-tool:'
securityd: [com.apple.securityd:kcacl] displaying keychain prompt for /usr/bin/security(<pid>); ACL: <AclValidationContext(action:65538)SUBJECT[not-init]OBJECT[not-init]>
securityd: [com.apple.securityd:integrity] user approved XARA access for 'apple-tool:'
securityd: [com.apple.securityd:integrity] adding XARA partition 'apple-tool:' to list

Note: the client is apple-tool: (i.e. /usr/bin/security) and it is not in the item's ACL partition list — confirming the item was created under a different partition (presumably teamid: via Security.framework).

3. Clean single-install environment

$ which -a claude
/Users/<user>/.local/bin/claude
 
$ ls -la ~/.local/bin/claude
lrwxr-xr-x ... /Users/<user>/.local/bin/claude -> /Users/<user>/.local/share/claude/versions/2.1.170
 
$ npm ls -g | grep -i claude
(nothing — no npm install)
 
$ claude --version
2.1.170 (Claude Code)

~/.claude/settings.json contains no statusLine and no hooks — only permissions, model, alwaysThinkingEnabled, effortLevel, autoUpdatesChannel, verbose.

What Should Happen?

Expected Behavior

  • Clicking "Always Allow" should permanently suppress the prompt, OR
  • Claude Code should read/write the keychain item through a single consistent mechanism so its own reads never trigger a XARA partition check, OR
  • Token refresh should update the item in place (SecItemUpdate / preserving ACL & partition list) instead of delete-and-recreate

Error Messages/Logs

Steps to Reproduce

  1. Install Claude Code via the native installer on macOS (single install, no npm/Homebrew copy)
  2. Log in with OAuth (/login) — credentials stored in keychain item Claude Code-credentials
  3. Use Claude Code normally across token-refresh cycles
  4. Observe the keychain dialog "security wants to access key 'Claude Code-credentials'"
  5. Click "Always Allow" and enter the keychain password
  6. Continue using Claude Code → the dialog reappears after the next token refresh

Claude Model

Opus

Is this a regression?

Not sure

Last Working Version

_No response_

Claude Code Version

2.1.170

Platform

Claude.ai (subscription)

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Additional Information

_No response_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗