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

未关闭
#87,702 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
stale
主要语言
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

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。