-
Notifications
You must be signed in to change notification settings - Fork 48
fix(agent): pin the agent's secure-storage dir so no keychain login leaks #1191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
posthog
wants to merge
1
commit into
main
Choose a base branch
from
posthog-self-driving/fixagent-keep-the-macos-keychain-claude-2015d6
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+72
−33
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fresh config directories break resumed tutorial sessions
Why we think it's a valid issue
@anthropic-ai/claude-agent-sdk@0.3.169(the version pinned atpackage.json:35) and read its typings and bundle, rather than reasoning from the snippet.sdk.d.tsdocumentspersistSessionas "When false, disables session persistence to disk. Sessions will not be saved to ~/.claude/projects/ and cannot be resumed later. @default true", and thesessionStoredoc says "the subprocess still writes to CLAUDE_CONFIG_DIR". Insdk.mjsthe config root resolves as(process.env.CLAUDE_CONFIG_DIR ?? join(homedir(), ".claude")).normalize("NFC"), and lookup failures raiseSession ${id} not found in project directory/Session ${id} not found (no projects directory).isolatedAgentCredentialEnv()callsmkdtempSyncon every invocation (stored-login.ts:57-60,stored-login.ts:90). The PR's own test asserts this at__tests__/stored-login.test.ts:129-131— "returns a distinct directory on each call". So prompt 2 spawns against a different, empty root than prompt 1 wrote its transcript into.McpSuggestedPromptsScreen.tsx:412passesresumeSessionId: currentSessionIdRef.current, whichmcp-prompt-streaming.ts:309turns intoresume.MAX_PROMPT_RUNS = 5(McpSuggestedPromptsScreen.tsx:121) with a dedicatedPhase.FollowUp, so every tutorial user who picks a second prompt hits it. The code states the intent it no longer delivers:mcp-prompt-streaming.ts:202-205and:298-300describe resumed follow-ups keeping prior turns as context.claude-resume-*) only runs on thesessionStorepath, which this call site does not use.git diff FETCH_HEAD HEADshows main already hadCLAUDE_CONFIG_DIR: createIsolatedAgentConfigDir()here, added by919e7d1(fix(agent): isolate CLAUDE_CONFIG_DIR so a stored Claude login cannot 401 the run #1180, v2.71.0). This PR replaces that line with the two-var spread atmcp-prompt-streaming.ts:372.errorchunk atmcp-prompt-streaming.ts:400-403andMcpSuggestedPromptsScreen.tsx:430-433— or silently starts fresh and drops the conversation the follow-up suggestions refer to. The trigger and the consequence are both concrete and deterministic, so this clears the bar even though the PR only re-expresses the line. It is the right moment to fix, because the change edits that exact line and adds a test that locks in the per-call fresh directory.Issue description
The SDK stores resumable sessions under
CLAUDE_CONFIG_DIRbecausepersistSessiondefaults totrue. This call creates a new directory for every prompt, including prompts withresumeSessionId. The resumed process cannot find the first prompt's transcript. Follow-up prompts can fail or lose their prior context.Suggested fix
Create one isolated credential directory for each tutorial conversation. Reuse both environment values for resumed prompts. Create a new directory only when the user starts a new conversation. Add a test that checks path reuse for follow-ups and path replacement after reset.
Prompt to fix with AI (copy-paste)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed this is a real bug against the current head, and I'm escalating it for a human decision rather than fixing it unattended.
What happens: the MCP tutorial resumes sessions for follow-up prompts (it carries the previous run's session id forward as
resumeSessionId, up to 5 prompts per session). But each run is handed a brand-new, empty per-run config directory — the isolation helper creates a fresh temp dir on every call, and a test in this PR deliberately locks that in ("a distinct directory on each call"). Because the SDK keeps resumable transcripts under that config directory, a resumed follow-up looks for the first prompt's transcript in a directory that never held it. The result is either a "session not found" error surfaced to the user or a silent fresh start that drops the conversation the follow-up suggestions refer to. The root cause actually shipped in v2.71.0 with the original config-dir isolation, but this PR edits the exact line, so it's a reasonable place to address it.Why it needs a human: fixing it means reconciling two goals that currently conflict — per-run credential isolation wants a fresh, empty directory, while session resume wants a stable directory for the whole conversation. The natural fix is one isolated directory per tutorial conversation (created when the user picks a new prompt, reused for follow-ups, reset on a new conversation), which requires threading that directory through the screen → services → streaming runner, changing the isolation helper's contract, and updating its locking test. Two things put it beyond an unattended fix: (1) its correctness — that resume actually recovers the transcript once the directory is stable — can only be proven by running the real Agent SDK against a resumed session, which this pass can't do; and (2) the helper is credential-leak-prevention code, so changing how its directory is created and reused shouldn't be done without a human confirming it doesn't reopen a leak path.
Decision needed: adopt the per-conversation stable isolated directory (and confirm via a real resumed-session run that it fixes resume without reintroducing a stored-login leak), or decide the tutorial shouldn't resume at all (drop
resumehere and accept each prompt as standalone).