anthropics / anthropics/claude-code
[BUG] mcp-needs-auth-cache.json is shared across CLAUDE_SECURESTORAGE_CONFIG_DIR profiles — one account's auth failure blocks the other's MCP servers
- 主要语言
- Python
- 星标
- 145k
- 派生
- 23.1k
- PR 合并指标
- PR 指标待抓取
描述
## Environment
- Claude Code: 2.1.234 (native install)
- Platform: macOS (Darwin 27.0.0)
- Two accounts on one machine, split via `CLAUDE_SECURESTORAGE_CONFIG_DIR`
## Summary
`CLAUDE_SECURESTORAGE_CONFIG_DIR` correctly namespaces credential storage — each profile gets its own Keychain item (`Claude Code-credentials` vs `Claude Code-credentials-`). But `~/.claude/mcp-needs-auth-cache.json` is **not** namespaced: both profiles read and write the same file.
The cache is keyed by server name only, with a 15-minute TTL during which new processes skip the MCP connection attempt entirely (see #48670). Since claude.ai connector server names are identical across accounts ("claude.ai Teamwork", "claude.ai Figma", …), a needs-auth entry written by profile A blocks profile B from even attempting to connect — despite profile B holding a valid token in its own Keychain item.
## Repro
1. Set up two accounts:
- Profile A: plain `claude` (default securestorage)
- Profile B: `CLAUDE_SECURESTORAGE_CONFIG_DIR=internal claude`
2. Authenticate a claude.ai connector (e.g. Teamwork) on profile B; leave it unauthenticated/expired on profile A.
3. Start a session as profile A → the connector fails auth → entry written to the shared `~/.claude/mcp-needs-auth-cache.json`.
4. Within 15 minutes, start a session as profile B.
**Expected:** profile B connects — its Keychain item has a valid token.
**Actual:** profile B skips the connection ("cached needs-auth") and reports the server as requiring authentication.
## Impact
- Worst for SDK/headless consumers (`sdk-ts` entrypoint, agent hosts): they can't run `/mcp` interactively, so within the TTL window there is no in-session recovery. Combined with the cross-profile poisoning, alternating between two accounts makes MCP auth appear to "never stick" — each profile's failures continuously re-poison the other.
- Interactive sessions show misleading "needs authentication" status for servers that are actually fine for the current profile.
## Workaround
`rm -f ~/.claude/mcp-needs-auth-cache.json` after re-authenticating, before starting the next (SDK) session.
## Suggested fix
Namespace the needs-auth cache by the same securestorage profile hash already used for the Keychain service name — e.g. `mcp-needs-auth-cache-.json`, or include the profile hash in each cache key. Alternatively, on cache hit, cheaply verify that a credential for that server exists in the *current* profile's storage before trusting the cached needs-auth verdict.
## Related
- #48670 — needs-auth cache blocks SDK reconnection after successful re-auth (single profile; closed not-planned). This issue is the multi-profile variant: the cache isn't just stale, it's shared across identities.
- #80635, #78220 — other cases of the cache being keyed too coarsely (by server name only)
- #79223 — `CLAUDE_SECURESTORAGE_CONFIG_DIR` documentation request
贡献指南
这个仓库没有索引到贡献指南
调研方向
Start by tracing the code that reads and writes ~/.claude/mcp-needs-auth-cache.json, then compare it with the profile hash used for Keychain service names under CLAUDE_SECURESTORAGE_CONFIG_DIR. Reproduce the two-profile sequence, including the sdk-ts entrypoint. Done means one profile's needs-auth result cannot block the other, with regression coverage for the isolated cache behavior.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- authentication, cli
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 活跃
- 描述清晰度
- 基本清楚
- 新手友好度
- 52/100