Add govulncheck CI job, Dependabot, and raise Go toolchain to 1.26.7 - #131
Merged
Conversation
CI built, vetted, tested, and linted but never scanned the Go toolchain or module dependencies for known vulnerabilities, and no Dependabot config existed to keep SHA-pinned Actions or gopkg.in/yaml.v3 current (the sonarqube job's dependabot[bot] guard was already prepared for Dependabot, but the config was never committed). Add a govulncheck job (reachability-based, so noise is low) that runs on every push/PR plus a weekly schedule so a newly-published CVE against an unchanged codebase gets caught without waiting for the next commit. Add .github/dependabot.yml for the github-actions and gomod ecosystems. Document both in ARCHITECTURE.md's CI summary and add govulncheck to CONTRIBUTING.md's pre-PR checklist.
SonarCloud's Quality Gate failed the PR with a MAJOR security finding (githubactions:S8545, "Dependency versions are not predictable") on the "go install ...@latest" line: an unpinned/floating dependency install in CI is a supply-chain risk, the same class of issue the repo's SHA-pinned Actions already guard against. Pin to v1.7.0 (the version @latest resolved to) instead. The vulnerability database itself is fetched fresh over the network at scan time regardless of the installed tool's version, so this keeps the main benefit (current CVE data) while making the build reproducible.
Go 1.22 fell out of the two-most-recent-majors support window, so it
receives no further security patches. Since PiMonitor ships as a
single statically-linked binary with the standard library baked in,
the toolchain version is a dependency-security property: the new
govulncheck CI job (added alongside this) found 31 real, reachable
CVEs in net/http, crypto/tls, crypto/x509, net/url and others that are
only fixed in Go 1.23-1.25 — none of them fixable by updating
gopkg.in/yaml.v3, since they're in the standard library itself.
Go 1.26.7 is the newest patch of the older of the two currently
supported majors (1.26 and 1.27), verified against the Go module
proxy's toolchain list. No language features were adopted opportunistically;
this is a mechanical version bump per docs/CONTRIBUTING.md's now-documented
policy of tracking a supported release.
golangci-lint v2.12.2 was built with Go 1.25 and refuses to lint a
go.mod targeting a newer Go version ("the Go language version used to
build golangci-lint is lower than the targeted Go version"), so it is
bumped to v2.13.1 (built with Go 1.26.7) to match, as anticipated by
issue #107.
Closes #107.
SonarCloud's Quality Gate still failed after pinning to
"go install .../govulncheck@v1.7.0" (githubactions:S8545, "Dependency
versions are not predictable. Use a lock-file enforcing command
instead."): the rule flags any `go install pkg@version` in CI
regardless of pinning, since it isn't verified against this repo's own
go.sum.
Go 1.24+ (available now that go.mod targets 1.26.7) supports `tool`
dependencies: `go get -tool golang.org/x/vuln/cmd/govulncheck@v1.7.0`
records it under a `tool` directive with a real go.sum-checksummed
require entry, and `go tool govulncheck ./...` runs that exact,
verified build - a genuine lock-file-enforcing command. This also
means Dependabot's gomod ecosystem can now track and bump govulncheck
automatically, closing the gap the original issue noted ("it must be a
tool dependency, which this project does not otherwise have").
The added golang.org/x/vuln/x/tools/x/mod/etc. requires are tool-only:
`go list -deps ./cmd/pimonitor` confirms none of them reach the
shipped binary.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



📖 Description
CI built, vetted, tested, and linted, but nothing scanned the Go toolchain or module dependencies for known vulnerabilities, and
.github/dependabot.ymldidn't exist — even though thesonarqubejob already carried agithub.actor != 'dependabot[bot]'guard clearly written in anticipation of Dependabot being enabled.This PR started as #106 alone, then grew to include its companion #107 once CI showed why the two were meant to be done together (see "How this PR grew" below).
Part 1 — CI vulnerability scanning + Dependabot (#106):
govulncheckjob to.github/workflows/ci.ymlthat runsgo tool govulncheck ./...on every push/PR tomain, plus a weekly schedule (0 6 * * 1) so a newly-published CVE against an unchanged codebase is surfaced without waiting for the next commit.govulncheckdoes reachability analysis, so false-positive noise is low.govulncheckis installed as a go.mod tool dependency (go get -tool golang.org/x/vuln/cmd/govulncheck@v1.7.0, Go 1.24+), notgo install ...@latest/@version— see "How this PR grew" for why. This also means Dependabot'sgomodecosystem tracks and bumps it automatically..github/dependabot.ymlwith two ecosystems:github-actions(keeps the existing SHA pins moving forward) andgomod(keepsgopkg.in/yaml.v3and nowgolang.org/x/vulncurrent), both weekly.docs/ARCHITECTURE.md's CI summary anddocs/CONTRIBUTING.md's pre-PR checklist.Part 2 — Raise the Go toolchain (#107):
go.mod'sgo 1.22directive raised togo 1.26.7— Go 1.22 fell out of the two-most-recent-majors support window (currently 1.26 and 1.27, verified against the Go module proxy's toolchain list), so it receives no further security patches. Since PiMonitor ships as a single statically-linked binary, this is a dependency-security property, not just a build detail. It also happens to be what unlocks thetooldirective mechanism used in Part 1 (Go 1.24+).golangci-lintbumped fromv2.12.2tov2.13.1in CI anddocs/CONTRIBUTING.md: v2.12.2 was built with Go 1.25 and refuses to lint ago.modtargeting a newer Go version, so this was necessary to keepmake lintworking — anticipated in go.mod targets Go 1.22, which no longer receives upstream security fixes #107's own checklist.README.mdanddocs/CONTRIBUTING.md, and added a policy note todocs/CONTRIBUTING.mdexplaining thegodirective tracks a supported release going forward, so this doesn't silently recur.go list -deps ./cmd/pimonitorconfirms none of the new tool-only requires (golang.org/x/vuln,x/tools,x/mod, etc.) reach the shipped binary — they exist purely forgo tool govulncheck.How this PR grew from #106 to also include #107
I initially opened this PR scoped to #106 only. CI then failed on three rounds:
githubactions:S8545("Dependency versions are not predictable") ongo install .../govulncheck@latest.@v1.7.0(stillgo install) did not clear it — S8545 flagsgo install pkg@versionin CI generally, since it isn't verified against this repo's owngo.sum, regardless of which version is pinned.go get -tool .../govulncheck@v1.7.0, needs Go 1.24+) andgo tool govulncheck ./...in CI — a real go.sum-checksummed, lock-file-enforced install, which is what S8545 actually wants, and a bonus: Dependabot'sgomodecosystem can now track and bump it automatically, closing a gap the original issue explicitly flagged as unresolved ("it must be a tool dependency, which this project does not otherwise have").Separately, the
govulncheckjob itself correctly found 31 real, reachable CVEs in the Go 1.22 standard library (net/http,crypto/tls,crypto/x509,net/url, etc.) — none fixable by touchinggopkg.in/yaml.v3, since they're in the toolchain itself. Issue #107 — already filed, and explicitly written as "companion to the issue adding govulncheck... consider doing them in that order" — was exactly this. Rather than leave the newly-added job permanently red pending separate follow-up work, I confirmed with the repo owner and folded #107 into this PR.🎫 Issues
Closes #106
Closes #107
👩💻 Reviewer Notes
sonarqubejob'sif: github.actor != 'dependabot[bot]'guard was already present and is unchanged; this PR is what makes it actually matter, since Dependabot PRs will now exist.build-test-lint,govulncheck, andcross-compile, and that.github/dependabot.ymlshows up under Insights → Dependency graph → Dependabot.golangci-lintv2.13.1 vs. the previously-pinned v2.12.2: ran locally against the full repo with the new Go 1.26.7 toolchain —0 issues.go.mod/go.sumnow carrygolang.org/x/vulnand its transitive deps under atooldirective — these are build-tool-only (seego list -depsnote above), not a change to the runtime dependency policy inCLAUDE.md/ARCHITECTURE.md(still justgopkg.in/yaml.v3in the shipped binary).📑 Test Plan
This is CI/toolchain configuration, so there is no Go test to add. Verification performed instead:
go build ./...,go vet ./...,go test ./... -race -cover, andgolangci-lint run(v2.13.1) all pass locally against the Go 1.26.7 toolchain, both before and after switching to the tool-dependency form of govulncheck.GOOS=linux GOARCH=arm64andGOOS=linux GOARCH=arm GOARM=6, bothCGO_ENABLED=0— both succeed.go list -deps ./cmd/pimonitorconfirms the new tool-only requires don't reach the shipped binary.ci.yml,dependabot.yml) parse as valid YAML.go tool govulncheck ./...could not be run to completion in this sandbox, on any commit: this environment's outbound network policy blocksvuln.go.dev(the tool's vulnerability database), returning 403. The job itself is correctly wired and did run for real on GitHub's runners against the Go 1.22 toolchain (that's how the 31 findings that motivated the toolchain bump were discovered, and how the two SonarCloud rounds were diagnosed) — final end-to-end confirmation that Go 1.26.7 clears the findings and thatgo tool govulnchecksatisfies SonarCloud happens when this commit's CI runs in Actions.✅ Checklist
General
go vet ./...andgolangci-lint runare clean.ARCHITECTURE.mdif this changes a documented design decision.REST API / configuration / packaging
Not applicable — no REST API, config schema, or packaging changes.
⏭ Next Steps
None outstanding — this PR now covers both #106 and its companion #107 together, as the original issue suggested.