Skip to content

fix: refresh CLI credentials before each invocation#926

Merged
EhabY merged 4 commits intomainfrom
forward-auth-env-to-cli
Apr 30, 2026
Merged

fix: refresh CLI credentials before each invocation#926
EhabY merged 4 commits intomainfrom
forward-auth-env-to-cli

Conversation

@EhabY
Copy link
Copy Markdown
Collaborator

@EhabY EhabY commented Apr 30, 2026

  • Refresh the credential file (or keyring on supported systems) before each CLI call by awaiting cliManager.configure inside commands.ts:resolveCliEnv. The CLI reads the fresh token via the existing --global-config / --url flags. mTLS still works since the refresh accepts an empty token.
  • Stop wrapping AbortError inside cliError. Previously, wrapping replaced the AbortError name with stale CLI stderr, so cancellations from speedtest and support bundle looked like real failures to withCancellableProgress.
  • Tighten isAbortError to narrow to Error so callers can return the error directly.
  • Drop the unused keyringOnly option from storeToken.
  • Add writeStdoutJs / writeStderrJs test helpers that wrap fs.writeSync. Fixes a flaky version-fallback test caused by lost async pipe writes on exit (see https://nodejs.org/api/process.html#a-note-on-process-io).

@EhabY EhabY self-assigned this Apr 30, 2026
EhabY added 2 commits April 30, 2026 18:52
Pass CODER_URL and CODER_SESSION_TOKEN to every CLI child (speedtest,
support bundle, ping, app status terminal). An empty token is valid and
covers mTLS. This is in addition to the existing --url / --global-config
flags so subprocesses the CLI itself spawns also see the auth.

Also stop wrapping AbortError in cliError. Wrapping replaced the
AbortError name with stale CLI stderr, making cancellations look like
real failures. Tighten isAbortError to narrow to Error so callers can
return it directly.
@EhabY EhabY force-pushed the forward-auth-env-to-cli branch from 5944f8c to c820189 Compare April 30, 2026 15:52
@EhabY
Copy link
Copy Markdown
Collaborator Author

EhabY commented Apr 30, 2026

/coder-agents-review

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three P3s, two nits. No blockers.

The env forwarding is sibling-complete: all four cliExec.ts call sites get the same buildChildEnv treatment. The mTLS empty-token edge case has its own test. The AbortError analysis is grounded in code structure (traced isExecFileException matching AbortError.code), not asserted from intuition. The isAbortError type narrowing from boolean to error is Error is a prerequisite for the cliError return, not scope drift. Commit hygiene is solid: functional change and reformat are separate commits.

"I tried four different framings of the problem and the author's framing survived all of them." (Pariston)

The main gap is that the AbortError fix (the PR's second bullet) ships without a test proving it works. The createTerminal env semantics mismatch is a real bug in one of the four call sites. And runCliCommand in workspace.ts is a sibling CLI spawn site that the PR's "every" claim misses.

PS. The reformat commit subject (reformat cliExec) doesn't follow the project's type(scope): message format; should be refactor: reformat cliExec or similar.


src/core/cliExec.ts:238

Nit [DEREM-2] banner is now required (string[], line 192), so if (options.banner) always evaluates to true (even an empty array is truthy). The guard can be removed, keeping only the loop body. (Netero)

🤖

src/api/workspace.ts:70

P3 [DEREM-4] runCliCommand spawns coder start/coder update via spawn(cmd, { shell: true }) with no env override. Same class of CLI child process as the four fixed in cliExec.ts.

"CliContext at workspace.ts:48 is a sibling of CliEnv at cliExec.ts:14. Both wrap 'how to invoke the coder binary.' The PR adds authEnv and buildChildEnv to CliEnv, but runCliCommand uses CliContext which has no authEnv field." (Robin)

The CLI flags still carry auth for the direct binary, so nothing breaks today. The gap matters for nested subprocesses that coder start/coder update might spawn. The PR description says "every coder CLI child process"; these two are not covered. (Kite P3, Robin P3, Hisoka P4)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread src/core/cliExec.ts
Comment thread src/core/cliExec.ts Outdated
Comment thread src/error/errorUtils.ts
Comment thread src/core/cliExec.ts Outdated
createTerminal({env}) merges additively on top of the user's terminal
env, so spreading process.env was clobbering platform settings like
terminal.integrated.env.linux. Split the env builder so execFile/spawn
get the full process.env overlay and createTerminal only gets the
CODER_URL/CODER_SESSION_TOKEN delta.

Also:
- Add unit tests for isAbortError covering the DOMException path.
- Add a speedtest test asserting AbortError survives cancellation.
- Rename CliEnv.authEnv to childCredentials to disambiguate from CliEnv.auth.
- Remove the always-true banner guard in spawnCliInTerminal.
@EhabY
Copy link
Copy Markdown
Collaborator Author

EhabY commented Apr 30, 2026

DEREM-2: Done in 357814b.

DEREM-4: Skipping. The direct binary already has auth via flags, and coder start/coder update are short-lived calls we have no evidence spawn auth-needing children. Capturing {url, token} here would also break the refresh-resilience cliAuth has by design (it never carries a token). Scoped the PR description to the four cliExec.ts call sites.

@EhabY EhabY changed the title fix: forward auth env to coder CLI child processes fix: refresh CLI credentials per call instead of forwarding via env Apr 30, 2026
@EhabY EhabY changed the title fix: refresh CLI credentials per call instead of forwarding via env fix: refresh CLI credentials before each invocation Apr 30, 2026
@EhabY EhabY requested a review from code-asher April 30, 2026 20:32
@EhabY EhabY force-pushed the forward-auth-env-to-cli branch from 185abc4 to 0ca0170 Compare April 30, 2026 20:42
Comment thread src/login/loginCoordinator.ts Outdated
Forwarding CODER_SESSION_TOKEN via the child env exposed it to any
sibling process via /proc/<pid>/environ on Linux and similar interfaces
elsewhere. Drop all env injection from cliExec and instead refresh the
file or keyring once via cliManager.configure inside resolveCliEnv,
mirroring the connection-time write in remote.ts. The CLI reads the
fresh token from the file (or keyring on supported systems) via the
existing --global-config / --url flags. mTLS still works since the
refresh accepts an empty token.

Also drop the keyringOnly option from storeToken (no longer needed now
that we always refresh) and update the matching tests.

Add writeStdoutJs / writeStderrJs helpers in test/utils/platform.ts that
generate fs.writeSync snippets, and use them in the cliExec and platform
tests. process.stdout/stderr.write is async on POSIX pipes and can be
lost on exit (nodejs/node#4112), which was making the version fallback
test flaky.
@EhabY EhabY force-pushed the forward-auth-env-to-cli branch from 0ca0170 to c104424 Compare April 30, 2026 20:49
@EhabY EhabY merged commit 207d11e into main Apr 30, 2026
10 checks passed
@EhabY EhabY deleted the forward-auth-env-to-cli branch April 30, 2026 20:53
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.

2 participants