Skip to content

Commit 029a67e

Browse files
authored
Harden workflows for OpenSSF scorecard (#79)
Signed-off-by: Davanum Srinivas <dsrinivas@nvidia.com>
1 parent 6c62f81 commit 029a67e

File tree

10 files changed

+206
-48
lines changed

10 files changed

+206
-48
lines changed

.github/actions/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ This action runs `tools/setup-tools --skip-go --skip-docker` in auto mode, which
7777
```yaml
7878
- uses: ./.github/actions/load-versions
7979
id: versions
80-
- uses: actions/setup-go@v5
80+
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
8181
with:
8282
go-version: ${{ steps.versions.outputs.go }}
8383
```
@@ -282,7 +282,7 @@ jobs:
282282
test:
283283
runs-on: ubuntu-latest
284284
steps:
285-
- uses: actions/checkout@v5
285+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
286286
- uses: ./.github/actions/load-versions
287287
id: versions
288288
- uses: ./.github/actions/go-ci
@@ -299,7 +299,7 @@ jobs:
299299
release:
300300
runs-on: ubuntu-latest
301301
steps:
302-
- uses: actions/checkout@v5
302+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
303303
- uses: ./.github/actions/load-versions
304304
id: versions
305305
- uses: ./.github/actions/go-ci

.github/workflows/codeql.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ on:
3434
- cron: '0 5 * * 1'
3535

3636
permissions:
37-
actions: read
3837
contents: read
39-
security-events: write
4038

4139
jobs:
4240
analyze:
4341
runs-on: ubuntu-latest
42+
permissions:
43+
actions: read
44+
contents: read
45+
security-events: write
4446
steps:
4547
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4648
- uses: ./.github/actions/load-versions

.github/workflows/kwok-recipes.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ on:
3939
type: string
4040

4141
permissions:
42-
actions: read
4342
contents: read
4443

4544
concurrency:
@@ -54,6 +53,8 @@ jobs:
5453
outputs:
5554
recipes: ${{ steps.find.outputs.recipes }}
5655
recipe_count: ${{ steps.find.outputs.recipe_count }}
56+
permissions:
57+
contents: read
5758
steps:
5859
- name: Checkout Code
5960
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -113,6 +114,8 @@ jobs:
113114
max-parallel: 4
114115
matrix:
115116
recipe: ${{ fromJSON(needs.discover.outputs.recipes) }}
117+
permissions:
118+
contents: read
116119
steps:
117120
- name: Checkout Code
118121
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -137,6 +140,8 @@ jobs:
137140
needs: [discover, test]
138141
runs-on: ubuntu-latest
139142
if: always()
143+
permissions:
144+
contents: read
140145
steps:
141146
- name: Check test results
142147
run: |

.github/workflows/on-push-comment.yaml

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
# This workflow posts coverage comments on PRs after the main workflow completes.
16-
# Using workflow_run gives us write permissions even for fork PRs.
16+
# Uses workflow_run with guarded checkout to avoid executing untrusted code.
1717
# See: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
1818

1919
name: Post PR Comment
@@ -26,15 +26,17 @@ on:
2626

2727
permissions:
2828
actions: read # Required to download artifacts from other workflow runs
29-
contents: read # Required to checkout repository for go.mod and changed-files
3029
pull-requests: write
3130

3231
jobs:
3332
post-coverage-comment:
3433
name: Post Coverage Comment
3534
runs-on: ubuntu-latest
3635
# Run for PRs regardless of conclusion - coverage might exist even if other steps failed
37-
if: github.event.workflow_run.event == 'pull_request'
36+
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.head_repository.fork == false
37+
permissions:
38+
actions: read
39+
pull-requests: write
3840
steps:
3941
- name: Checkout for go.mod version
4042
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -58,7 +60,7 @@ jobs:
5860
with:
5961
name: coverage-pr
6062
path: /tmp/pr-coverage
61-
github-token: ${{ secrets.GITHUB_TOKEN }}
63+
github-token: ${{ github.token }}
6264
run-id: ${{ github.event.workflow_run.id }}
6365

6466
- name: Download Coverage Metadata
@@ -68,14 +70,14 @@ jobs:
6870
with:
6971
name: coverage-comment-data
7072
path: /tmp/coverage-comment-data
71-
github-token: ${{ secrets.GITHUB_TOKEN }}
73+
github-token: ${{ github.token }}
7274
run-id: ${{ github.event.workflow_run.id }}
7375

7476
- name: Download Baseline Coverage
7577
id: download-baseline
7678
if: steps.download-pr.outcome == 'success'
7779
env:
78-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
80+
GH_TOKEN: ${{ github.token }}
7981
run: |
8082
set -e
8183
mkdir -p /tmp/baseline-coverage
@@ -111,25 +113,41 @@ jobs:
111113
echo "mode: set" > /tmp/baseline-coverage/coverage.out
112114
fi
113115
114-
- name: Checkout for changed-files action
115-
if: steps.download-pr.outcome == 'success'
116-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
117-
with:
118-
ref: ${{ github.event.workflow_run.head_sha }}
119-
fetch-depth: 0
120-
121116
- name: Get Changed Files
122117
id: changed-files
123118
if: steps.download-pr.outcome == 'success'
124-
uses: tj-actions/changed-files@aa08304bd477b800d468db44fe10f6c61f7f7b11 # v46.0.5
125-
with:
126-
write_output_files: true
127-
json: true
128-
files: "**.go"
129-
files_ignore: |
130-
vendor/**
131-
**_test.go
132-
output_dir: .github/outputs
119+
shell: bash
120+
env:
121+
GH_TOKEN: ${{ github.token }}
122+
run: |
123+
set -euo pipefail
124+
mkdir -p .github/outputs
125+
126+
PR_URL="${{ github.event.workflow_run.pull_requests[0].url }}"
127+
if [[ -z "$PR_URL" || "$PR_URL" == "null" ]]; then
128+
echo "No PR URL found in workflow_run payload. Skipping changed files." >&2
129+
echo "any_changed=false" >> "$GITHUB_OUTPUT"
130+
exit 0
131+
fi
132+
133+
FILES_JSON=$(curl -sS \
134+
-H "Authorization: Bearer $GH_TOKEN" \
135+
-H "Accept: application/vnd.github+json" \
136+
"$PR_URL/files?per_page=300")
137+
138+
echo "$FILES_JSON" | jq -c '
139+
[.[] |
140+
select(.filename | endswith(".go")) |
141+
select(.filename | test("^vendor/") | not) |
142+
select(.filename | test("_test\\.go$") | not) |
143+
.filename
144+
]' > .github/outputs/all_modified_files.json
145+
146+
if [[ "$(cat .github/outputs/all_modified_files.json)" == "[]" ]]; then
147+
echo "any_changed=false" >> "$GITHUB_OUTPUT"
148+
else
149+
echo "any_changed=true" >> "$GITHUB_OUTPUT"
150+
fi
133151
134152
- name: Generate Coverage Delta Report
135153
id: delta

.github/workflows/on-push.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ on:
3232
workflow_dispatch: {} # Allow manual runs
3333

3434
permissions:
35-
actions: read
3635
contents: read
37-
id-token: write
38-
pull-requests: write
3936

4037
concurrency:
4138
group: ${{ github.workflow }}-${{ github.ref }}
@@ -47,6 +44,8 @@ jobs:
4744
name: Unit Tests
4845
runs-on: ubuntu-latest
4946
timeout-minutes: 15
47+
permissions:
48+
contents: read
5049
steps:
5150

5251
- name: Checkout Code
@@ -69,6 +68,8 @@ jobs:
6968
name: Integration Tests
7069
runs-on: ubuntu-latest
7170
timeout-minutes: 15
71+
permissions:
72+
contents: read
7273
steps:
7374

7475
- name: Checkout Code
@@ -87,6 +88,8 @@ jobs:
8788
name: E2E Tests
8889
runs-on: ubuntu-latest
8990
timeout-minutes: 30
91+
permissions:
92+
contents: read
9093
steps:
9194

9295
- name: Checkout Code

.github/workflows/on-tag.yaml

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,7 @@ on:
2020
- 'v[0-9]+.[0-9]+.[0-9]+' # Only build tags with semantic versioning format
2121

2222
permissions:
23-
actions: read
24-
attestations: write
25-
contents: write
26-
id-token: write
27-
packages: write
28-
pull-requests: write
29-
security-events: write
23+
contents: read
3024

3125
concurrency:
3226
group: ${{ github.workflow }}-${{ github.ref }}
@@ -42,6 +36,8 @@ jobs:
4236
name: Unit Tests
4337
runs-on: ubuntu-latest
4438
timeout-minutes: 15
39+
permissions:
40+
contents: read
4541
steps:
4642
- name: Checkout Code
4743
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -68,6 +64,8 @@ jobs:
6864
name: Integration Tests
6965
runs-on: ubuntu-latest
7066
timeout-minutes: 15
67+
permissions:
68+
contents: read
7169
steps:
7270
- name: Checkout Code
7371
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -85,6 +83,8 @@ jobs:
8583
name: E2E Tests
8684
runs-on: ubuntu-latest
8785
timeout-minutes: 30
86+
permissions:
87+
contents: read
8888
steps:
8989
- name: Checkout Code
9090
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -109,6 +109,11 @@ jobs:
109109
timeout-minutes: 30
110110
outputs:
111111
release_outcome: ${{ steps.release.outputs.release_outcome }}
112+
permissions:
113+
contents: write
114+
packages: write
115+
id-token: write
116+
attestations: write
112117
steps:
113118
- name: Checkout Code
114119
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -139,6 +144,10 @@ jobs:
139144
needs: [build]
140145
if: needs.build.outputs.release_outcome == 'success'
141146
timeout-minutes: 10
147+
permissions:
148+
contents: read
149+
id-token: write
150+
attestations: write
142151
steps:
143152
- name: Checkout Code
144153
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -177,6 +186,9 @@ jobs:
177186
runs-on: ubuntu-latest
178187
needs: [attest]
179188
timeout-minutes: 10
189+
permissions:
190+
contents: read
191+
id-token: write
180192
env:
181193
IDENTITY_PROVIDER: 'projects/116689922666/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider'
182194
SERVICE_ACCOUNT: 'github-actions'

.github/workflows/packaging.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: Packaging Check
16+
17+
on:
18+
push:
19+
branches:
20+
- main
21+
paths:
22+
- '.goreleaser.yaml'
23+
- '.goreleaser.yml'
24+
- '.github/workflows/packaging.yml'
25+
workflow_dispatch: {}
26+
27+
permissions:
28+
contents: read
29+
30+
jobs:
31+
package:
32+
name: Package (Dry Run)
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 15
35+
permissions:
36+
contents: read
37+
steps:
38+
- name: Checkout Code
39+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
40+
41+
- name: Load versions
42+
id: versions
43+
uses: ./.github/actions/load-versions
44+
45+
- name: Setup Go
46+
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
47+
with:
48+
go-version: ${{ steps.versions.outputs.go }}
49+
cache: true
50+
51+
- name: Setup GoReleaser
52+
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
53+
with:
54+
install-only: true
55+
56+
- name: GoReleaser Dry Run
57+
env:
58+
GORELEASER_CURRENT_TAG: v0.0.0
59+
run: |
60+
set -euo pipefail
61+
goreleaser release --snapshot --clean --skip=publish

.github/workflows/test-deploy.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ on:
2424

2525
permissions:
2626
contents: read
27-
id-token: write
28-
packages: read
2927

3028
jobs:
3129
deploy:
3230
name: Test Deploy
3331
runs-on: ubuntu-latest
3432
timeout-minutes: 10
33+
permissions:
34+
contents: read
35+
id-token: write
36+
packages: read
3537
env:
3638
IDENTITY_PROVIDER: 'projects/116689922666/locations/global/workloadIdentityPools/github-actions-pool/providers/github-actions-provider'
3739
SERVICE_ACCOUNT: 'github-actions'

0 commit comments

Comments
 (0)