ci: harden workflow token permissions and add CodeQL analysis - #145
ci: harden workflow token permissions and add CodeQL analysis#145mgarbs wants to merge 1 commit into
Conversation
Declare a read-only top-level permissions block in every workflow and move write scopes to the jobs that use them, add a CodeQL workflow, and replace the unpinned npm install in the PR label check with npm ci. - release.yml: top-level actions/checks/contents/id-token/issues/ pull-requests/packages write replaced by contents: read; each job now declares only the scopes its steps use (dispatch-rc: actions+contents write; create-github-release: contents/issues/pull-requests write; create-snapshot-pr: contents/pull-requests write; publish-npm-package: id-token/packages write) - tests.yml, manual-testing.yml: checks: write and pull-requests: write moved from the top level to each job calling test-workflow.yml and to PublishResults; effective job permissions are unchanged - pr-label-milestone-check.yml: add the missing permissions block (contents: read top level, issues/pull-requests read on the job) and use npm ci --omit=dev instead of npm install axios - add .github/workflows/codeql.yml (actions + javascript-typescript, build-mode none) on pull_request, push to main/release/** and weekly Scorecard checks affected: Token-Permissions (0 -> 10), SAST (0 -> 10 locally), Pinned-Dependencies (8 -> 9). Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
|
Some context on the intent behind this PR: it's part of a coordinated effort to raise the OpenSSF Scorecard scores across the hiero-ledger org. Scorecard is an automated 0–10 rating of a repository's supply-chain security practices — workflow token permissions, dependency pinning, SAST coverage, committed binaries, fuzzing, and similar checks — and it's what the org's security dashboard tracks. The checks this PR moves (measured with |
Description:
Harden the GitHub Actions workflows so the repository scores well on the OpenSSF Scorecard
Token-Permissions,SASTandPinned-Dependencieschecks, without changing what any job is able to do.permissionsblock in every workflow and move write scopes down to the jobs that use themactions+javascript-typescript) that runs on pull requests, pushes tomain/release/**and weeklynpm install axiosin the PR label/milestone check withnpm ci --omit=dev(axios is already a dependency inpackage.json/package-lock.json)Changes by Scorecard check
Token-Permissions
release.yml: the top-level block grantedactions,checks,contents,id-token,issues,pull-requestsandpackages: writeto every job. It is nowcontents: readat the top level and each job gets only what its steps use:dispatch-rc→actions: write,contents: write(creates therc/*branch and re-dispatches the workflow)prepare-release→contents: read(semantic-release dry run)create-github-release→contents: write,issues: write,pull-requests: write(semantic-release publish, milestone close)create-snapshot-pr→contents: write,pull-requests: write(peter-evans/create-pull-request)publish-npm-package→id-token: write(npm provenance),packages: write,contents: readchecks: writewas not used by any job in this workflow and is not re-granted.tests.yml/manual-testing.yml: top level is nowcontents: read;checks: write+pull-requests: writeare granted per job (each caller of the reusabletest-workflow.yml, andPublishResults). The called workflow already declares the same job-level scopes, so the effective permissions of every job are unchanged.pr-label-milestone-check.yml: had nopermissionsblock at all (defaulted to the repository-wide token). Nowcontents: readat the top level andissues: read+pull-requests: readon the job, which is allcheck-pr.jsneeds (it only performs GET requests).code-quality-check.yml,flow-pr-title-check.ymlandtest-workflow.ymlalready followed this pattern and are untouched.SAST
.github/workflows/codeql.yml, pinned togithub/codeql-action@v4.37.9, using the samehl-contr-lin-mdrunner,step-security/harden-runnerandactions/checkoutpins as the other PR checks. Solidity is not a CodeQL-supported language, so the matrix coversactions(the workflow files themselves) andjavascript-typescript(tests, scripts and config), both withbuild-mode: none.Pinned-Dependencies
pr-label-milestone-check.yml:npm install axios→npm ci --omit=dev, so the install is driven by the committed lockfile.scorecard --local)Intentionally not changed
release.ymlinstallssemantic-releaseand its plugins withnpm install --no-save …@<version>intocontracts/, where there is no lockfile. Scorecard still flags these two commands; converting them would mean adding a lockfile for the release tooling, which is out of scope here.solonetwork and is invoked with--grepfilters in CI, so a standalone property test would not fit the current runner setup.Related issue(s):
None
Notes for reviewer:
actionlinton every touched workflow (only the pre-existing self-hosted runner-label andrelease.ymlshellcheck notes remain, identical tomain);scorecard --local . --checks Token-Permissions,Pinned-Dependencies,Binary-Artifacts,Dangerous-Workflow,SASTbefore/after (table above);npm ci --omit=devagainst the committedpackage-lock.jsoninstallsaxiosin ~1s.secrets.GH_ACCESS_TOKENfor checkout, git push,gh workflow run, semantic-release andcreate-pull-request, so the per-jobGITHUB_TOKENscopes mostly matter forid-token: write(npm provenance) and as a safety net. If a job is found to need an additional scope it can be added at the job level without affecting the Scorecard result.hl-contr-lin-md.Checklist