NO-JIRA: fix Claude WIF test workflow HOME for ARC runners#8600
Conversation
|
Pipeline controller notification For optional jobs, comment This repository is configured in: LGTM mode |
|
@bryan-cox: This pull request explicitly references no jira issue. DetailsIn response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository. |
📝 WalkthroughWalkthroughThe .github/workflows/claude-wif-test.yaml workflow sets the test-wif job's HOME environment variable to /tmp and reorders job steps so the "Authenticate to GCP via WIF" step runs before the "Install Claude Code" step; the install step still appends $HOME/.local/bin to GITHUB_PATH. Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 11✅ Passed checks (11 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Please specify an area label DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: bryan-cox The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/claude-wif-test.yaml (1)
43-43:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftSupply chain security risk: External script executed without integrity verification.
Downloading and executing an installer script from
https://claude.ai/install.shwithout integrity checks creates a supply chain vulnerability. If the script or domain is compromised, malicious code could execute in the workflow.Recommended mitigations:
- Pin to a specific version/commit of the installer with checksum verification
- Vendor the installer script in the repository
- Use an official Claude Code GitHub Action if available
As per coding guidelines: "SAST/SCA steps in pipeline" and general CI/CD security requires supply chain integrity verification.
🔒 Example fix with checksum verification
- name: Install Claude Code run: | - curl -fsSL https://claude.ai/install.sh | bash + INSTALLER_URL="https://claude.ai/install.sh" + EXPECTED_SHA256="<checksum_here>" + curl -fsSL "$INSTALLER_URL" -o /tmp/claude-install.sh + echo "$EXPECTED_SHA256 /tmp/claude-install.sh" | sha256sum -c - + bash /tmp/claude-install.sh echo "$HOME/.local/bin" >> $GITHUB_PATHObtain the checksum by running:
curl -fsSL https://claude.ai/install.sh | sha256sum🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/claude-wif-test.yaml at line 43, Replace the unsafe one-liner that pipes the remote installer (curl -fsSL https://claude.ai/install.sh | bash) with a verified-install flow: download the installer to a temporary file, validate its integrity against a pinned checksum or specific version/commit (or vendor the script into the repo), and only execute if the checksum matches; alternatively switch to an official Claude GitHub Action if available—ensure the change references the original curl invocation so reviewers can find and remove the direct pipe-to-shell pattern.
🧹 Nitpick comments (1)
.github/workflows/claude-wif-test.yaml (1)
35-39: ⚖️ Poor tradeoffCheckout of potentially untrusted PR code in comment-triggered workflow.
While the workflow uses
issue_commentinstead ofpull_request_target, checking out PR code from forks (line 38) in a workflow triggered by comments carries security risks. Although mitigated by requiring MEMBER or OWNER association (lines 18-20), this pattern should be monitored.Considerations:
- Current mitigation: MEMBER/OWNER check reduces risk of malicious PRs
- Risk: A compromised member account could submit malicious code
- The checked-out code is not obviously executed in current steps
- However, future workflow changes could inadvertently execute PR code
As per coding guidelines: "Agentic CI actions: audit for prompt injection via issue/PR title/body flowing into LLM prompts" – while the Claude prompt is hardcoded (line 60), checking out untrusted code creates potential attack surface.
Consider: Document this security tradeoff or add explicit guards (e.g., only checkout from main repo, not forks).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/claude-wif-test.yaml around lines 35 - 39, The workflow currently checks out PR code using actions/checkout (refs: steps.pr.outputs.ref and steps.pr.outputs.repo) in an issue_comment-triggered run, which exposes a risk when handling forked PRs; update the job to avoid checking out untrusted fork code by either (A) using the main repo/commit only (use github.repository and github.sha instead of steps.pr.outputs.repo/ref) or (B) add an explicit guard step that validates the comment author association and that the PR repo is the same as github.repository and fails early if not (check github.event.comment.author_association and compare steps.pr.outputs.repo to github.repository), and document this security tradeoff in the workflow comments so future maintainers know why checkout was restricted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In @.github/workflows/claude-wif-test.yaml:
- Line 43: Replace the unsafe one-liner that pipes the remote installer (curl
-fsSL https://claude.ai/install.sh | bash) with a verified-install flow:
download the installer to a temporary file, validate its integrity against a
pinned checksum or specific version/commit (or vendor the script into the repo),
and only execute if the checksum matches; alternatively switch to an official
Claude GitHub Action if available—ensure the change references the original curl
invocation so reviewers can find and remove the direct pipe-to-shell pattern.
---
Nitpick comments:
In @.github/workflows/claude-wif-test.yaml:
- Around line 35-39: The workflow currently checks out PR code using
actions/checkout (refs: steps.pr.outputs.ref and steps.pr.outputs.repo) in an
issue_comment-triggered run, which exposes a risk when handling forked PRs;
update the job to avoid checking out untrusted fork code by either (A) using the
main repo/commit only (use github.repository and github.sha instead of
steps.pr.outputs.repo/ref) or (B) add an explicit guard step that validates the
comment author association and that the PR repo is the same as github.repository
and fails early if not (check github.event.comment.author_association and
compare steps.pr.outputs.repo to github.repository), and document this security
tradeoff in the workflow comments so future maintainers know why checkout was
restricted.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: ab333925-32c8-4a0c-b3a6-364f16a7fcf5
📒 Files selected for processing (1)
.github/workflows/claude-wif-test.yaml
132201b to
ddbcdd3
Compare
ARC runner containers use dash as default shell and don't have gh CLI installed. Use bash explicitly for the Claude installer and curl for the GitHub API call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ddbcdd3 to
14b7473
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.github/workflows/claude-wif-test.yaml (2)
54-60: Agentic CI action present: ensure prompt injection safeguards remain in place.The workflow uses Claude (an LLM) in CI and is triggered by issue comments. Currently, the prompt is hardcoded and safe. However, if future modifications pass issue/PR title, body, or comment content into Claude prompts, this could enable prompt injection attacks where malicious actors craft inputs to manipulate the LLM's behavior or exfiltrate credentials.
Recommendations:
- Keep prompts hardcoded or strictly validated
- Never interpolate untrusted user input (issue/PR/comment content) directly into LLM prompts
- If user input is required, sanitize and use strict input validation
As per coding guidelines: "Agentic CI actions: audit for prompt injection via issue/PR title/body flowing into LLM prompts."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/claude-wif-test.yaml around lines 54 - 60, The workflow currently invokes the Claude agent via the run block ("claude --version" and "claude -p \"Say hello in one sentence\" --max-turns 1"); ensure you never substitute untrusted issue/PR/comment text into that prompt or any other Claude invocation. Keep prompts fully hardcoded (as in the existing "Say hello..." string) or, if you must accept inputs, add strict validation/sanitization and an allowlist before interpolation and log/deny any disallowed content; update the run steps that call claude (the "claude -p" invocation) to use only safe hardcoded prompts or validated variables.
8-11: ⚡ Quick winConsider adding SAST/SCA and artifact signing steps.
The workflow currently lacks SAST/SCA security scanning and artifact signing mechanisms. While this is a test workflow, adding these steps would strengthen supply chain security and align with best practices.
Suggested additions:
- Add dependency scanning (e.g.,
snyk,trivy, or GitHub'sdependency-review-action)- Consider signing any artifacts or attestations with Sigstore/cosign if applicable
As per coding guidelines: "SAST/SCA steps in pipeline" and "Sign artifacts with Sigstore/cosign."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/claude-wif-test.yaml around lines 8 - 11, Add explicit SAST/SCA and artifact signing steps to this workflow by inserting a new job (e.g., dependency-scan) that runs a dependency scanner like trivy or snyk (or use GitHub's dependency-review-action) and fails on high-severity findings, and a separate sign-artifacts job that uses Sigstore/cosign to sign build outputs or attestations; reference the workflow's existing permissions block and ensure the jobs use appropriate permissions (id-token write for OIDC) and output artifacts to be signed so tools like "trivy", "snyk/actions", "dependency-review-action", and "sigstore/cosign" are invoked from the new jobs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/claude-wif-test.yaml:
- Around line 48-51: Replace the unsafe piped installer invocation "curl -fsSL
https://claude.ai/install.sh | bash" with a two-step verified install: download
the bootstrap script to a file (e.g., via curl), verify its integrity/signature
against a pinned hash or signature from a trusted source (or vendor the
bootstrap script into the repo), and only then execute it; also ensure the
bootstrap is instructed to install a pinned Claude Code release/manifest (not
latest) or fetch a pinned manifest and verify the downloaded binary checksum
before installation. Locate the workflow step that runs the installer (the run
block containing the curl | bash line) and update it to perform explicit
download, verification, and pinned-version installation instead of executing the
remote script directly.
---
Nitpick comments:
In @.github/workflows/claude-wif-test.yaml:
- Around line 54-60: The workflow currently invokes the Claude agent via the run
block ("claude --version" and "claude -p \"Say hello in one sentence\"
--max-turns 1"); ensure you never substitute untrusted issue/PR/comment text
into that prompt or any other Claude invocation. Keep prompts fully hardcoded
(as in the existing "Say hello..." string) or, if you must accept inputs, add
strict validation/sanitization and an allowlist before interpolation and
log/deny any disallowed content; update the run steps that call claude (the
"claude -p" invocation) to use only safe hardcoded prompts or validated
variables.
- Around line 8-11: Add explicit SAST/SCA and artifact signing steps to this
workflow by inserting a new job (e.g., dependency-scan) that runs a dependency
scanner like trivy or snyk (or use GitHub's dependency-review-action) and fails
on high-severity findings, and a separate sign-artifacts job that uses
Sigstore/cosign to sign build outputs or attestations; reference the workflow's
existing permissions block and ensure the jobs use appropriate permissions
(id-token write for OIDC) and output artifacts to be signed so tools like
"trivy", "snyk/actions", "dependency-review-action", and "sigstore/cosign" are
invoked from the new jobs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: ad5a50d9-8278-4edc-baa8-d1a3ee11ac01
📒 Files selected for processing (1)
.github/workflows/claude-wif-test.yaml
| - name: Install Claude Code | ||
| run: | | ||
| curl -fsSL https://claude.ai/install.sh | bash | ||
| echo "$HOME/.local/bin" >> $GITHUB_PATH |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if claude.ai provides checksums or signatures for the installer
curl -fsSL -I https://claude.ai/install.sh
curl -fsSL https://claude.ai/install.sh.sha256 || echo "No SHA256 checksum found"
curl -fsSL https://claude.ai/install.sh.sig || echo "No signature found"Repository: openshift/hypershift
Length of output: 1745
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and print the relevant portion of the workflow to understand credential context
path=".github/workflows/claude-wif-test.yaml"
if [ ! -f "$path" ]; then
echo "Missing file: $path"
exit 1
fi
echo "== file: $path (lines around 1-120) =="
nl -ba "$path" | sed -n '1,140p'
echo "== grep for auth/WIF/credentials in workflow =="
rg -n "wif|workload identity|credentials|gcp|google|service account|id-token|permissions|actions/checkout|setup-.*gcloud|workloadIdentity" "$path" || true
echo "== grep for the install step =="
rg -n "Install Claude Code|install\.sh|claude\.ai/install\.sh|GITHUB_PATH|\.local/bin" "$path" || trueRepository: openshift/hypershift
Length of output: 198
🏁 Script executed:
#!/bin/bash
set -euo pipefail
path=".github/workflows/claude-wif-test.yaml"
echo "== checking file exists: $path =="
ls -la "$path"
echo "== file header (lines 1-120) =="
cat -n "$path" | sed -n '1,140p'
echo "== grep for WIF/credentials/auth context =="
rg -n "wif|workload identity|credentials|gcp|google|service account|id-token|setup-gcloud|workloadIdentity|GCP" "$path" || true
echo "== grep for install step bits =="
rg -n "Install Claude Code|install\.sh|claude\.ai/install\.sh|downloads\.claude\.ai|curl|bash|GITHUB_PATH|\.local/bin" "$path" || true
echo "== follow redirect and check checksum/signature endpoints =="
redir="$(curl -fsSL -I https://claude.ai/install.sh 2>/dev/null | awk -F': ' '/^location: /{print $2}' | tr -d '\r')"
echo "redirect location: ${redir:-<none>}"
# If we got a redirect, try likely checksum/signature URL patterns for the actual script.
if [ -n "${redir:-}" ]; then
base="${redir%/*}"
file="${redir##*/}"
# Try same patterns used in the review comment, relative to the redirect target.
curl -fsSL -I "${base}/${file}.sha256" >/dev/null && echo "FOUND sha256 at ${base}/${file}.sha256" || echo "No SHA256 checksum at ${base}/${file}.sha256"
curl -fsSL -I "${base}/${file}.sig" >/dev/null && echo "FOUND sig at ${base}/${file}.sig" || echo "No signature at ${base}/${file}.sig"
fiRepository: openshift/hypershift
Length of output: 3939
🏁 Script executed:
#!/bin/bash
set -euo pipefail
url="https://downloads.claude.ai/claude-code-releases/bootstrap.sh"
tmp="/tmp/claude-bootstrap.sh"
echo "== fetching $url to $tmp (no execute) =="
curl -fsSL "$url" -o "$tmp"
echo "== size/first 60 lines =="
wc -l "$tmp"
head -n 60 "$tmp" | sed -e 's/\t/ /g'
echo "== searching for verification-related strings =="
rg -n "sha256|sha1|md5|gpg|gpgv|pgp|cosign|sig|signature|verify|verification|openssl dgst|shasum|checksum|integrity|public key|keyring" "$tmp" || true
echo "== searching for download/extract/execution flow =="
rg -n "curl|wget|tar|unzip|sh -c|bash|chmod \\+x|./|exec " "$tmp" | head -n 80 || true
echo "== last 60 lines =="
tail -n 60 "$tmp" | sed -e 's/\t/ /g'Repository: openshift/hypershift
Length of output: 6207
Supply chain risk: unverified installer script executed after WIF auth
The workflow runs curl -fsSL https://claude.ai/install.sh | bash after the “Authenticate to GCP via WIF” step. Even though the redirected bootstrap.sh script verifies the SHA256 of the downloaded claude binary against a manifest checksum, the bootstrap script itself is executed without any hash/signature validation or version pinning, and it installs the latest release at runtime. If claude.ai/downloads.claude.ai is tampered with, arbitrary code could run with the job’s WIF-enabled permissions.
Mitigations:
- Fetch the bootstrap script to a file and verify it (hash/signature) before executing (or vendor it and pin).
- Pin the installer to a specific Claude Code version/manifest instead of using
latest.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/claude-wif-test.yaml around lines 48 - 51, Replace the
unsafe piped installer invocation "curl -fsSL https://claude.ai/install.sh |
bash" with a two-step verified install: download the bootstrap script to a file
(e.g., via curl), verify its integrity/signature against a pinned hash or
signature from a trusted source (or vendor the bootstrap script into the repo),
and only then execute it; also ensure the bootstrap is instructed to install a
pinned Claude Code release/manifest (not latest) or fetch a pinned manifest and
verify the downloaded binary checksum before installation. Locate the workflow
step that runs the installer (the run block containing the curl | bash line) and
update it to perform explicit download, verification, and pinned-version
installation instead of executing the remote script directly.
|
@bryan-cox: all tests passed! Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Summary
HOME=/home/runnerat job level for ARC runner containersHOME, so the Claude installer tries to create/.claudeand fails with permission deniedVerified locally by running the Claude installer inside the actual
ghcr.io/actions/actions-runnerbase image via podman.Test plan
/test-wifon any open PR — should pass the "Install Claude Code" step that currently fails withmkdir: cannot create directory '//.claude': Permission denied🤖 Generated with Claude Code
Summary by CodeRabbit