Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7
Comment on lines 17 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's see the structure and find the workflow file
find .github/workflows -name "ci-build.yml" -type f

Repository: codeready-toolchain/toolchain-e2e

Length of output: 108


🏁 Script executed:

#!/bin/bash
# Read the ci-build.yml file to see the checkout usage
cat -n .github/workflows/ci-build.yml | head -60

Repository: codeready-toolchain/toolchain-e2e

Length of output: 1273


🏁 Script executed:

#!/bin/bash
# Check if there are additional checkout uses beyond line 38
cat -n .github/workflows/ci-build.yml

Repository: codeready-toolchain/toolchain-e2e

Length of output: 1273


🌐 Web query:

GitHub Actions checkout mutable tags security risk @v7 pinning to SHA

💡 Result:

Pinning GitHub Actions to a full-length commit SHA is a critical security best practice to mitigate supply chain attacks [1][2][3]. Referencing actions by mutable tags (e.g., @v7) or branches allows the underlying code to be silently updated by repository maintainers or attackers who gain unauthorized access [1][4][3]. By using a full 40-character commit SHA, you ensure the workflow executes a specific, immutable version of the code, preventing "tag-mutation" attacks where malicious code is injected into an existing version tag [2][5][6]. Security Recommendations and Best Practices: 1. Pin to Full SHA: Always use the full 40-character commit SHA for all third-party actions [4][7][3]. 2. Maintain Human-Readability: To retain context, use a trailing comment to indicate the original version tag (e.g., - uses: actions/checkout@de0fac2 # v6.0.2) [2][4][3]. 3. Enforce via Policy: If you manage an organization, use GitHub's organization-level policy to enforce SHA pinning, which causes workflows using non-pinned actions to fail automatically [6][8]. 4. Automate Updates: Manually maintaining SHAs is error-prone. Use tools like Renovate (with the helpers:pinGitHubActionDigests preset) or Dependabot to automatically track and propose updates to pinned SHAs, keeping your actions secure and current without manual overhead [4][5][6]. 5. Defense-in-Depth: SHA pinning is necessary but not always sufficient [1][9]. Ensure your security posture includes least-privilege permissions, OIDC-based authentication, and monitoring, as SHA pinning does not protect against vulnerabilities inherent in the action code itself or actions that dynamically fetch other unpinned dependencies at runtime [1][9][3]. GitHub maintains documentation on these security practices, emphasizing that pinning to a full-length commit SHA is currently the only way to treat an action reference as an immutable asset [10]. While GitHub has introduced an immutable release feature for tags, the industry standard for maximum security remains explicit SHA pinning [11][10].

Citations:


🌐 Web query:

GitHub Actions persist-credentials false best practice when necessary

💡 Result:

Setting persist-credentials: false in the actions/checkout GitHub Action is considered a security best practice for most workflows [1][2][3]. The persist-credentials input defaults to true, which configures the local Git environment with a GITHUB_TOKEN (or a provided PAT) to enable authenticated Git operations [4][2]. When left at its default, this token remains available to all subsequent steps in the job [5][6]. If a workflow is compromised or utilizes insecure third-party actions, those actions could potentially access or misuse the persisted credentials [2][5]. Best Practice Guidance: 1. Default to false: For the majority of workflows that only checkout code and do not perform subsequent Git operations (e.g., git push, git commit), you should explicitly set persist-credentials: false [1][2]. 2. When to use true: Only set persist-credentials: true when your workflow genuinely requires authenticated Git commands to run in later steps [2]. 3. Defense in depth: Even if you must persist credentials, follow the principle of least privilege by using scoped permissions for your GITHUB_TOKEN or restricted service accounts [6][7]. Example of the recommended configuration: - name: Code checkout uses: actions/checkout@v6 with: persist-credentials: false While the official actions/checkout has improved security by storing credentials in a separate file under $RUNNER_TEMP rather than directly in.git/config, explicitly disabling persistence remains the recommended approach to minimize the attack surface of your workflow jobs [4][8].

Citations:


Pin checkout to commit SHA and disable credential persistence.

actions/checkout@v7 uses a mutable tag, which allows supply chain attack vectors through tag mutation. Additionally, the default persist-credentials: true leaves the GITHUB_TOKEN available to all subsequent steps unnecessarily. This workflow only checks out code for linting and testing, so both credentials and mutable tags should be eliminated.

Suggested changes
-      uses: actions/checkout@v7
+      uses: actions/checkout@<sha>
+      with:
+        persist-credentials: false

Also applies to: 37-38

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 17-18: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 18-18: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/ci-build.yml around lines 17 - 18, The actions/checkout
step at the specified location uses a mutable tag reference (v7) which creates a
supply chain attack vector, and the default behavior allows GITHUB_TOKEN
credentials to persist across all subsequent steps unnecessarily. Replace the
mutable tag reference with a pinned commit SHA for actions/checkout and add the
persist-credentials parameter set to false to the uses statement to disable
credential persistence for this workflow that only requires code checkout for
linting and testing.

Source: Linters/SAST tools


- name: Install Go
uses: actions/setup-go@v6
Expand All @@ -35,7 +35,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7

- name: Install Go
uses: actions/setup-go@v6
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-check-gomod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7
Comment on lines 14 to +15

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n .github/workflows/ci-check-gomod.yml | head -50

Repository: codeready-toolchain/toolchain-e2e

Length of output: 531


Pin checkout to a SHA and disable credential persistence.

actions/checkout@v7 uses a mutable tag, and this job doesn't require persisted git credentials since it only checks go.mod replacements. Pin it to a specific SHA and set persist-credentials: false to reduce the attack surface.

Suggested change
-      uses: actions/checkout@v7
+      uses: actions/checkout@<sha>
+      with:
+        persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 14-15: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 15-15: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/ci-check-gomod.yml around lines 14 - 15, The checkout
action in the "Checkout code" step uses a mutable version tag (v7) instead of a
pinned SHA, and it's persisting git credentials when they're not needed. Replace
the `actions/checkout@v7` reference with a pinned SHA commit hash and add
`persist-credentials: false` as a parameter to the checkout step to disable
credential persistence and reduce the attack surface.

Source: Linters/SAST tools

- name: check
uses: codeready-toolchain/toolchain-cicd/gomod-check@master
2 changes: 1 addition & 1 deletion .github/workflows/govulncheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7
Comment on lines 13 to +14

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the file exists and examine its content
if [ -f ".github/workflows/govulncheck.yml" ]; then
  echo "=== File exists ==="
  cat -n ".github/workflows/govulncheck.yml"
else
  echo "File not found"
  find . -name "govulncheck.yml" -o -name "*govuln*"
fi

Repository: codeready-toolchain/toolchain-e2e

Length of output: 651


🏁 Script executed:

#!/bin/bash
# Check for other checkout actions in the repo to see the pattern
echo "=== All checkout actions in this repo ==="
rg "actions/checkout@" .github/workflows/ -A 2 -B 1

Repository: codeready-toolchain/toolchain-e2e

Length of output: 1775


🏁 Script executed:

#!/bin/bash
# Check if this workflow uses any authenticated operations
echo "=== Checking workflow context and job definition ==="
rg "persist-credentials" .github/workflows/ || echo "No persist-credentials found"

Repository: codeready-toolchain/toolchain-e2e

Length of output: 159


🌐 Web query:

actions/checkout v7 best practices security mutable tags persist-credentials

💡 Result:

The actions/checkout v7 release, launched on June 18, 2026, introduces significant security enhancements to default behaviors, particularly regarding pull request handling [1][2]. Below are the key best practices and security considerations: ### 1. Security Enhancements in v7 actions/checkout v7 now blocks checking out fork pull request code by default in pull_request_target and workflow_run events to mitigate common pwn-request vulnerabilities [1][2]. - If your workflow legitimately requires checking out fork pull request code in these contexts, you can opt out of this protection by setting the allow-unsafe-pr-checkout input to true [1][3]. - This option is intentionally named to be easy to identify during code reviews and security audits [1][3]. ### 2. Best Practice: persist-credentials By default, actions/checkout persists Git credentials (specifically the GITHUB_TOKEN or other configured tokens) into the runner’s Git configuration to allow subsequent Git operations [4][5]. - Recommendation: Unless your workflow explicitly requires executing authenticated Git commands (like pushing commits back to the repository), you should always set persist-credentials: false [6][7][8]. - Risk: Leaving this enabled (the default) exposes the credentials to any subsequent step or third-party action within the same job [8][9]. This has historically led to vulnerabilities like "ArtiPACKED," where leaked tokens are inadvertently included in uploaded artifacts [10]. ### 3. Best Practice: Use Immutable Tags To ensure supply chain security, avoid using mutable tags (e.g., actions/checkout@v7) that can be updated by the action owner to point to malicious code [7]. - Recommendation: Pin your actions to a specific, immutable commit SHA [7]. - Example: - uses: actions/checkout@11bd719 ### 4. General Workflow Security - Least Privilege: Ensure your GITHUB_TOKEN has the minimum required permissions using the permissions: key at the job or workflow level [7][11][9]. - Avoid Untrusted Code: Never check out and execute code from untrusted sources (e.g., external forks) in privileged contexts like pull_request_target [6][3][11]. When necessary, always use immutable references (commit SHAs) to point to the exact, audited state of the code [6][11].

Citations:


Pin checkout to a commit SHA and disable credential persistence.

The actions/checkout@v7 action uses a mutable tag, creating a supply chain security risk. Additionally, this job only reads the repository and doesn't require persisted Git credentials. Pin to a specific commit SHA and set persist-credentials: false.

Suggested change
    - name: Checkout code
      uses: actions/checkout@v7
+     with:
+       persist-credentials: false

Note: Replace v7 with a pinned commit SHA (e.g., 11bd71901bbe5b1630ceea73d27597364c9af683) to fully secure the action reference.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v7
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 13-14: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 14-14: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/govulncheck.yml around lines 13 - 14, The
`actions/checkout` action is using a mutable tag (v7) which presents a supply
chain security risk. Pin the action to a specific commit SHA instead of the v7
tag, and add the parameter `persist-credentials: false` to the checkout action
configuration since this job only requires read-only access to the repository
and does not need Git credentials to be persisted between runs.

Source: Linters/SAST tools


- name: Run govulncheck
uses: codeready-toolchain/toolchain-cicd/govulncheck-action@master
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish-components-for-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
steps:
# Checkout from PR event
- name: Checkout code from PR event
uses: actions/checkout@v6
uses: actions/checkout@v7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the workflow file exists and examine the checkout steps
if [ -f ".github/workflows/publish-components-for-e2e-tests.yml" ]; then
  echo "=== File contents ===" 
  cat -n .github/workflows/publish-components-for-e2e-tests.yml | head -60
else
  echo "File not found in toolchain-e2e"
  # Check host-operator as the linked findings suggest it might be there
fi

Repository: codeready-toolchain/toolchain-e2e

Length of output: 2454


🏁 Script executed:

#!/bin/bash
# Check the host-operator repo which was mentioned in linked findings
if [ -f ".github/workflows/publish-components-for-e2e-tests.yml" ]; then
  echo "=== File from host-operator ===" 
  cat -n .github/workflows/publish-components-for-e2e-tests.yml | head -60
else
  echo "File not found"
fi

Repository: codeready-toolchain/host-operator

Length of output: 2656


🌐 Web query:

actions/checkout v7 fork security persist-credentials best practices

💡 Result:

As of June 2026, actions/checkout v7 is the latest major version [1][2]. It introduces significant security improvements regarding how fork pull requests are handled, while maintainining existing best practices for credential persistence [3][4]. Persist-Credentials Best Practices The persist-credentials input defaults to true in all versions, including v7 [5][6]. When true, the GITHUB_TOKEN (or provided SSH key) is configured in the local Git repository's configuration for the duration of the job [5]. While this is convenient for authenticated Git operations (like pushing commits), it poses security risks because subsequent steps or third-party actions in the same job can read these credentials [7][6]. Best practices for persist-credentials: - Explicitly set persist-credentials: false in all workflows unless your job specifically requires authenticated Git write access (e.g., pushing tags or commits back to the repo) [6]. - If you require authenticated Git access, ensure the GITHUB_TOKEN has the minimum necessary permissions [6]. - Rely on the default only when absolutely necessary and limit the scope of subsequent steps to minimize exposure [6]. Fork Security in v7 A major feature of actions/checkout v7 is its improved protection against "pwn request" vulnerabilities in privileged contexts [3][8]. - By default, v7 now refuses to check out fork pull request code when triggered by pull_request_target or certain workflow_run events [3][4]. This prevents malicious fork code from running in the context of the base repository's secrets and permissions [3][4]. - If a workflow genuinely requires this behavior and has been audited for safety, you must explicitly opt-in by setting allow-unsafe-pr-checkout: true [3][4][8]. This input is intentionally named to be prominent during code reviews and security audits [3][4]. For workflows using pull_request_target, GitHub recommends thoroughly reviewing the security implications before enabling allow-unsafe-pr-checkout [3][4]. You should also ensure that your GITHUB_TOKEN permissions are restricted to the minimum level required [4][9].

Citations:


Add allow-unsafe-pr-checkout: true to both checkout steps for v7 compatibility with fork repositories.

actions/checkout v7 introduces a breaking security change: it now refuses to check out fork pull request code when triggered by pull_request_target events unless explicitly opt-in via allow-unsafe-pr-checkout: true. This workflow explicitly checks out fork repositories (lines 31–32 and 51–52), so both checkout steps will fail without this flag.

Additionally, add persist-credentials: false to both steps as a best practice for read-only operations, and optionally pin to commit SHAs for supply chain security.

Suggested change (line 28)
      uses: actions/checkout@v7
+      with:
+        ref: ${{github.event.pull_request.head.ref}}
+        repository: ${{github.event.pull_request.head.repo.full_name}}
+        fetch-depth: 0
+        allow-unsafe-pr-checkout: true
+        persist-credentials: false
Suggested change (line 48)
      uses: actions/checkout@v7
+      with:
+        repository: ${{ fromJson(steps.request.outputs.data).head.repo.full_name }}
+        ref: ${{ fromJson(steps.request.outputs.data).head.ref }}
+        fetch-depth: 0
+        allow-unsafe-pr-checkout: true
+        persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uses: actions/checkout@v7
uses: actions/checkout@v7
with:
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
fetch-depth: 0
allow-unsafe-pr-checkout: true
persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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/publish-components-for-e2e-tests.yml at line 28, Both
checkout steps (actions/checkout@v7) in this workflow need to be updated to
handle fork pull request checkouts safely. Add `allow-unsafe-pr-checkout: true`
to both checkout steps to opt into the v7 breaking security change that requires
explicit approval for checking out fork PRs with pull_request_target events.
Additionally, add `persist-credentials: false` to both checkout steps as a best
practice since the workflow only performs read operations, and optionally pin to
specific commit SHAs instead of v7 for improved supply chain security.

Source: Linters/SAST tools

if: ${{ github.event_name == 'pull_request_target' }}
with:
ref: ${{github.event.pull_request.head.ref}}
Expand All @@ -45,7 +45,7 @@ jobs:
# Checkout the code based on the data retrieved from the previous step
# Is executed only for comment events
- name: Checkout code from PR
uses: actions/checkout@v6
uses: actions/checkout@v7
if: ${{ github.event_name == 'issue_comment' }}
with:
repository: ${{ fromJson(steps.request.outputs.data).head.repo.full_name }}
Expand Down
Loading