Skip to content

fix(externagent): run claude and codex against their own homes, never copy their tokens - #643

Open
ion-alpha-dev wants to merge 2 commits into
mainfrom
fix/claude-own-config-home
Open

ion-alpha-dev wants to merge 2 commits into
mainfrom
fix/claude-own-config-home

Conversation

@ion-alpha-dev

@ion-alpha-dev ion-alpha-dev commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What

Flynn now keeps a separate home for each external CLI under its data directory (claude/ and codex/) and runs the CLI against it, instead of copying the user's own credential (~/.claude/.credentials.json, or auth.json from ~/.codex or CODEX_HOME) into a per-run home for every episode. Flynn never reads, copies or stores the token inside.

Why

The user's personal sign-in belongs to their own use of the CLI, and Flynn had no reason to handle it. A copied token also lives outside the CLI's control: the CLI cannot refresh the original, and the copy sits in a directory the user never asked for. With a home of its own, each CLI signs in through its own login flow, keeps its token where it put it, and refreshes it in place.

How to verify

  • go test ./cmd/flynn ./externagent
  • TestDedicatedAuthDirIsWrittenInPlace: a home marked writable (SandboxConfig.AuthDirWritable) is used in place with nothing copied, and an unmarked home stays read-only.
  • TestClaudeHomeIsFlynnsOwnAndNeverTheUsers, TestCodexHomeIsFlynnsOwnAndNeverTheUsers: each backend uses Flynn's home whatever the user's environment variable says, and the home exists before detection. The codex test also checks that a config.toml is removed and auth.json is kept, and it fails if the removal is taken out.
  • TestLoginSignsInFlynnsHome: the sign-in message for both backends names the right variable and login command, quotes the path for sh and PowerShell, and never asks for an API key.
  • By hand: run flynn --model codex (or claude) with no sign-in; it prints a CODEX_HOME=... codex login (or CLAUDE_CONFIG_DIR=... claude auth login --claudeai) command. After running it, the backend reports itself ready and ~/.codex / ~/.claude are unchanged.

Notes for reviewers

  • Anyone already using --model claude or --model codex signs in once more. Their own ~/.claude and ~/.codex sign-ins are untouched.
  • The user's own settings, hooks, MCP servers and config.toml are never on the child's path. A config.toml found in Flynn's codex home is removed before a spawner is built, because the child may write that home and nothing Flynn does puts one there.

The claude backend used to read the user's Claude Code credential file
and config out of ~/.claude and copy them into a per-run directory for
each episode. Flynn handled the OAuth token itself, and a token the CLI
refreshed mid-episode was refreshed only in the copy.

The backend now keeps a Claude Code home of its own under the data
directory. The user signs the CLI in to it once with the CLI's own
login, and every probe and episode points the CLI at it through
CLAUDE_CONFIG_DIR. Flynn never reads, copies or deletes the token; the
CLI writes it at sign-in and refreshes it in place. The user's own home,
settings, hooks and MCP servers are no longer read at all.

SandboxConfig gains AuthDirWritable so an episode may write such a
dedicated home. A user's own CLI home stays read-only to the child, as
before. When claude is installed but not signed in, the onboarding
message now prints the sign-in command for Flynn's home, quoted for
PowerShell on Windows and for sh elsewhere.

Signed-off-by: Ion Alpha <[email protected]>
The codex backend copied auth.json out of the user's own codex home
into a per-run home for every episode. It now gets the same treatment
as claude: Flynn keeps a codex home of its own under its data
directory, the user signs the CLI in to it once with `codex login`
(Flynn prints the exact command), and probes and episodes point the
CLI at it through CODEX_HOME with write access, so the CLI refreshes
its token in place and Flynn never reads it.

The user's config.toml is never on the child's path. A config.toml
found in Flynn's own codex home is removed before a spawner is built,
so a harness cannot leave one behind to steer a later run.

The not-signed-in message for both backends now comes from one
helper, and the login command is built by one function per shell.

Existing codex users sign in once more; their own ~/.codex is
untouched.

Signed-off-by: Ion Alpha <[email protected]>
@ion-alpha-dev ion-alpha-dev changed the title fix(externagent): run claude against its own home, never copy its token fix(externagent): run claude and codex against their own homes, never copy their tokens Oct 31, 2026
@codecov

codecov Bot commented Oct 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.23404% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/flynn/externagent.go 86.04% 6 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant