Tighten CI security and remove dead code in workflows#7139
Conversation
Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
See https://docs.zizmor.sh/audits/\#template-injection Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
… config - Add explicit permissions blocks (workflow + job level, contents: read where possible) to build, cffconvert, docs, stale - stale job gets issues: write + pull-requests: write (only what actions/stale actually needs) - Move github.event.pusher.name/email out of the git config run script and into env vars to prevent shell injection via a malicious pusher Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
build.yml:
- Replace `${{ ... }}` template interpolation in `Get the commit message`
with env vars + `gh api` (was curl with token in template, also let
drift toward shell injection through the SHA/repo expansions)
- Drop two `env | sort` blocks and a `cat $HOME/.nextflow/scm` debug
line that printed a file containing NXF_GITHUB_ACCESS_TOKEN. GitHub
masks known secrets in logs but the protection is fragile
- Write GCP credentials to $RUNNER_TEMP instead of the workspace so they
cannot be accidentally captured by upload-artifact globs
- test-e2e: drop `actions: write` + `contents: write` (job uses
AUTOMATION_GITHUB_TOKEN against a different repo, touches nothing here)
- test-e2e: switch the COMMIT_MESSAGE env var to heredoc delimiter so
multi-line / quote-containing commit messages survive intact
- release: trim permissions to just `contents: write` (gh release create
is all the make targets need against this repo; Docker pushes go to
Docker Hub and Seqera CR, not ghcr.io)
- Workflow-level `concurrency:` so PR pushes cancel earlier runs
claude.yml:
- Drop `assigned` from issues trigger (the `if` clause never matched it
so every assign was burning a runner start)
- `concurrency:` keyed on issue/PR number
docs.yml:
- Bump Python from 3.9.25 (EOL branch) to 3.14
- Add pip cache via setup-python
- Workflow-level `concurrency:`
Signed-off-by: Phil Ewels <phil.ewels@seqera.io>
|
@ewels can you fix the merge conflicts? then I will merge it |
|
@copilot resolve the merge conflicts in this pull request |
Signed-off-by: GitHub <noreply@github.com> Co-authored-by: ewels <465550+ewels@users.noreply.github.com>
✅ Deploy Preview for nextflow-docs-staging canceled.
|
Merge conflicts resolved in 83e3634. |
|
@copilot careful - I think you added "persist-credentials: false" back to the build.yml workflow. But the credentials are needed for the script that pushes the release. This edit was reverted in the upstream PR and comments explaining why added. You just removed this in the merge conflict resolution I think. |
Agent-Logs-Url: https://github.com/nextflow-io/nextflow/sessions/1a776272-c3d0-4e84-995c-a05d51640328 Co-authored-by: ewels <465550+ewels@users.noreply.github.com>
Fixed in 5246adc — removed the |
|
Should be good now I think @bentsherman |
Follow-up to
#gha-updates(#7138) after a deeper pass throughbuild.yml,claude.yml,docs.yml. Driven by a manual security review on top of zizmor — no zizmor findings before or after, but the pass surfaced real issues zizmor doesn't catch: secret-dumping debug lines, dead permissions, a multi-line$GITHUB_ENVbug, and a trigger that fires the runner with no possible match.build.ymlenv | sort(×2) andcat $HOME/.nextflow/scm. GitHub's log masking is a fragile exact-string replace; dumping every env var orcating a file that containsNXF_GITHUB_ACCESS_TOKENis the pattern that leaked secrets in the March 2025tj-actions/changed-filesincident. Both looked like leftover debug.Get the commit message.${{ secrets.GITHUB_TOKEN }},${{ github.event.pull_request.head.sha }}and${{ github.repository }}moved intoenv:;curl + jqswapped forgh api(pre-installed, picks upGH_TOKENautomatically). Same shape as several recent supply-chain incidents — safe today only because GitHub controls every value.$RUNNER_TEMP. Were being written to$GITHUB_WORKSPACE, which an over-broadupload-artifactglob could exfiltrate by accident.$RUNNER_TEMPis outside the workspace and auto-cleaned.test-e2e→permissions: {}. Job dispatches a workflow inseqeralabs/showcase-automationviaAUTOMATION_GITHUB_TOKEN(separate PAT) and touches nothing here. Previousactions: write+contents: writeon the default token were dead.COMMIT_MESSAGEin$GITHUB_ENV. Old form embedded literal quotes into the value and broke on multi-line /"-containing messages. Latent rather than blocking (run.sh just greps for[e2e prod]) but worth fixing.releasepermissions →contents: writeonly. Wasactions/contents/packages/pull-requests/issues: write. Verified by grepping*.gradle/*.sh/Makefileforghcr.io,gh issue,gh pr,gh workflow— only hit isgh release create/upload. Docker pushes go to Docker Hub andpublic.cr.seqera.io, notghcr.io.concurrency:. Cancels in-flightpull_requestruns on new pushes;master/STABLE-*/test*/dev*are never cancelled so a partial release can't be aborted.claude.ymlassignedfromissues:trigger. Theifclause only checks@claudeinissue.body, so every assignment was starting a runner just to skip.concurrency:keyed on issue/PR number. Multiple@claudementions on the same thread queue rather than race.docs.yml3.9.25→3.14. Renovate had us on a near-EOL branch; no docs-specific reason to stay.cache: 'pip'withcache-dependency-path: docs/requirements.txt. ~30s/PR.concurrency:.