Summary
In gh-aw v0.84.3, generated safe_outputs jobs upload raw process-safe-outputs.stdout.log and .stderr.log. For workflows that use create-pull-request or push-to-pull-request-branch with GH_AW_CI_TRIGGER_TOKEN, those artifacts contain a reversible base64-encoded authorization header.
Verified execution path
- The compiler injects
GH_AW_CI_TRIGGER_TOKEN for patch-capable safe outputs: compiler_safe_outputs_steps.go L223-L243.
git_auth_helpers.cjs constructs Authorization: basic <base64(x-access-token:TOKEN)> and passes it to unsilenced exec.exec("git", ...): git_auth_helpers.cjs L108-L121.
@actions/exec defaults to silent: false and writes the complete command line, including arguments, to stdout: toolrunner.ts L353-L366 and L420-L425.
process_safe_outputs.cjs tees stdout/stderr to files before forwarding the bytes to the GitHub runner: process_safe_outputs.cjs L35-L70.
- The compiler uploads both raw files unconditionally:
compiler_safe_outputs_job.go L944-L957.
The derived base64 value is not registered for masking. More importantly, runner masking cannot protect the local file because the wrapper writes it before the runner receives stdout. The authorization value is trivially reversible with base64 -d.
Scope
The exposure requires a configured nonempty CI-trigger token and a normal same-repository create/push safe-output path. Staged, cross-repository, or skipped paths do not reach it. Artifact access and token lifetime determine the practical blast radius.
Expected behavior
No credential-bearing command line should be captured in uploaded artifacts.
Suggested remediation
One of the following is needed:
- Add
{ silent: true } to the credential-bearing git config calls in git_auth_helpers.cjs.
- Redact credential-bearing chunks inside
process_safe_outputs.cjs before writing its artifact files.
- Stop uploading the raw process-safe-output stdout/stderr logs until credential handling is safe.
core.setSecret() alone is insufficient because these files are written before runner-side masking.
Affected generated workflow consumers should regenerate their locks after a fixed stable release is available.
Summary
In gh-aw v0.84.3, generated
safe_outputsjobs upload rawprocess-safe-outputs.stdout.logand.stderr.log. For workflows that usecreate-pull-requestorpush-to-pull-request-branchwithGH_AW_CI_TRIGGER_TOKEN, those artifacts contain a reversible base64-encoded authorization header.Verified execution path
GH_AW_CI_TRIGGER_TOKENfor patch-capable safe outputs:compiler_safe_outputs_steps.goL223-L243.git_auth_helpers.cjsconstructsAuthorization: basic <base64(x-access-token:TOKEN)>and passes it to unsilencedexec.exec("git", ...):git_auth_helpers.cjsL108-L121.@actions/execdefaults tosilent: falseand writes the complete command line, including arguments, to stdout:toolrunner.tsL353-L366 and L420-L425.process_safe_outputs.cjstees stdout/stderr to files before forwarding the bytes to the GitHub runner:process_safe_outputs.cjsL35-L70.compiler_safe_outputs_job.goL944-L957.The derived base64 value is not registered for masking. More importantly, runner masking cannot protect the local file because the wrapper writes it before the runner receives stdout. The authorization value is trivially reversible with
base64 -d.Scope
The exposure requires a configured nonempty CI-trigger token and a normal same-repository create/push safe-output path. Staged, cross-repository, or skipped paths do not reach it. Artifact access and token lifetime determine the practical blast radius.
Expected behavior
No credential-bearing command line should be captured in uploaded artifacts.
Suggested remediation
One of the following is needed:
{ silent: true }to the credential-bearinggit configcalls ingit_auth_helpers.cjs.process_safe_outputs.cjsbefore writing its artifact files.core.setSecret()alone is insufficient because these files are written before runner-side masking.Affected generated workflow consumers should regenerate their locks after a fixed stable release is available.