CodeQL's first run flagged seven instances of one rule, actions/missing-workflow-permissions, all medium:
.github/workflows/test.yml:29, :117, :152
.github/workflows/test-examples.yml:23, :53
.github/workflows/starters.yml:24
.github/workflows/nightly.yml:10
Four workflows with no permissions: block anywhere, so every job in them runs with whatever the repository default grants rather than with what the job actually needs.
This repo already has the convention
Four of the eight workflows declare it, and they are the four that touch anything:
| workflow |
permissions |
release.yml |
contents: write, id-token: write, actions: read |
pr-title.yml |
pull-requests: read |
stale.yml |
issues: write |
cleanup-caches.yml |
actions: write |
release.yml even carries the note explaining the sharp edge, from #192:
An explicit block sets every scope it omits to none, so this has to be named.
So this is not a new practice to introduce — it is four workflows that never got the treatment the other four did. The four missing it are exactly the ones that only build and test, which is why nobody noticed.
What they need
All four are pure build-and-test: check out, install, run a suite. None comment on a PR, push a tag, write a cache, or read the API. contents: read at the top level of each file should cover all of them.
That is the claim to verify rather than assume. The failure mode is real and this repo has already hit it once — an explicit block silences every scope it does not name, so a job quietly using a token scope it never declared fails only when it runs. starters.yml is the one to look at hardest: it runs on a schedule, so a mistake there surfaces on a nightly nobody is watching rather than on a PR.
Why it is worth doing rather than dismissing
Not because a build job is likely to be exploited. Because the default is invisible and the explicit block is not: right now the answer to "what can test.yml do with its token?" is "whatever the repo setting says today", and that setting is somewhere else and can change without a commit. The other four workflows already answer that question in the file.
It also clears the entire actions half of the code scanning results, which matters while the alert list is still small enough to read. Seven identical medium alerts sitting open is how a list becomes something people scroll past.
Not in scope
The ten javascript-typescript alerts from the same run are real findings in product source (js/incomplete-sanitization, js/polynomial-redos, js/bad-code-sanitization) and want separate triage — they are not workflow configuration and should not ride along with a one-line-per-file change.
Related: #385 (the settings that produced these), #192 (where the omitted-scope note came from).
CodeQL's first run flagged seven instances of one rule,
actions/missing-workflow-permissions, all medium:Four workflows with no
permissions:block anywhere, so every job in them runs with whatever the repository default grants rather than with what the job actually needs.This repo already has the convention
Four of the eight workflows declare it, and they are the four that touch anything:
release.ymlcontents: write,id-token: write,actions: readpr-title.ymlpull-requests: readstale.ymlissues: writecleanup-caches.ymlactions: writerelease.ymleven carries the note explaining the sharp edge, from #192:So this is not a new practice to introduce — it is four workflows that never got the treatment the other four did. The four missing it are exactly the ones that only build and test, which is why nobody noticed.
What they need
All four are pure build-and-test: check out, install, run a suite. None comment on a PR, push a tag, write a cache, or read the API.
contents: readat the top level of each file should cover all of them.That is the claim to verify rather than assume. The failure mode is real and this repo has already hit it once — an explicit block silences every scope it does not name, so a job quietly using a token scope it never declared fails only when it runs.
starters.ymlis the one to look at hardest: it runs on a schedule, so a mistake there surfaces on a nightly nobody is watching rather than on a PR.Why it is worth doing rather than dismissing
Not because a build job is likely to be exploited. Because the default is invisible and the explicit block is not: right now the answer to "what can
test.ymldo with its token?" is "whatever the repo setting says today", and that setting is somewhere else and can change without a commit. The other four workflows already answer that question in the file.It also clears the entire
actionshalf of the code scanning results, which matters while the alert list is still small enough to read. Seven identical medium alerts sitting open is how a list becomes something people scroll past.Not in scope
The ten
javascript-typescriptalerts from the same run are real findings in product source (js/incomplete-sanitization,js/polynomial-redos,js/bad-code-sanitization) and want separate triage — they are not workflow configuration and should not ride along with a one-line-per-file change.Related: #385 (the settings that produced these), #192 (where the omitted-scope note came from).