From 2813ab6cb4ac72e2b52b08205c7ffc1d5da96456 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 21 Sep 2025 17:21:41 -0400 Subject: [PATCH 1/6] Test that we always have `actions/checkout` not persist credentials --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9151ceb4857..74e1942c9ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -561,6 +561,31 @@ jobs: git status git diff --exit-code + # Check that all `actions/checkout` in CI jobs have `persist-credentials: false`. + check-no-persist-credentials: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + sparse-checkout: '.github/workflows' + - name: List workflows to be scanned + run: | + shopt -s extglob + printf '%s\n' .github/workflows/*.@(yaml|yml) + - name: Scan workflows + run: | + shopt -s extglob + yq '.jobs.*.steps[] + | select(.uses == "actions/checkout@*" and .with.["persist-credentials"]? != false) + | {"file": filename, "line": line, "name": (.name // .uses)} + | .file + ":" + (.line | tostring) + ": " + .name + ' .github/workflows/*.@(yaml|yml) >query-output.txt + cat query-output.txt + - name: Check for matches + run: test -z "$( Date: Sun, 21 Sep 2025 17:43:12 -0400 Subject: [PATCH 2/6] Check that we catch `actions/checkout` with no `with` --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 74e1942c9ea..878fa5eeeff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -546,8 +546,6 @@ jobs: steps: - uses: actions/checkout@v5 - with: - persist-credentials: false - name: Check that working tree is initially clean run: | set -x From 80b9e26a3138c2d98c63c6b2169943849264ac7b Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 21 Sep 2025 18:27:02 -0400 Subject: [PATCH 3/6] Improve `check-no-persist-credentials` output and maintainability --- .github/workflows/ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 878fa5eeeff..f4136ddbeb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -563,6 +563,9 @@ jobs: check-no-persist-credentials: runs-on: ubuntu-latest + env: + GLOB: .github/workflows/*.@(yaml|yml) + steps: - uses: actions/checkout@v5 with: @@ -571,7 +574,7 @@ jobs: - name: List workflows to be scanned run: | shopt -s extglob - printf '%s\n' .github/workflows/*.@(yaml|yml) + printf '%s\n' ${{ env.GLOB }} - name: Scan workflows run: | shopt -s extglob @@ -579,10 +582,9 @@ jobs: | select(.uses == "actions/checkout@*" and .with.["persist-credentials"]? != false) | {"file": filename, "line": line, "name": (.name // .uses)} | .file + ":" + (.line | tostring) + ": " + .name - ' .github/workflows/*.@(yaml|yml) >query-output.txt + ' -- ${{ env.GLOB }} >query-output.txt cat query-output.txt - - name: Check for matches - run: test -z "$( Date: Sun, 21 Sep 2025 18:30:20 -0400 Subject: [PATCH 4/6] Check that we catch checkout `with` without `persist-credentials` --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f4136ddbeb2..1482908b6cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -546,6 +546,8 @@ jobs: steps: - uses: actions/checkout@v5 + with: + persist-credentials: false - name: Check that working tree is initially clean run: | set -x @@ -610,7 +612,6 @@ jobs: echo "WORKFLOW_PATH=${relative_workflow_with_ref%@*}" >> "$GITHUB_ENV" - uses: actions/checkout@v5 with: - persist-credentials: false sparse-checkout: ${{ env.WORKFLOW_PATH }} - name: Get all jobs run: yq '.jobs | keys.[]' -- "$WORKFLOW_PATH" | sort | tee all-jobs.txt From 938313ae85a4eeb8c003d4c128fc3976ba837750 Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 21 Sep 2025 18:51:52 -0400 Subject: [PATCH 5/6] Check that we catch `persist-credentials` not set to boolean false --- .github/workflows/ci.yml | 1 + .github/workflows/cron.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1482908b6cf..067c73fdd41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -612,6 +612,7 @@ jobs: echo "WORKFLOW_PATH=${relative_workflow_with_ref%@*}" >> "$GITHUB_ENV" - uses: actions/checkout@v5 with: + persist-credentials: false sparse-checkout: ${{ env.WORKFLOW_PATH }} - name: Get all jobs run: yq '.jobs | keys.[]' -- "$WORKFLOW_PATH" | sort | tee all-jobs.txt diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 2765c016265..eb48470ceca 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v5 with: - persist-credentials: false + persist-credentials: '' - uses: Swatinem/rust-cache@v2 - name: stress run: make stress From adf319cf9b7715d98cd1ba519fc10fc4d223900a Mon Sep 17 00:00:00 2001 From: Eliah Kagan Date: Sun, 21 Sep 2025 18:54:35 -0400 Subject: [PATCH 6/6] Having tested the new check, restore `persist-credentials: false` --- .github/workflows/cron.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index eb48470ceca..2765c016265 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/checkout@v5 with: - persist-credentials: '' + persist-credentials: false - uses: Swatinem/rust-cache@v2 - name: stress run: make stress