Repository navigation
ci: harden GitHub Actions workflows against Scorecard and CodeQL alerts - #463
Conversation
Scorecard's Pinned-Dependencies check flags each action referenced by a tag or branch, because the owner can move the tag to new code. Each one now names the commit its tag pointed to on 2026-10-26, with the exact version in a comment. Dependabot updates the SHA and the comment together. The floating tags resolve as follows: setup-python v7 is v7.1.0, download-artifact v8 is v8.0.2, configure-pages v6 is v6.0.0, upload-pages-artifact v5 is v5.0.0, deploy-pages v5 is v5.0.1, and pypi-publish release/v1 is v1.14.3. No workflow runs different code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eight workflows had no permissions block, so their token took the repository default. Scorecard's Token-Permissions and CodeQL's missing-workflow-permissions flag that. Each one now sets a top-level block that its jobs inherit, unless a job sets its own: - format, docs, main, pre-release, release and test-release read contents only. The publish jobs keep their own id-token block. - bump-version gets an empty top-level block. Its job keeps contents and pull-requests write, since it pushes a branch and opens a PR. - pr-compliance gets an empty top-level block, and its job gets pull-requests write. The reminder action only calls the API: it lists the PR's files and adds or deletes its comment. The pr-compliance job also drops its actions/checkout step. The action reads no files, so the checkout did nothing. Under pull_request_target a checkout with a write token is the risky pattern, so removing it also removes the need for contents access. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scorecard flags every pip install that does not check hashes. The format, gh-pages and bump-version workflows now install from lock files in .github/requirements/, with --require-hashes: - tox.txt locks tox for format and gh-pages. - bump-version.txt locks qbraid-core and pyyaml. These jobs hold a write token: gh-pages has pages and id-token write, and bump-version has contents write. docs.yml stays unlocked. It runs with a read-only token and no secrets, so a lock there costs upkeep and protects little. Each .txt file is compiled from the .in file with the same name. Its first lines give the uv pip compile command that rebuilds it. The locks are universal, from Python 3.10 up, because gh-pages runs on the newest Python 3. A new Dependabot uv entry updates them in one grouped weekly PR. .gitattributes marks them as generated, so GitHub collapses them in diffs. The pip self-upgrades go away, since they were unpinned installs too. In main.yml, `pip install setuptools` did nothing: Python 3.11 from setup-python already ships setuptools, and no test or script imports it. This also fixes a shell bug. `pip install tox>=4.2.0` without quotes sent pip's output to a file named `=4.2.0` and installed any tox version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tool venv in publish-lab-env.yml now installs qbraid-cli 0.16.10 and qbraid-core 0.6.27 from .github/requirements/lab-env-tools.txt, with --require-hashes. The two versions moved from the QBRAID_CLI_VERSION and QBRAID_CORE_VERSION variables into lab-env-tools.in. The other dependencies are now locked too, and PIP_ONLY_BINARY still applies. Dependabot now proposes new qbraid-cli and qbraid-core versions in the grouped weekly PR. Before, they changed only by hand. qbraid-core does the upload path rewriting, so check a bump of it with a staging run before the next production publish. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Argus reviewAuto-review is off for this repo. Tick the box below to run a review on this PR. Running Argus review... Estimated cost
Tip: you can also comment |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
f96e0f8 to
1eaf624
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Argus · 9/10 — Wrong ecosystem for compiled requirements
Check 1 warning before you merge. Argus reviewed 19 files.
- 🟡 Warning · Wrong ecosystem for compiled requirements ·
.github/dependabot.yml:L16
What this PR does · 16 author checks
- Fix 79 of 81 workflow code scanning alerts from Scorecard and CodeQL without changing workflow behavior beyond the listed behavior changes.
- Excludes: Shell-script alerts in bin/ and the 5 repository-level alerts are out of scope.
- Excludes: Removing contents: write from bump-version.yml requires a GitHub App token or PAT and is not included.
Author's checks
- 79 of the 81 workflow alert locations are fixed; the identified bump-version.yml and docs.yml alerts remain.
- Every uses: reference names a commit SHA matching its original tag, with the version in a comment.
- format, docs, main, pre-release, release and test-release declare contents: read; publish jobs retain their id-token permissions.
- bump-version and pr-compliance declare empty top-level permissions blocks, with job-specific permissions.
- Jobs holding a write token or secret install Python tools from the specified lock files with --require-hashes.
- Each requirements .txt is compiled from its same-named .in file using uv pip compile, with the command in its header.
- Dependabot has a uv entry updating the requirements in one grouped weekly PR.
- .gitattributes marks the requirements lock files as generated.
- pr-compliance.yml does not check out the repository, and its changelog reminder job has only pull-requests: write.
- Remove pip install --upgrade pip lines and main.yml's pip install setuptools.
- Fix the unquoted pip install tox>=4.2.0 shell redirection bug in format and gh-pages.
- publish-lab-env.yml reads qbraid-cli 0.16.10 and qbraid-core 0.6.27 pins from lab-env-tools.in rather than environment variables.
- All workflows parse and actionlint reports no findings.
- tox.txt installs with --require-hashes on Python 3.10, 3.11 and 3.14; bump-version.txt installs on Python 3.11.
- lab-env-tools.txt installs with --require-hashes on Python 3.12 with PIP_ONLY_BINARY=:all:.
- Each lock resolves for x86_64-manylinux_2_28.
⚠️ This PR exceeds reviewable size — findings carry reduced confidence. Consider splitting it into smaller PRs.
usage: 233.7k tokens · 4 stages
Contract: config/full · checked: single-pass review · review took 57s
| Stage | Model | Tokens | Cost |
|---|---|---|---|
| Intent | openai/gpt-6.1-sol |
7.5k | $0.0151 |
| Triage | openai/gpt-6.1-sol |
35.7k | $0.0374 |
| Review | openai/gpt-6.1-sol |
188.3k | $0.3900 |
| Scoring | openai/gpt-6.1-sol |
2.1k | $0.0032 |
Note
1929 lines changed, over the full-review limit of 1500 — reviewing at reduced depth
Dashboard → · React 👎 on an inline comment to dismiss it · Reply to an inline comment or use @argus-eye help
🧠 Learned: 1 PR summary · 1 finding memory · 1 file memory · 1 architecture note
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Merging after argus review was passed. |
#465) * ci(lab-env): set minimum versions in lab-env-tools.in so Dependabot can update it Dependabot's first weekly uv update after #463 failed with "No solution found". lab-env-tools.in pinned qbraid-cli==0.16.10 and qbraid-core==0.6.27 exactly, and Dependabot raises one package at a time: - qbraid-cli 0.16.16 needs qbraid-core>=0.6.35, which the exact core pin forbids. - Dependabot treats the qbraid-core in bump-version.in as the same package. Raising it to 0.6.36 collided with the ==0.6.27 pin here. The .in file now sets minimum versions only. The exact versions stay in lab-env-tools.txt, which the workflow installs, and rebuilding it gives a byte-identical file. A run of the same uv pip compile -P commands Dependabot used now resolves, to qbraid-cli 0.16.16 and qbraid-core 0.6.37. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(changelog): note the lab-env-tools.in minimum versions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary of changes
Fixes 79 of the 81 open code scanning alerts on
.github/workflows/*.yml. These come from OpenSSF Scorecard (Pinned-Dependencies, Token-Permissions) and CodeQL (actions/missing-workflow-permissions). The aim is to change no workflow behavior beyond the items listed under "Behavior changes".Action pins. Every
uses:now names a commit SHA, with the version in a comment. Each SHA is the commit its tag pointed to, so no workflow runs different code. Dependabot updates the SHA and the comment together.Token permissions. The 8 workflows with no
permissionsblock now declare one:format,docs,main,pre-release,releaseandtest-releaseread contents only. The publish jobs keep their ownid-tokenblock.bump-versionandpr-complianceget an empty top-level block. Each job asks only for what it uses.Hash-locked installs. Jobs that hold a write token or a secret now install their Python tools with
--require-hashes:tox.txtis used byformatandgh-pages.bump-version.txtis used bybump-version.lab-env-tools.txtis used bypublish-lab-env.These files live in
.github/requirements/. Each.txtis compiled withuv pip compilefrom the.infile of the same name, and its header gives the command. A new Dependabotuventry updates them in one grouped weekly PR..gitattributesmarks them as generated, so GitHub collapses them in diffs.Behavior changes
pr-compliance.ymlno longer checks out the repository. The changelog reminder only calls the GitHub API, so the checkout did nothing. Its job now haspull-requests: writeonly.pip install --upgrade piplines are removed. Inmain.yml,pip install setuptoolsis removed too: Python 3.11 already ships it, and nothing imports it.formatandgh-pages.pip install tox>=4.2.0without quotes sent pip's output to a file named=4.2.0.publish-lab-env.ymlreads the qbraid-cli 0.16.10 and qbraid-core 0.6.27 pins fromlab-env-tools.ininstead of env vars. Dependabot will now propose bumps for both. Check a qbraid-core bump with a staging run before a production publish.Alerts left open
Both should be dismissed with these reasons:
bump-version.yml:20: the job needscontents: writeto push its branch. Removing it needs a GitHub App token or a PAT.docs.yml:24:pip install -e '.[docs]'stays unlocked. The job has a read-only token and no secrets, so a lock costs upkeep for little gain.The shell-script alerts in
bin/and the 5 repository-level alerts are out of scope.Validation
actionlintreports nothing.pip --require-hashes:tox.txton Python 3.10, 3.11 and 3.14.bump-version.txton 3.11.lab-env-tools.txton 3.12 withPIP_ONLY_BINARY=:all:.x86_64-manylinux_2_28.No workflow has run with these changes yet. This PR's own checks test
main,format,docsandpr-compliance. The release workflows first run at the next release. A manualtest-release.ymlrun after merge would test the publish path.