fix: refresh CLI credentials before each invocation#926
Conversation
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.
5944f8c to
c820189
Compare
|
/coder-agents-review |
There was a problem hiding this comment.
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.
"
CliContextatworkspace.ts:48is a sibling ofCliEnvatcliExec.ts:14. Both wrap 'how to invoke the coder binary.' The PR addsauthEnvandbuildChildEnvtoCliEnv, butrunCliCommandusesCliContextwhich has noauthEnvfield." (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.
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.
|
DEREM-2: Done in 357814b. DEREM-4: Skipping. The direct binary already has auth via flags, and |
185abc4 to
0ca0170
Compare
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.
0ca0170 to
c104424
Compare
cliManager.configureinsidecommands.ts:resolveCliEnv. The CLI reads the fresh token via the existing--global-config/--urlflags. mTLS still works since the refresh accepts an empty token.AbortErrorinsidecliError. Previously, wrapping replaced theAbortErrorname with stale CLI stderr, so cancellations fromspeedtestandsupport bundlelooked like real failures towithCancellableProgress.isAbortErrorto narrow toErrorso callers can return the error directly.keyringOnlyoption fromstoreToken.writeStdoutJs/writeStderrJstest helpers that wrapfs.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).