Skip to content

Commit 3cf1937

Browse files
authored
fix(ci): scope nightly.yaml writes to per-job permissions (#929)
Top-level `permissions: { contents: write, packages: write, id-token: write }` on nightly.yaml granted every job in the workflow the union of all writes any one job needed, including jobs that only consume read-only inputs. The Scorecard `TokenPermissionsID` rule flags this as the most severe form of over-grant because top-level writes propagate to every reuse-called workflow as the upper bound. Drop the top-level to `contents: read` and raise per-job only where the job actually writes: - build: contents: read, packages: write (forwarded to _build.yaml for NuGet/vcpkg writes to ghcr.io via VCPKG_BINARY_SOURCES=...readwrite) - cleanup-prereleases: contents: write (git push origin --delete <tag> and gh release delete; the tag deletion requires repo write) - prerelease: contents: write, id-token: write (forwarded to _release.yaml for tag push + gh release create + Sigstore keyless signing) - docker: contents: read, packages: write (forwarded to _docker.yaml for ghcr image push; matches release.yaml's docker job pattern) - init: no override, inherits top-level read (_init.yaml is read-only — extracts versions from package.json via jq and stamps github.sha) The grants mirror the canonical pattern already in place in release.yaml (committed in the prior TokenPermissionsID cleanup pass that closed #513 and #515 on _build.yaml and _init.yaml). Closes Scorecard TokenPermissionsID alerts #566 (topLevel contents:write) and #567 (topLevel packages:write). The remaining 10 TokenPermissionsID alerts on this repo (#451, #452, #454, #455, #489, #490, #604, #635, #649, #650) flag job-level writes that are required for the job's function (ghcr image push, GitHub release publish, artifact cleanup, model-sync commits). Those are being dismissed separately with "won't fix" + per-alert justification — Scorecard penalizes any write, including the unavoidable kind.
1 parent f007209 commit 3cf1937

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

.github/workflows/nightly.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ concurrency:
99
group: nightly
1010
cancel-in-progress: true
1111

12+
# Top-level least-privilege. Individual jobs below raise to write only
13+
# where they actually need it (image push, tag/release publish, prerelease
14+
# cleanup). Closes Scorecard TokenPermissionsID #566 and #567.
1215
permissions:
13-
contents: write
14-
packages: write
15-
id-token: write
16+
contents: read
1617

1718
# Triggered when develop's CI run completes successfully — this is the
1819
# gate. A red CI on develop (whether from a bad merge, a flaky test, or
@@ -83,6 +84,9 @@ jobs:
8384
name: Build
8485
needs: init
8586
uses: ./.github/workflows/_build.yaml
87+
permissions:
88+
contents: read
89+
packages: write
8690
with:
8791
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
8892
full_version: ${{ needs.init.outputs.full_server_version }}
@@ -97,6 +101,8 @@ jobs:
97101
name: Clean up prereleases
98102
needs: build
99103
runs-on: ubuntu-latest
104+
permissions:
105+
contents: write
100106
steps:
101107
- name: Check out repository
102108
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
@@ -130,6 +136,9 @@ jobs:
130136
name: Prerelease
131137
needs: [init, build, cleanup-prereleases]
132138
uses: ./.github/workflows/_release.yaml
139+
permissions:
140+
contents: write
141+
id-token: write
133142
with:
134143
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
135144
prerelease: true
@@ -144,6 +153,9 @@ jobs:
144153
name: Docker
145154
needs: [init, build]
146155
uses: ./.github/workflows/_docker.yaml
156+
permissions:
157+
contents: read
158+
packages: write
147159
with:
148160
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
149161
server_version: ${{ needs.init.outputs.server_version }}

0 commit comments

Comments
 (0)