Skip to content

Release scripts keep the GitHub token off the command line - #529

Merged
andersalm merged 3 commits into
developfrom
fix/release-token-argv
Nov 4, 2026
Merged

andersalm merged 3 commits into
developfrom
fix/release-token-argv

Conversation

@andersalm

Copy link
Copy Markdown
Contributor

Fixes #528. The release scripts no longer put the GitHub token, or the local Runtime shell token, on any process's command line, where other users on the same machine can read it.

  • Seed download get() in scripts/release-publish.sh: curl reads the Authorization header from stdin (printf ... | curl -K -; printf is a shell builtin).
  • Signing command: env -i still gives the signer only GH_TOKEN; the token now arrives on file descriptor 3 from gh auth token and is read by /bin/sh before exec, so it is never an argument. The printed line needs bash or zsh (process substitution); scripts/README.md says so.
  • scripts/publish-release.sh runtime_tunnel_url: the shell token goes to curl on stdin the same way.

Test: the printed seed download and signing commands keep the GitHub token out of every argv in scripts/release-publish.test.mjs. It runs the printed commands with recording fake curl, env, gh and python and a fake token. It fails on develop (the token appears in curl's and env's argv) and passes with the fix; all 111 release-publish tests pass.

Written by Cursor (Claude Opus); cross-family review by Codex (GPT-6 Astra): PASS on d659809, no blocking findings. The pushed head 97f2cd9 adds only the merge of current develop (with #526). Note from review, not changed here: printed paths containing an apostrophe would break argument boundaries, on develop as well.

Other places that put a token in argv are test and proof scripts only, listed on #528; unchanged.

andersalm and others added 3 commits November 3, 2026 22:16
Any account on the seed or the signing Mac reads another process's command
line, so the release token must never be an argument.

The seed preamble get() now pipes the header into curl with -K -. printf is a
shell builtin, so the token passes from the shell to curl through a pipe and
enters no argv. curl keeps the same -fsSL behaviour and the same URL argument.

The signing launch keeps env -i, which gives the signer GH_TOKEN and nothing
else of the operator's environment. The token now arrives on file descriptor 3,
which env -i keeps while it clears the environment: `gh auth token` feeds that
descriptor through a process substitution, and a clean /bin/sh reads the line,
exports GH_TOKEN and execs the pinned Python. The script text holds no token,
env's arguments hold no token, and stdin stays the terminal for the DID prompt.

Other launch shapes keep the token in an argv (env -i GH_TOKEN=...) or lose the
clean environment (an assignment prefix passes the caller's whole environment),
so the descriptor is the simplest shape that meets both requirements.

The new test runs the printed get() and the printed signing command with a fake
token and recording curl, gh, env and python executables. It asserts that no
recorded command line holds the token, that curl still receives the
Authorization header, and that the signer's environment holds GH_TOKEN and
nothing else of the caller's.

Co-authored-by: Cursor <cursoragent@cursor.com>
runtime_tunnel_url passed the local Runtime shell token to curl as an argument,
where any account on the publication host reads it. It now pipes the header
into curl with -K -, like the seed preamble. The request keeps its method,
content type, body and URL.

Co-authored-by: Cursor <cursoragent@cursor.com>
@andersalm
andersalm merged commit 42c869e into develop Nov 4, 2026
26 of 32 checks passed
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