fix: pin bun runtime config and improve log hygiene#1174
Conversation
e17ed2d to
3976f9c
Compare
| }, | ||
| ); | ||
| console.log("App token successfully obtained"); | ||
| core.setSecret(appToken); | ||
|
|
||
| console.log("Using GITHUB_TOKEN from OIDC"); | ||
| return appToken; |
There was a problem hiding this comment.
🔴 The OIDC token obtained via getOidcToken() is never masked with core.setSecret(), while this PR adds core.setSecret(appToken) for the exchanged app token. Although the OIDC token is not currently logged in any code path, the PR establishes an inconsistent masking pattern — add core.setSecret(oidcToken) immediately after line 138 to apply the same hygiene to the upstream bearer credential.
Extended reasoning...
What the bug is: The setupGitHubToken() function obtains an OIDC JWT token from GitHub Actions at line 138 (const oidcToken = await retryWithBackoff(() => getOidcToken())) and then uses it to exchange for an app token. This PR adds core.setSecret(appToken) at line 151 to mask the exchanged app token in CI logs. However, the oidcToken itself — a GitHub Actions JWT bearer credential with audience claude-code-github-action — is never passed to core.setSecret(), meaning it is not registered as a secret and would appear in plaintext if it ever surfaced in logs.
The specific code path: The OIDC token flows from getOidcToken() into retryWithBackoff(), then into exchangeForAppToken() where it is placed in the Authorization: Bearer ${oidcToken} header. The PR masks the downstream credential (appToken) but not the upstream credential (oidcToken).
Why existing code does not prevent it: The current code does not log the OIDC token directly — retryWithBackoff logs only lastError.message (not full error objects or arguments), and error paths in exchangeForAppToken throw Error objects with plain message strings derived from the server response, not from the token value. So the token is not actively leaking today.
What the impact would be: While not an active leak in current code, the OIDC token is still a valid bearer credential (short-lived but non-trivially scoped to the action's audience). More importantly, the PR explicitly establishes the pattern of calling core.setSecret() for sensitive tokens — applying it to the downstream token but not the upstream one is an inconsistency that could cause confusion. If any future logging, debug output, or error-handling change inadvertently surfaces oidcToken, it would appear in plaintext in publicly-visible GitHub Actions logs. GitHub's own Actions toolkit documentation recommends masking tokens returned by core.getIDToken() immediately after retrieval.
How to fix it: Add core.setSecret(oidcToken) immediately after line 138, right after the console.log('OIDC token successfully obtained') statement. This completes the security hygiene pass the PR is already performing.
Step-by-step proof of the inconsistency: (1) setupGitHubToken() calls getOidcToken() and gets back a JWT string. (2) This JWT is stored in oidcToken at line 138 — no core.setSecret() call is made. (3) oidcToken is passed to exchangeForAppToken() where it becomes the Authorization header value. (4) exchangeForAppToken() returns appToken. (5) The PR adds core.setSecret(appToken) at line 151. (6) Result: appToken is masked in GitHub Actions logs; oidcToken is not. If any log statement were added to print oidcToken (e.g., a debug log in exchangeForAppToken), the full JWT would appear unredacted.
| bun --no-env-file \ | ||
| --config="${GITHUB_ACTION_PATH}/bunfig.toml" \ | ||
| --tsconfig-override="${GITHUB_ACTION_PATH}/tsconfig.json" \ |
There was a problem hiding this comment.
🟣 The positional entrypoint path argument is unquoted in all three bun run steps: run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts — if GITHUB_ACTION_PATH contains spaces (possible on self-hosted runners), bash word-splitting will break the command. This is a pre-existing issue that this PR makes more visible by adding properly double-quoted --config and --tsconfig-override flags alongside the unquoted path; fix by wrapping the path: run "${GITHUB_ACTION_PATH}/src/entrypoints/run.ts".
Extended reasoning...
The unquoted shell expansion run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts is present in all three bun entrypoint steps (lines ~232, ~332, ~346 of action.yml). When bash processes this command, it performs word-splitting on unquoted variable expansions. If GITHUB_ACTION_PATH contains a space — for example /my runner/_actions/org/repo/v1 on a self-hosted runner — bash will split it into separate tokens, and bun will receive run, /my, runner/... as distinct arguments rather than a single file path, causing a file-not-found error.
The code path that triggers the bug: any self-hosted GitHub Actions runner whose configured path contains whitespace. The environment variable GITHUB_ACTION_PATH is set by the Actions runner to the directory of the checked-out action. While GitHub-hosted runners use /home/runner/work/_actions/... (no spaces), enterprise self-hosted runners can be configured with arbitrary paths.
The existing code fails to prevent this because the --config and --tsconfig-override flags added by this PR are correctly quoted (--config="${GITHUB_ACTION_PATH}/bunfig.toml"), demonstrating that the author was aware of proper quoting, but the final positional argument was overlooked. The old single-line invocation had the same issue and was never fixed.
The practical impact is low: GitHub-hosted runners never have spaces in GITHUB_ACTION_PATH, and most self-hosted runners follow similar conventions. However, the inconsistency is now more prominent — three properly-quoted flags sit right above an unquoted path argument, which could mislead reviewers into thinking the path is safe.
This is a pre-existing issue not introduced by this PR. The original bun run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts had the same unquoted expansion. The PR touched these lines and could have fixed it incidentally when reformatting to multi-line, but did not introduce the problem.
Step-by-step proof: (1) A self-hosted runner is configured with a path containing a space, e.g. /my runners/actions. (2) The runner sets GITHUB_ACTION_PATH=/my runners/actions/org/repo@v1. (3) bash executes bun --no-env-file --config="..." --tsconfig-override="..." run ${GITHUB_ACTION_PATH}/src/entrypoints/run.ts. (4) After word-splitting, bun receives: arg0=run, arg1=/my, arg2=runners/actions/org/repo@v1/src/entrypoints/run.ts. (5) Bun tries to find a file named /my — it does not exist — and exits with an error. Fix: change to run "${GITHUB_ACTION_PATH}/src/entrypoints/run.ts" in all three steps.
v1.0.89 (6e2bd52) breaks the action with a bun "directory mismatch" internal error when resolving tsconfig.json, caused by the bun runtime config pinning change in anthropics/claude-code-action#1174. Pins back to the last known-good release until upstream ships a fix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| ".ripgreprc", | ||
| "CLAUDE.md", | ||
| "CLAUDE.local.md", | ||
| ".husky", |
There was a problem hiding this comment.
In our repo, we do commit the .husky files, but not the hook setup in themself.
with this setup, we need to rerun npx husky to reinstall the hooks, otherwise, our pre commit hook do not run.
this broke previous behavior
Removes .husky from the sensitive paths list that gets restored from the base branch during PR checkout. This fixes a regression from #1174 where repos that commit .husky files would have their git hook setup broken because the directory was being restored/reset. Fixes #1203 Co-authored-by: Ashwin Bhat <ashwin-ant@users.noreply.github.com>
Bumps the github-actions group with 2 updates: [anthropics/claude-code-action](https://github.com/anthropics/claude-code-action) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `anthropics/claude-code-action` from 1.0.88 to 1.0.93 Release notes *Sourced from [anthropics/claude-code-action's releases](https://github.com/anthropics/claude-code-action/releases).* > v1.0.93 > ------- > > **Full Changelog**: <anthropics/claude-code-action@v1...v1.0.93> > > v1.0.92 > ------- > > **Full Changelog**: <anthropics/claude-code-action@v1...v1.0.92> > > v1.0.91 > ------- > > What's Changed > -------------- > > * Use pinned bun binary for post-steps when allowed\_non\_write\_users is set by [`@OctavianGuzu`](https://github.com/OctavianGuzu) in [anthropics/claude-code-action#1190](https://redirect.github.com/anthropics/claude-code-action/pull/1190) > > **Full Changelog**: <anthropics/claude-code-action@v1...v1.0.91> > > v1.0.90 > ------- > > What's Changed > -------------- > > * fix: forward MCP\_TIMEOUT, MCP\_TOOL\_TIMEOUT, MAX\_MCP\_OUTPUT\_TOKENS to action step by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1162](https://redirect.github.com/anthropics/claude-code-action/pull/1162) > * security: reject PATH\_TO\_CLAUDE\_CODE\_EXECUTABLE with control characters by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1185](https://redirect.github.com/anthropics/claude-code-action/pull/1185) > > **Full Changelog**: <anthropics/claude-code-action@v1...v1.0.90> > > v1.0.89 > ------- > > What's Changed > -------------- > > * fix: skip token revocation when no token was acquired by [`@Dave-London`](https://github.com/Dave-London) in [anthropics/claude-code-action#918](https://redirect.github.com/anthropics/claude-code-action/pull/918) > * Use env vars for workflow\_run context values in example workflows by [`@ddworken`](https://github.com/ddworken) in [anthropics/claude-code-action#1125](https://redirect.github.com/anthropics/claude-code-action/pull/1125) > * docs: document include/exclude\_comments\_by\_actor inputs by [`@yuribodo`](https://github.com/yuribodo) in [anthropics/claude-code-action#1130](https://redirect.github.com/anthropics/claude-code-action/pull/1130) > * fix: use correct fallback type for reviewData in fetcher by [`@MaxwellCalkin`](https://github.com/MaxwellCalkin) in [anthropics/claude-code-action#1034](https://redirect.github.com/anthropics/claude-code-action/pull/1034) > * Strip OIDC token request env vars from Claude session by [`@chyipin`](https://github.com/chyipin) in [anthropics/claude-code-action#1011](https://redirect.github.com/anthropics/claude-code-action/pull/1011) > * fix: skip retries for non-retryable errors in retryWithBackoff by [`@ei-grad`](https://github.com/ei-grad) in [anthropics/claude-code-action#1082](https://redirect.github.com/anthropics/claude-code-action/pull/1082) > * fix: restore ripgrep execute bits after bun install --production by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1163](https://redirect.github.com/anthropics/claude-code-action/pull/1163) > * fix: allow # in branch names for PR checkout and base restore by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1167](https://redirect.github.com/anthropics/claude-code-action/pull/1167) > * fix: prevent hang in restoreConfigFromBase on repos with .gitmodules by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1166](https://redirect.github.com/anthropics/claude-code-action/pull/1166) > * fix: strip shell comment lines before parsing claude\_args by [`@VoidChecksum`](https://github.com/VoidChecksum) in [anthropics/claude-code-action#1055](https://redirect.github.com/anthropics/claude-code-action/pull/1055) > * fix: snapshot PR's .claude/ to .claude-pr/ before security restore by [`@qozle`](https://github.com/qozle) in [anthropics/claude-code-action#1172](https://redirect.github.com/anthropics/claude-code-action/pull/1172) > * chore: fix prettier formatting by [`@ashwin-ant`](https://github.com/ashwin-ant) in [anthropics/claude-code-action#1171](https://redirect.github.com/anthropics/claude-code-action/pull/1171) > * chore: fix prettier formatting in parse-sdk-options.test.ts by [`@ashwin-ant`](https://github.com/ashwin-ant) in [anthropics/claude-code-action#1176](https://redirect.github.com/anthropics/claude-code-action/pull/1176) > * fix: pin bun runtime config and improve log hygiene by [`@ashwin-ant`](https://github.com/ashwin-ant) in [anthropics/claude-code-action#1174](https://redirect.github.com/anthropics/claude-code-action/pull/1174) > > New Contributors > ---------------- > > * [`@yuribodo`](https://github.com/yuribodo) made their first contribution in [anthropics/claude-code-action#1130](https://redirect.github.com/anthropics/claude-code-action/pull/1130) > * [`@MaxwellCalkin`](https://github.com/MaxwellCalkin) made their first contribution in [anthropics/claude-code-action#1034](https://redirect.github.com/anthropics/claude-code-action/pull/1034) > * [`@chyipin`](https://github.com/chyipin) made their first contribution in [anthropics/claude-code-action#1011](https://redirect.github.com/anthropics/claude-code-action/pull/1011) > * [`@ei-grad`](https://github.com/ei-grad) made their first contribution in [anthropics/claude-code-action#1082](https://redirect.github.com/anthropics/claude-code-action/pull/1082) > * [`@qozle`](https://github.com/qozle) made their first contribution in [anthropics/claude-code-action#1163](https://redirect.github.com/anthropics/claude-code-action/pull/1163) > * [`@VoidChecksum`](https://github.com/VoidChecksum) made their first contribution in [anthropics/claude-code-action#1055](https://redirect.github.com/anthropics/claude-code-action/pull/1055) > > **Full Changelog**: <anthropics/claude-code-action@v1...v1.0.89> Commits * [`b47fd72`](anthropics/claude-code-action@b47fd72) chore: bump Claude Code to 2.1.101 and Agent SDK to 0.2.101 * [`c26cb64`](anthropics/claude-code-action@c26cb64) chore: bump Claude Code to 2.1.100 and Agent SDK to 0.2.98 * [`657fb7c`](anthropics/claude-code-action@657fb7c) chore: bump Claude Code to 2.1.98 and Agent SDK to 0.2.98 * [`2ff1acb`](anthropics/claude-code-action@2ff1acb) chore: bump Claude Code to 2.1.97 and Agent SDK to 0.2.97 * [`b2fdd80`](anthropics/claude-code-action@b2fdd80) Use pinned bun binary for post-steps when allowed\_non\_write\_users is set ([#1190](https://redirect.github.com/anthropics/claude-code-action/issues/1190)) * [`26ddc35`](anthropics/claude-code-action@26ddc35) chore: bump Claude Code to 2.1.96 and Agent SDK to 0.2.96 * [`3983706`](anthropics/claude-code-action@3983706) chore: bump Claude Code to 2.1.94 and Agent SDK to 0.2.94 * [`6cad158`](anthropics/claude-code-action@6cad158) security: reject PATH\_TO\_CLAUDE\_CODE\_EXECUTABLE with control characters ([#1185](https://redirect.github.com/anthropics/claude-code-action/issues/1185)) * [`0f1fe5e`](anthropics/claude-code-action@0f1fe5e) fix: forward MCP\_TIMEOUT, MCP\_TOOL\_TIMEOUT, MAX\_MCP\_OUTPUT\_TOKENS to action s... * [`6e2bd52`](anthropics/claude-code-action@6e2bd52) fix: pin bun runtime config and improve log hygiene ([#1174](https://redirect.github.com/anthropics/claude-code-action/issues/1174)) * Additional commits viewable in [compare view](anthropics/claude-code-action@1eddb33...b47fd72) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 Release notes *Sourced from [actions/upload-artifact's releases](https://github.com/actions/upload-artifact/releases).* > v7.0.1 > ------ > > What's Changed > -------------- > > * Update the readme with direct upload details by [`@danwkennedy`](https://github.com/danwkennedy) in [actions/upload-artifact#795](https://redirect.github.com/actions/upload-artifact/pull/795) > * Readme: bump all the example versions to v7 by [`@danwkennedy`](https://github.com/danwkennedy) in [actions/upload-artifact#796](https://redirect.github.com/actions/upload-artifact/pull/796) > * Include changes in typespec/ts-http-runtime 0.3.5 by [`@yacaovsnc`](https://github.com/yacaovsnc) in [actions/upload-artifact#797](https://redirect.github.com/actions/upload-artifact/pull/797) > > **Full Changelog**: <actions/upload-artifact@v7...v7.0.1> Commits * [`043fb46`](actions/upload-artifact@043fb46) Merge pull request [#797](https://redirect.github.com/actions/upload-artifact/issues/797) from actions/yacaovsnc/update-dependency * [`634250c`](actions/upload-artifact@634250c) Include changes in typespec/ts-http-runtime 0.3.5 * [`e454baa`](actions/upload-artifact@e454baa) Readme: bump all the example versions to v7 ([#796](https://redirect.github.com/actions/upload-artifact/issues/796)) * [`74fad66`](actions/upload-artifact@74fad66) Update the readme with direct upload details ([#795](https://redirect.github.com/actions/upload-artifact/issues/795)) * See full diff in [compare view](actions/upload-artifact@bbbca2d...043fb46) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
--config,--tsconfig-override, and--no-env-fileon the threebun runentrypoints so bun resolves runtime config from the action directory instead of the workspacecore.setSecretextraArgsfrom the SDK options debug log alongsideenvCLAUDE.md,CLAUDE.local.md, and.huskyto the config-restore listbase-action/test/parse-sdk-options.test.ts(drift from fix: strip shell comment lines before parsing claude_args #1055)Tests, typecheck, and format all pass.