Skip to content

BUILD-12475 Document persist-credentials: false for actions requiring contents: write - #341

Closed
julien-carsique-sonarsource wants to merge 1 commit into
masterfrom
fix/jcarsique/BUILD-12473-persist-credentials-false-examples
Closed

julien-carsique-sonarsource wants to merge 1 commit into
masterfrom
fix/jcarsique/BUILD-12473-persist-credentials-false-examples

Conversation

@julien-carsique-sonarsource

@julien-carsique-sonarsource julien-carsique-sonarsource commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Every composite action requiring contents: write (config-maven, build-maven, config-poetry, build-poetry, config-gradle, build-gradle, config-npm, build-npm, build-yarn, config-pip, config-uv) checks out the repo before running PR-authored build/test code (mvn verify, ./gradlew build, etc.).

actions/checkout defaults to persist-credentials: true, writing the job's now-elevated contents: write token into .git/config. A caller's PR-authored code running after checkout could use that persisted token to push to master or manipulate refs/build-number/*, since these composite actions themselves read their token from github.token in their own step env — not from the git credential helper — so persist-credentials: false doesn't affect them.

Adds persist-credentials: false to the actions/checkout step in each of the 11 usage examples above (check-sca's example is untouched — it doesn't require contents: write).

Confirmed working end-to-end: flagged by gitar-bot on sonar-dummy-maven-enterprise#143, applied there, all CI green (Linux/Windows build+verify, pre-commit).

Tracked in BUILD-12473.

Every composite action requiring contents: write (config-maven, build-maven,
config-poetry, build-poetry, config-gradle, build-gradle, config-npm,
build-npm, build-yarn, config-pip, config-uv) checks out the repo before
running PR-authored build/test code. actions/checkout defaults to
persist-credentials: true, writing that now-elevated token into
.git/config where PR-authored code could use it to push or manipulate
build-number refs - these actions themselves take their token from
github.token in their own step env, not the git credential helper, so
this doesn't affect their behavior.

Confirmed working (all CI green) on SonarSource/sonar-dummy-maven-enterprise#143,
which applies this to a real caller.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 1, 2026 16:23
@julien-carsique-sonarsource
julien-carsique-sonarsource requested a review from a team as a code owner September 1, 2026 16:23
@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Document persist-credentials: false for actions requiring contents: write BUILD-12475 Document persist-credentials: false for actions requiring contents: write Sep 1, 2026
@gitar-bot

gitar-bot Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Code Review ⚠️ Changes requested 0 resolved / 2 findings

Adds persist-credentials: false to usage examples for actions requiring contents: write, but this breaks git fetch operations in build-* actions that rely on persisted credentials for authentication — build-gradle will fail the job, while build-maven/build-npm/build-poetry/build-yarn silently degrade analysis. Additionally, the migration templates in .cursor/cirrus-github-migration.md and the per-action "Required GitHub Permissions" sections in README are not updated to reflect this pattern, so generated workflows will still expose the elevated token. Either keep credentials on the checkout for the build-* examples, configure git authentication separately (e.g. via http.extraheader), or update the templates and permissions documentation with the mitigation.

⚠️ Bug: persist-credentials: false breaks git fetch inside build-* actions

📄 README.md:341-343 📄 README.md:540-542 📄 README.md:651-653 📄 README.md:778-780 📄 README.md:1074-1076 📄 README.md:1186-1188

The build-maven, build-gradle, build-npm, build-poetry and build-yarn composite actions run git fetch --unshallow / git fetch origin "$GITHUB_BASE_REF" against origin to give SonarQube full history — these use the credential that actions/checkout writes into .git/config, not github.token from step env (no http.extraheader/GH_TOKEN is configured for git anywhere in the repo). With persist-credentials: false in a private repo the fetch is unauthenticated: build-gradle runs git fetch origin "$GITHUB_BASE_REF" unguarded on every PR (build-gradle/build.sh:74-77) and will fail the job, while the maven/npm/poetry/yarn variants swallow the failure with || true on the shallow path, so history is silently not unshallowed and new-code/blame analysis degrades with a green build — which is why the end-to-end test looked clean. Either keep credentials on the checkout for the build-* examples, or make the build actions authenticate git themselves (e.g. git -c http.extraheader="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64)" fetch ...) before documenting this pattern for them.

Revert persist-credentials: false in the six build-* examples (build-maven, build-poetry, build-gradle, build-npm, build-yarn) until the actions authenticate their own git fetch; keep it only in the config-* examples, which perform no git remote operations.
steps:
  - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
    with:
      # Full history for SonarQube; credentials stay persisted because the
      # build-* actions fetch from origin themselves.
      fetch-depth: 0
  - uses: SonarSource/ci-github-actions/build-gradle@v1
💡 Quality: New persist-credentials pattern not propagated or explained

📄 README.md:220 📄 README.md:235-239 📄 README.md:88-102

The migration templates in .cursor/cirrus-github-migration.md (lines 313-320 and 1789-1795) grant contents: write and check out with the default persist-credentials: true, so every workflow generated from them reproduces exactly the token-persistence exposure this PR sets out to close; nothing in the diff updates them or states they are intentionally excluded. Additionally, the README change is snippet-only: the per-action "Required GitHub Permissions" sections that call out contents: write never mention persist-credentials: false, so a reader who copies only the permissions block (or is told to add contents: write, as at README:88-92) gets the elevated token without the mitigation. Add the with: persist-credentials: false to the migration templates and one sentence of rationale next to the contents: write requirement.

Apply the same pattern to both build-job templates in .cursor/cirrus-github-migration.md and document the rationale once in the README requirements prose.
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
  with:
    # contents: write is elevated for this job; don't leave that token in
    # .git/config where PR-authored build code could reuse it.
    persist-credentials: false
🤖 Prompt for agents
Code Review: Adds `persist-credentials: false` to usage examples for actions requiring `contents: write`, but this breaks git fetch operations in `build-*` actions that rely on persisted credentials for authentication — `build-gradle` will fail the job, while `build-maven`/`build-npm`/`build-poetry`/`build-yarn` silently degrade analysis. Additionally, the migration templates in `.cursor/cirrus-github-migration.md` and the per-action "Required GitHub Permissions" sections in README are not updated to reflect this pattern, so generated workflows will still expose the elevated token. Either keep credentials on the checkout for the `build-*` examples, configure git authentication separately (e.g. via `http.extraheader`), or update the templates and permissions documentation with the mitigation.

1. ⚠️ Bug: persist-credentials: false breaks git fetch inside build-* actions
   Files: README.md:341-343, README.md:540-542, README.md:651-653, README.md:778-780, README.md:1074-1076, README.md:1186-1188

   The `build-maven`, `build-gradle`, `build-npm`, `build-poetry` and `build-yarn` composite actions run `git fetch --unshallow` / `git fetch origin "$GITHUB_BASE_REF"` against `origin` to give SonarQube full history — these use the credential that `actions/checkout` writes into `.git/config`, not `github.token` from step env (no `http.extraheader`/`GH_TOKEN` is configured for git anywhere in the repo). With `persist-credentials: false` in a private repo the fetch is unauthenticated: `build-gradle` runs `git fetch origin "$GITHUB_BASE_REF"` unguarded on every PR (build-gradle/build.sh:74-77) and will fail the job, while the maven/npm/poetry/yarn variants swallow the failure with `|| true` on the shallow path, so history is silently not unshallowed and new-code/blame analysis degrades with a green build — which is why the end-to-end test looked clean. Either keep credentials on the checkout for the build-* examples, or make the build actions authenticate git themselves (e.g. `git -c http.extraheader="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64)" fetch ...`) before documenting this pattern for them.

   Fix (Revert persist-credentials: false in the six build-* examples (build-maven, build-poetry, build-gradle, build-npm, build-yarn) until the actions authenticate their own git fetch; keep it only in the config-* examples, which perform no git remote operations.):
   steps:
     - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
       with:
         # Full history for SonarQube; credentials stay persisted because the
         # build-* actions fetch from origin themselves.
         fetch-depth: 0
     - uses: SonarSource/ci-github-actions/build-gradle@v1

2. 💡 Quality: New persist-credentials pattern not propagated or explained
   Files: README.md:220, README.md:235-239, README.md:88-102

   The migration templates in `.cursor/cirrus-github-migration.md` (lines 313-320 and 1789-1795) grant `contents: write` and check out with the default `persist-credentials: true`, so every workflow generated from them reproduces exactly the token-persistence exposure this PR sets out to close; nothing in the diff updates them or states they are intentionally excluded. Additionally, the README change is snippet-only: the per-action "Required GitHub Permissions" sections that call out `contents: write` never mention `persist-credentials: false`, so a reader who copies only the permissions block (or is told to add `contents: write`, as at README:88-92) gets the elevated token without the mitigation. Add the `with: persist-credentials: false` to the migration templates and one sentence of rationale next to the `contents: write` requirement.

   Fix (Apply the same pattern to both build-job templates in .cursor/cirrus-github-migration.md and document the rationale once in the README requirements prose.):
   - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
     with:
       # contents: write is elevated for this job; don't leave that token in
       # .git/config where PR-authored build code could reuse it.
       persist-credentials: false

Implementation Status ✅ 1 of 1 objectives covered
✅ BUILD-12473 - 1 of 1 objectives covered

This PR documents persist-credentials: false for actions requiring contents: write in the README usage examples.

✅ 1 covered here
  • ✅ Document persist-credentials: false for actions requiring contents: write
Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.
Unblock → Override a blocking verdict and allow merging.

Comment with these commands to change the behavior for this request:

Auto-apply Compact Unblock
gitar auto-apply:on         
gitar display:verbose         
gitar unblock         

Was this helpful? React with 👍 / 👎 | Gitar

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

BUILD-12475

Copilot AI 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.

Pull request overview

Updates the repository documentation to harden GitHub Actions workflow examples that run PR-authored code after checkout while requiring contents: write, by preventing actions/checkout from persisting the elevated token into .git/config.

Changes:

  • Add with: persist-credentials: false to actions/checkout in 11 README workflow examples that request contents: write.
  • Leave the check-sca example unchanged (as it does not require contents: write).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@sonarqubecloud

sonarqubecloud Bot commented Sep 1, 2026

Copy link
Copy Markdown

Comment thread README.md
Comment on lines 341 to +343
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false

@gitar-bot gitar-bot Bot Sep 1, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Bug: persist-credentials: false breaks git fetch inside build-* actions

The build-maven, build-gradle, build-npm, build-poetry and build-yarn composite actions run git fetch --unshallow / git fetch origin "$GITHUB_BASE_REF" against origin to give SonarQube full history — these use the credential that actions/checkout writes into .git/config, not github.token from step env (no http.extraheader/GH_TOKEN is configured for git anywhere in the repo). With persist-credentials: false in a private repo the fetch is unauthenticated: build-gradle runs git fetch origin "$GITHUB_BASE_REF" unguarded on every PR (build-gradle/build.sh:74-77) and will fail the job, while the maven/npm/poetry/yarn variants swallow the failure with || true on the shallow path, so history is silently not unshallowed and new-code/blame analysis degrades with a green build — which is why the end-to-end test looked clean. Either keep credentials on the checkout for the build-* examples, or make the build actions authenticate git themselves (e.g. git -c http.extraheader="AUTHORIZATION: basic $(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64)" fetch ...) before documenting this pattern for them.

Revert persist-credentials: false in the six build- examples (build-maven, build-poetry, build-gradle, build-npm, build-yarn) until the actions authenticate their own git fetch; keep it only in the config- examples, which perform no git remote operations.:**

steps:
  - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
    with:
      # Full history for SonarQube; credentials stay persisted because the
      # build-* actions fetch from origin themselves.
      fetch-depth: 0
  - uses: SonarSource/ci-github-actions/build-gradle@v1

Was this helpful? React with 👍 / 👎

Comment thread README.md
Comment on lines 235 to +239
contents: write
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false

@gitar-bot gitar-bot Bot Sep 1, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Quality: New persist-credentials pattern not propagated or explained

The migration templates in .cursor/cirrus-github-migration.md (lines 313-320 and 1789-1795) grant contents: write and check out with the default persist-credentials: true, so every workflow generated from them reproduces exactly the token-persistence exposure this PR sets out to close; nothing in the diff updates them or states they are intentionally excluded. Additionally, the README change is snippet-only: the per-action "Required GitHub Permissions" sections that call out contents: write never mention persist-credentials: false, so a reader who copies only the permissions block (or is told to add contents: write, as at README:88-92) gets the elevated token without the mitigation. Add the with: persist-credentials: false to the migration templates and one sentence of rationale next to the contents: write requirement.

Apply the same pattern to both build-job templates in .cursor/cirrus-github-migration.md and document the rationale once in the README requirements prose.:

- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
  with:
    # contents: write is elevated for this job; don't leave that token in
    # .git/config where PR-authored build code could reuse it.
    persist-credentials: false

Was this helpful? React with 👍 / 👎

@julien-carsique-sonarsource

Copy link
Copy Markdown
Contributor Author

We decided not to use persist-credentials: false at the moment.

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.

2 participants