ci: add OpenSSF Scorecard workflow - #412
Conversation
Argus reviewAuto-review is off for this repo. Tick the box below to run a review on this PR.
Estimated cost
Tip: you can also comment |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
| # Lets Scorecard read workflow definitions and run history. Documented by the | ||
| # upstream starter workflow as required for private repositories; this repo is | ||
| # public, so it is retained only as a safeguard should that ever change. | ||
| actions: read |
There was a problem hiding this comment.
Is this needed? As per the comment, it is present only as a safeguard if we choose to make pyqasm private , which might not be happening.
There was a problem hiding this comment.
You're right, and it goes one line further than you flagged — contents: read has exactly the same status. Both removed in dd81908.
I dug through the OpenSSF sources rather than reason from the comment, since my own justification for the line turned out to be the weak part. Evidence, strongest last:
1. The endpoint Scorecard needs is publicly readable. Its only Actions API call is ListWorkflowRunsByFileName (checks/raw/github/packaging.go, checks/raw/binary_artifact.go), hitting GET /repos/{owner}/{repo}/actions/workflows/{file}/runs. Requesting that with no authentication at all returns 200; /user returned 401 in the same session, so the request really was anonymous. A token cannot have less access than anonymous on a public repo.
2. Upstream ships both commented out. actions/starter-workflows code-scanning/scorecard.yml:
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: readSo my comment's premise was right — private-repo only — and the conclusion I drew from it was wrong. Keeping it "as a safeguard" just meant carrying a permission that does nothing, which is what a least-privilege review should strip.
3. OSSF dogfoods it. ossf/scorecard and ossf/scorecard-action are both public and run with security-events: write and id-token: write alone. Last five runs green, and the checks that touch the Actions API score Packaging 10, Binary-Artifacts 10, CI-Tests 10. That is also what justifies dropping contents: read — their actions/checkout works without it.
Residual risk, stated plainly: both affected checks return an error rather than degrading if the call fails, so a mistake here surfaces as a check erroring, not as a silently lower score. The same workflow has already run green on qBraid and qbraid-algorithms with the wider permissions, giving a baseline to compare the next run against.
Same change: qBraid/qBraid#1354 and qBraid/qbraid-algorithms#97 (both merged their scorecard PRs before this came up, so they needed follow-ups).
TheGupta2012
left a comment
There was a problem hiding this comment.
@ryanhill1 looks good, just one comment regarding permissions
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Haven't tested it 'cause we'll need it to be merged to |
Both are private-repository permissions and this repo is public. The only Actions API call Scorecard makes is ListWorkflowRunsByFileName, from the Packaging and Binary-Artifacts checks. That endpoint is publicly readable: requesting it for a public repo with no authentication at all returns 200. Upstream's starter workflow ships `contents: read` and `actions: read` commented out under "uncomment if installing in a private repository", and OSSF runs Scorecard on its own public repos -- ossf/scorecard and ossf/scorecard-action -- with `security-events: write` and `id-token: write` alone. Those runs are green and score Packaging 10, Binary-Artifacts 10 and CI-Tests 10, which is the same evidence for dropping `contents: read`: their checkout step works without it.
Both are private-repository permissions and this repo is public. The only Actions API call Scorecard makes is ListWorkflowRunsByFileName, from the Packaging and Binary-Artifacts checks. That endpoint is publicly readable: requesting it for a public repo with no authentication at all returns 200. Upstream's starter workflow ships `contents: read` and `actions: read` commented out under "uncomment if installing in a private repository", and OSSF runs Scorecard on its own public repos -- ossf/scorecard and ossf/scorecard-action -- with `security-events: write` and `id-token: write` alone. Those runs are green and score Packaging 10, Binary-Artifacts 10 and CI-Tests 10, which is the same evidence for dropping `contents: read`: their checkout step works without it. Follows #94, which merged before this was raised in review on qBraid/pyqasm#412.
Adds the OpenSSF Scorecard workflow, copied verbatim from
qbraid-algorithms, where itis already running and publishing a score to the public Scorecard API.
Scorecard grades a repository against supply-chain practices — branch protection, pinned
dependencies, token permissions, publishing provenance, code review — and publishes the
result at
api.securityscorecards.dev, where anyone can look it up. The value is that athird party computes the number rather than us.
Notes on the workflow itself, carried over from the original:
repointed at other code, and that is exactly what Scorecard's own Pinned-Dependencies
check looks for.
permissions: {}means a job added later starts with nothing until itdeclares what it needs.
concurrencycancels superseded runs, since Scorecard reports current repositorystate and an outdated run has nothing to add.
Results upload to code scanning as SARIF and to the public API. No secrets are required;
id-token: writeis what lets the run publish under the repository's identity.