Skip to content

ci: use commit hash for github action, add persist-credentials false - #357

Closed
richm wants to merge 1 commit into
mainfrom
use-commit-hash
Closed

ci: use commit hash for github action, add persist-credentials false#357
richm wants to merge 1 commit into
mainfrom
use-commit-hash

Conversation

@richm

@richm richm commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

The latest security guidance is to use the full commit hash, which is immutable,
instead of a tag or version, which can be mutable, for the reference to a version
of a github action. There are known attacks which inserted unauthorized code
in a version tag and moved the tag. This prevents this sort of attack, at the
cost of more maintenance burden, but dependabot will largely take care of this
for us.

Each version or tag has been replaced with the corresponding commit hash - in some
cases, this is not the latest commit on the main branch, so I would expect to see
some dependabot updates in the near future. I thought it was safer to do it this
way - preserve existing behavior/functionality - rather than replace and upgrade
to a newer version at the same time.

The coderabbit Pin the Galaxy action's container image. issue is tracked at
robertdebock/galaxy-action#16

This also adds persist-credentials: false to the actions/checkout tasks so that
any credentials used by that task will not persist for subsequent tasks, for those
workflows that do not need the credentials for subsequent tasks.

Signed-off-by: Rich Megginson rmeggins@redhat.com

Summary by CodeRabbit

  • Security

    • Improved the reliability and security of automated workflows by locking third-party tools and actions to verified, immutable versions.
    • Reduced the risk of unintended changes from moving versions and limited credential persistence during automated tasks.
  • Chores

    • Updated continuous integration, testing, documentation, release, and publishing workflows while preserving their existing behavior.

@richm richm self-assigned this Aug 12, 2026
The latest security guidance is to use the full commit hash, which is immutable,
instead of a tag or version, which can be mutable, for the reference to a version
of a github action.  There are known attacks which inserted unauthorized code
in a version tag and moved the tag.  This prevents this sort of attack, at the
cost of more maintenance burden, but dependabot will largely take care of this
for us.

Each version or tag has been replaced with the corresponding commit hash - in some
cases, this is not the latest commit on the main branch, so I would expect to see
some dependabot updates in the near future.  I thought it was safer to do it this
way - preserve existing behavior/functionality - rather than replace and upgrade
to a newer version at the same time.

The coderabbit `Pin the Galaxy action's container image.` issue is tracked at
robertdebock/galaxy-action#16

This also adds `persist-credentials: false` to the actions/checkout tasks so that
any credentials used by that task will not persist for subsequent tasks, for those
workflows that do not need the credentials for subsequent tasks.

Signed-off-by: Rich Megginson <rmeggins@redhat.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The workflows now use commit-pinned GitHub Actions and pinned tox-lsr revisions. Checkout steps explicitly configure credential persistence for workflows that commit or push changes.

Workflow dependency pinning

Layer / File(s) Summary
Validation workflow pins
.github/workflows/ansible-*.yml, .github/workflows/codeql.yml, .github/workflows/codespell.yml, .github/workflows/markdownlint.yml, .github/workflows/pr-title-lint.yml, .github/workflows/python-unit-test.yml, .github/workflows/woke.yml
Validation workflows pin action and tox-lsr references. Checkout credential persistence is explicitly configured.
Build and release workflow pins
.github/workflows/build_docs.yml, .github/workflows/changelog_to_tag.yml, .github/workflows/weekly_ci.yml
Build, release, publishing, and weekly automation actions use pinned revisions. Required checkout credentials remain enabled where commits or pushes occur.
Integration and status workflow pins
.github/workflows/qemu-kvm-integration-tests.yml, .github/workflows/test_converting_readme.yml, .github/workflows/tft.yml
Integration, artifact, status, and Testing Farm actions use immutable revisions. Checkout steps disable credential persistence where applicable.

Suggested reviewers: spetrosi, rjeffman

Mergeability Score: 🟡 Moderate · up to 9f3b9

The documentation workflow may expose a write-capable repository credential to the Pandoc conversion environment, so a compromised conversion step could push unauthorized changes. Merge should wait until that job is read-only or the credential is otherwise isolated.

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description Format ⚠️ Warning The PR description omits the required Enhancement/Feature, Reason, and Result sections from .github/pull_request_template.md; only Signed-off-by is present. Rewrite the description with Enhancement or Feature, Reason, and Result sections, and retain the Signed-off-by line.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the valid ci type and clearly describes the commit-hash and credential-persistence changes. (github.com)
Description check ✅ Passed The description covers the change, security reason, expected result, and tracked issue, although it does not use the template headings.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/changelog_to_tag.yml (1)

82-82: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider replacing the release action with gh release.

The static-analysis hint identifies gh release as runner-provided. If this step only needs the shown tag, title, notes file, and latest-release behavior, gh release create supports those inputs and can remove one third-party action. Verify its tag validation and failure behavior before changing the workflow. (cli.github.com)

🤖 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/changelog_to_tag.yml at line 82, Replace the
ncipollo/release-action step with the runner-provided gh release create command,
preserving the existing tag, title, notes-file, and latest-release inputs.
Verify the command validates tags and fails appropriately, and retain any
required environment or authentication setup from the workflow.

Source: Linters/SAST tools

🤖 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/build_docs.yml:
- Around line 28-30: Update the workflow so Pandoc conversion runs in a separate
read-only job, with persist-credentials: false on every checkout. Move branch
initialization and pushing into a distinct write job that alone uses the
contents: write credential, and connect it to the conversion job’s output or
artifact as needed.

---

Nitpick comments:
In @.github/workflows/changelog_to_tag.yml:
- Line 82: Replace the ncipollo/release-action step with the runner-provided gh
release create command, preserving the existing tag, title, notes-file, and
latest-release inputs. Verify the command validates tags and fails
appropriately, and retain any required environment or authentication setup from
the workflow.
🪄 Autofix

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 30286c08-3557-4953-a513-c60a763e5d62

📥 Commits

Reviewing files that changed from the base of the PR and between 336f37a and 9f3b9f7.

📒 Files selected for processing (15)
  • .github/workflows/ansible-lint.yml
  • .github/workflows/ansible-managed-var-comment.yml
  • .github/workflows/ansible-test.yml
  • .github/workflows/build_docs.yml
  • .github/workflows/changelog_to_tag.yml
  • .github/workflows/codeql.yml
  • .github/workflows/codespell.yml
  • .github/workflows/markdownlint.yml
  • .github/workflows/pr-title-lint.yml
  • .github/workflows/python-unit-test.yml
  • .github/workflows/qemu-kvm-integration-tests.yml
  • .github/workflows/test_converting_readme.yml
  • .github/workflows/tft.yml
  • .github/workflows/weekly_ci.yml
  • .github/workflows/woke.yml

Comment on lines +28 to +30
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: true # needed for commit and push

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

file=".github/workflows/build_docs.yml"
printf '%s\n' '--- workflow ---'
cat -n "$file"

printf '%s\n' '--- checkout and container-action references ---'
rg -n -C 4 'actions/checkout|container:|uses:|persist-credentials|permissions:|contents:|git push|git config|ref_branch|docs' "$file"

printf '%s\n' '--- repository workflow files ---'
git ls-files '.github/workflows/*'

Repository: linux-system-roles/certificate

Length of output: 9641


🏁 Script executed:

#!/bin/bash
set -eu

sha="3d3c42e5aac5ba805825da76410c181273ba90b1"
printf '%s\n' '--- pinned actions/checkout metadata ---'
curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/action.yml" |
  sed -n '1,220p' |
  rg -n -C 3 'persist-credentials|credential|token|post'

printf '%s\n' '--- pinned actions/checkout implementation references ---'
for path in src/input-helper.ts src/git-auth-helper.ts src/main.ts; do
  printf '%s\n' "--- $path ---"
  curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/${path}" |
    rg -n -C 3 'persistCredentials|extraheader|configureToken|removeToken|git config'
done

printf '%s\n' '--- GitHub documentation references for Docker action workspace mounts ---'
curl -fsSL 'https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action' |
  rg -in -C 2 'workspace|mount|docker container action'

Repository: linux-system-roles/certificate

Length of output: 7364


🏁 Script executed:

#!/bin/bash
set -eu

sha="3d3c42e5aac5ba805825da76410c181273ba90b1"

printf '%s\n' '--- credential-file configuration ---'
curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/src/git-auth-helper.ts" |
  sed -n '320,390p;460,515p;550,590p'

printf '%s\n' '--- checkout tests or documentation for persisted credentials ---'
for path in README.md __tests__/git-auth-helper.test.ts __tests__/input-helper.test.ts; do
  printf '%s\n' "--- $path ---"
  curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/${path}" 2>/dev/null |
    rg -n -C 3 'credentialsConfig|includeIf|persist-credentials|RUNNER_TEMP|git-credentials' || true
done

printf '%s\n' '--- Docker container action workspace and temp references ---'
curl -fsSL 'https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action' |
  rg -in -C 5 'GITHUB_WORKSPACE|/github/workspace|volume|mount|RUNNER_TEMP|_temp' || true

Repository: linux-system-roles/certificate

Length of output: 50387


🏁 Script executed:

#!/bin/bash
set -eu

sha="3d3c42e5aac5ba805825da76410c181273ba90b1"

printf '%s\n' '--- container include configuration ---'
curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/src/git-auth-helper.ts" |
  sed -n '350,455p'

printf '%s\n' '--- pinned action identity and runner requirement ---'
curl -fsSL "https://raw.githubusercontent.com/actions/checkout/${sha}/README.md" |
  sed -n '1,42p'
curl -fsSL "https://api.github.com/repos/actions/checkout/commits/${sha}" |
  jq -r '"commit=\(.sha)\nmessage=\(.commit.message | split("\n")[0])\ndate=\(.commit.author.date)"'

Repository: linux-system-roles/certificate

Length of output: 7027


Isolate Pandoc from the write token.

Because Pandoc runs in the same job as checkouts with credential persistence enabled, a compromised container can use the runner-mounted contents: write credential to push. Run conversion in a read-only job with persist-credentials: false on every checkout. Perform branch initialization and pushing in a separate write job.

🤖 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/build_docs.yml around lines 28 - 30, Update the workflow
so Pandoc conversion runs in a separate read-only job, with persist-credentials:
false on every checkout. Move branch initialization and pushing into a distinct
write job that alone uses the contents: write credential, and connect it to the
conversion job’s output or artifact as needed.

@richm richm closed this Aug 12, 2026
@richm
richm deleted the use-commit-hash branch August 12, 2026 23:00
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