macOS: Keychain item written without trusted-application list -> auth prompt on every credential read

Open 💬 0 comments Opened Jul 15, 2026 by pgaultier

Version: 2.1.207 (also on 2.1.206)
Platform: macOS (Apple Silicon), login.keychain-db
Install: single, no tmux, no SSH, single terminal session

Summary

Claude Code stores OAuth credentials in a keychain item Claude Code-credentials, and reads it back by shelling out to /usr/bin/security.

The item is created without any trusted-application entry (no -T equivalent). macOS therefore prompts for the keychain password on every read -- in practice every LLM call, i.e. every 3-4 minutes of active use.

"Always Allow" does not help: Claude Code rewrites/recreates the item, and the new item again has an empty trusted-application list, discarding the granted ACL.

This is NOT the multi-session refresh race (#24317, #48786), which surfaces as an unexpected /login. And it is not limited to third-party tools (#22144): here the CLI prompts on its own reads.

Evidence

1. claude spawns security, and is not authorized against the item it wrote.
Process ancestry captured while the dialog was on screen:

  PID   PPID  COMMAND
68091  56374  security
56374    793  claude
  793    757  -zsh
  757    656  login

2. The keychain ACL machinery is healthy on this machine.
A control item created with an explicit trusted app reads back silently, twice, no prompt:

security add-generic-password -s "acl-test" -a "$USER" -w "x" -T /usr/bin/security
security find-generic-password -s "acl-test" -w   # -> x, no dialog
security find-generic-password -s "acl-test" -w   # -> x, no dialog

This rules out a corrupted keychain or a broken SecurityAgent.

3. Rewriting the item WITH -T /usr/bin/security suppresses the per-read prompts.

TOKEN=$(security find-generic-password -s "Claude Code-credentials" -w)
security delete-generic-password -s "Claude Code-credentials"
security add-generic-password -s "Claude Code-credentials" -a "$USER" -w "$TOKEN" -T /usr/bin/security

Prompt frequency drops from ~1 every 3-4 min to ~1 every 1h45. The residual prompts correlate exactly with Claude Code rewriting the item (ACL lost on rewrite):

| Event | cdat | mdat | Prompt |
|---|---|---|---|
| Item rewritten manually with -T | 14:10 CEST | 14:10 | none for 1h45 |
| Claude Code rewrote the item | 14:10 | 15:55 | dialog at 15:55 |

4. ~/.claude/.credentials.json is not an effective fallback on macOS.
With a valid credentials file in place, the keychain item was deleted. Claude Code recreated it on its own (fresh cdat), again with no trusted-application list, and prompting resumed. The file is not consulted in preference to the keychain, contrary to what several community workarounds assume.

Impact

Any macOS user on the keychain path gets an OS password dialog every few minutes of active use. Not dismissible, not remembered, not fixable from the user side. Only mitigation is to periodically rewrite the item by hand with -T, which reduces but does not eliminate the prompts.

Suggested fixes (in order of preference)

  1. Attach a trusted-application list on write (equivalent to security add-generic-password -T <path>), so the ACL is valid from creation and no user interaction is ever needed.
  2. Update the item in place instead of delete-and-recreate, so a user-granted ACL survives a token refresh.
  3. Honour ~/.claude/.credentials.json on macOS as on Linux, and do not silently recreate the keychain item.

View original on GitHub ↗