Skip to content

ci: set persist-credentials: false on checkout steps#3006

Open
CTOmari360 wants to merge 1 commit into
NVIDIA:mainfrom
CTOmari360:ci/harden-workflow-checkout-credentials
Open

ci: set persist-credentials: false on checkout steps#3006
CTOmari360 wants to merge 1 commit into
NVIDIA:mainfrom
CTOmari360:ci/harden-workflow-checkout-credentials

Conversation

@CTOmari360

Copy link
Copy Markdown
Contributor

Harden every actions/checkout step by setting persist-credentials: false, so the GITHUB_TOKEN is no longer written to the runner's .git/config after checkout — where any later step in the same job could read it. This resolves the recurring CodeRabbit findings in one pass instead of fixing them one at a time as they come up.

Related issues

Fixes #2925

Type of Change

  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

All 20 workflow files were validated to still parse as YAML after the change.

Additional Notes

  • 41 read-only checkouts across 14 workflows now set persist-credentials: false.
  • One deliberate exception: the release-new-version job in release.yaml, whose checkout credential is consumed by the following Push Git Tag step (it pushes back to the repo). That checkout is left enabled and annotated with an inline comment so it is not "hardened" later by mistake.
  • Scope is intentionally limited to the persist-credentials hardening that CodeRabbit flags. Other possible lockdowns (pinning actions to commit SHAs, tightening per-workflow permissions: blocks) are left out to keep this PR single-purpose and easy to review — happy to follow up separately if those are wanted.

CodeRabbit repeatedly flags actions/checkout steps for leaving the
GITHUB_TOKEN in the runner's git config after checkout, where any later
step in the job could read it. Harden every checkout in one pass by
setting persist-credentials: false, rather than fixing them one at a
time as CodeRabbit notices.

This covers 41 read-only checkouts across 14 workflows. The single
exception is the release.yaml release-new-version job, whose checkout
must keep its credential so the following "Push Git Tag" step can push
back to the repo; that checkout is annotated with a comment explaining
why it is intentionally left enabled.

Fixes NVIDIA#2925

Signed-off-by: Omar Refai <omar@refai.org>
@CTOmari360 CTOmari360 requested a review from a team as a code owner June 30, 2026 03:15
@copy-pr-bot

copy-pr-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • Chores
    • Improved Git checkout handling across CI, build, release, and docs workflows by avoiding persisted credentials after checkout.
    • Reduced the chance of leftover authentication data during automated jobs.

Walkthrough

persist-credentials: false is added to actions/checkout steps across 14 GitHub Actions workflow files. The sole exception is the release-new-version job in release.yaml, which intentionally retains credential persistence for a subsequent git tag push step and receives explanatory comments to that effect.

Changes

Credential Persistence Hardening Across CI/CD Workflows

Layer / File(s) Summary
release.yaml: selective credential control
.github/workflows/release.yaml
fetch-new-version job gains persist-credentials: false; release-new-version job retains default credential persistence and receives inline comments explaining the intentional exception for the tag-push step.
ci.yaml: all 18 checkout steps hardened
.github/workflows/ci.yaml
Every actions/checkout@v4 step across all jobs (changes, prepare, manifest merges, release service tests, security scans, proto validation, lint, Helm chart build/push, Bluefield binaries/charts) gains persist-credentials: false.
All remaining workflows hardened
.github/workflows/build-boot-artifacts.yml, .github/workflows/docker-build.yml, .github/workflows/fern-docs-*.yml, .github/workflows/promotion.yaml, .github/workflows/publish-fern-docs.yml, .github/workflows/rest-*.yml
All checkout steps in the remaining 12 workflow files gain persist-credentials: false, applying the credential hardening uniformly across build, lint, test, Helm, and docs pipelines.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the primary change: disabling credential persistence on checkout steps.
Description check ✅ Passed The description is directly aligned with the workflow hardening changes and the linked issue.
Linked Issues check ✅ Passed The PR satisfies #2925 by broadly hardening checkout credentials with persist-credentials disabled, with one intentional release exception.
Out of Scope Changes check ✅ Passed The diff stays focused on checkout credential hardening; the added release comments document the intentional exception rather than introduce scope creep.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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/rest-prepare-build-info.yml:
- Around line 64-69: The checkout step in the workflow is disabling credential
persistence, which can leave later Git operations without auth. Update the
actions/checkout usage in the job that runs the tag fetch so the token remains
available, or explicitly pass a token to the step that runs git fetch --tags
--force. Keep the fix localized to the checkout/fetch sequence in the workflow
and ensure the tag-fetching logic can authenticate in private repositories.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 25d03b74-ee1e-4b28-a46f-6c10ac9b3fb4

📥 Commits

Reviewing files that changed from the base of the PR and between d63a8ad and f328b21.

📒 Files selected for processing (14)
  • .github/workflows/build-boot-artifacts.yml
  • .github/workflows/ci.yaml
  • .github/workflows/docker-build.yml
  • .github/workflows/fern-docs-ci.yml
  • .github/workflows/fern-docs-preview-build.yml
  • .github/workflows/promotion.yaml
  • .github/workflows/publish-fern-docs.yml
  • .github/workflows/release.yaml
  • .github/workflows/rest-build-binaries.yml
  • .github/workflows/rest-build-push-service.yml
  • .github/workflows/rest-ci.yml
  • .github/workflows/rest-helm-workflows.yml
  • .github/workflows/rest-lint-and-test.yml
  • .github/workflows/rest-prepare-build-info.yml

Comment on lines 64 to 69
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
fetch-depth: 0
submodules: recursive

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=.github/workflows/rest-prepare-build-info.yml

sed -n '64,76p' "$FILE"
echo
rg -n -C2 'git fetch|git submodule' "$FILE"

Repository: NVIDIA/infra-controller

Length of output: 799


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE=.github/workflows/rest-prepare-build-info.yml

echo "=== workflow header ==="
sed -n '1,120p' "$FILE"

echo
echo "=== checkout/auth-related lines ==="
rg -n -C3 'actions/checkout|persist-credentials|fetch-depth|git fetch|git describe|tags' "$FILE"

Repository: NVIDIA/infra-controller

Length of output: 6821


🌐 Web query:

actions/checkout persist-credentials false git fetch private repository credential removal documentation

💡 Result:

In GitHub Actions, the persist-credentials input for actions/checkout determines whether the authentication token used for the repository checkout is stored in the local Git configuration of the runner [1][2]. When persist-credentials is set to true (which has historically been the default), the action configures the local.git/config file with the necessary credentials [1][3]. This allows subsequent steps in the same job to execute authenticated Git commands without needing to explicitly provide a token [1][4]. These credentials are removed during the post-job cleanup process [1][2]. When persist-credentials is set to false, the action does not configure these credentials in the local Git configuration [1][4]. Consequently, if your workflow requires further Git operations that must authenticate with the remote repository (such as pushing changes or fetching additional data), those operations may fail unless you provide authentication tokens explicitly through other means [4]. Setting persist-credentials: false is often recommended as a security best practice, especially in workflows triggered by events that have access to sensitive repository permissions (such as pull_request_target or workflow_run), to prevent untrusted code in subsequent steps from easily reading the token from the disk [3]. Summary of behavior: - persist-credentials: true (default in many versions): Credentials are written to.git/config for use by later steps and removed during post-job cleanup [1][2]. - persist-credentials: false: Credentials are not written to.git/config, preventing implicit access by subsequent steps [1][4][3]. Documentation for actions/checkout confirms that this input exists specifically to allow users to opt-out of credential persistence [1][5]. While community discussions have explored changing the default to false to improve security, users should explicitly set this to false when security auditing or risk mitigation requires preventing implicit token availability [6][7][3].

Citations:


Restore auth for the tag fetch. With persist-credentials: false, the checkout token is not available to later Git commands, so git fetch --tags --force can fail in private repositories. Keep credentials persisted for this job or pass an explicit token to the fetch step.

🤖 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/rest-prepare-build-info.yml around lines 64 - 69, The
checkout step in the workflow is disabling credential persistence, which can
leave later Git operations without auth. Update the actions/checkout usage in
the job that runs the tag fetch so the token remains available, or explicitly
pass a token to the step that runs git fetch --tags --force. Keep the fix
localized to the checkout/fetch sequence in the workflow and ensure the
tag-fetching logic can authenticate in private repositories.

Source: Path instructions

@nv-dmendoza nv-dmendoza left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@ajf

ajf commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

/ok to test f328b21

@ajf ajf enabled auto-merge (squash) June 30, 2026 17:53
@github-actions

Copy link
Copy Markdown

🔐 TruffleHog Secret Scan

No secrets or credentials found!

Your code has been scanned for 700+ types of secrets and credentials. All clear! 🎉

🔗 View scan details

🕐 Last updated: 2026-06-30 17:56:32 UTC | Commit: f328b21

@github-actions

Copy link
Copy Markdown

🔍 Container Scan Summary

Service Total Critical High Medium Low Other
boot-artifacts-aarch64 3 0 0 3 0 0
boot-artifacts-x86_64 3 0 0 3 0 0
forge-admin-cli-x86_64 302 6 30 114 8 144
machine-validation-runner 765 30 194 283 37 221
machine_validation 765 30 194 283 37 221
machine_validation-aarch64 765 30 194 283 37 221
nvmetal-carbide 765 30 194 283 37 221
TOTAL 3368 126 806 1252 156 1028

Per-CVE detail lives in the per-service grype-* artifacts (JSON + SARIF). Severity counts only — no CVE IDs published here.

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.

Audit github workflow actions for credential configuration

3 participants