chore(ci): add least-privilege permissions to build.yml and checks.yml - #8053
chore(ci): add least-privilege permissions to build.yml and checks.yml#8053yhabib wants to merge 1 commit into
Conversation
Both workflows declared no permissions key. Each job held the repository default GITHUB_TOKEN, which is read and write. Set contents: read at workflow level in both files. Raise the two jobs that publish a release to contents: write. Give small-tests actions: read for download-ci-wasm.test.
|
✅ No security or compliance issues detected. Reviewed everything up to 6fdf16f. Security Overview
Detected Code Changes
|
There was a problem hiding this comment.
🟡 Changes recommended
The new workflow-level permissions drop actions scope to none, but both workflows still use Actions APIs (cache and artifacts), which will likely cause CI authorization failures unless actions permissions are granted appropriately.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR tightens GitHub Actions least-privilege usage by explicitly setting GITHUB_TOKEN permissions in the always-on build.yml and checks.yml workflows instead of relying on the repository default read/write token.
Changes:
- Added workflow-level
permissions: contents: readto bothbuild.ymlandchecks.yml. - Added job-level
contents: writetotest-restandassetsinbuild.ymlfor release-related operations. - Added job-level
actions: readtosmall-testsinchecks.ymlforgh run ...usage.
File summaries
| File | Description |
|---|---|
| .github/workflows/checks.yml | Adds workflow/job permission blocks to reduce default token privileges. |
| .github/workflows/build.yml | Adds workflow/job permission blocks to scope write access to release-producing jobs. |
Review details
Suppressed comments (1)
.github/workflows/build.yml:477
- This job defines a job-level
permissionsblock, which overrides workflow-level permissions. The job uses bothactions/download-artifactandactions/upload-artifact, so it needsactions: writein addition tocontents: write.
permissions:
# The Release step creates a GitHub release. A later step pushes the
# refs/notes/mainnet/wasm-sha note.
contents: write
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
About the suppressed comment on |
There was a problem hiding this comment.
🟢 Approved
The permission changes are minimal, scoped to the documented jobs/steps that require them, and align with least-privilege without altering any workflow behavior beyond token scopes.
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
- Review effort level: Lite
Motivation
build.ymlandchecks.ymlrun on every push and declare nopermissions:key, so every job holds the repository defaultGITHUB_TOKEN, which is read and write.Most jobs only read the checkout. Proof that a write token on every push is a real risk:
nightly.yamlpushes a tag with the default token and nopermissions:block, andgit ls-remote --tags origin 'nightly-2026-09*'lists a tag for every day.Changes
permissions: contents: readblock tobuild.ymlandchecks.yml.test-restandassetsinbuild.ymltocontents: write, because theirReleasesteps callgh release create,gh release uploadandgh release edit.small-testsinchecks.ymltocontents: readplusactions: read, because its CI wasm download step callsgh run list,gh run downloadandgh run view --log.Tests
./scripts/fmt-yaml --checkexits 0.yqconfirms the workflow-level block iscontents: readin both files, and that onlytest-rest,assetsandsmall-testscarry a job-level block.git diff -U0againstmainshows only addedpermissions:lines and comments. Norun:step changed.actionlint(not in this repo, downloaded 1.7.7 to check) against both files onmainand on this branch. The finding sets are identical, so the new blocks add no schema warning.The permissions block only takes effect on a real GitHub Actions run, so this PR itself is the remaining proof. Two things stay open until CI runs here:
build.ymlandchecks.ymlmust go green, includingsmall-testson bothubuntu-24.04andmacos-15-intel, andassets.contents: writerelease path needs a tag pushed to this branch head, so a draft release gets created and then deleted as a throwaway check.Todos
Releasesteps create a draft release. The next stage checks this.