ci(security): add govulncheck, gosec and diff-only golangci-lint - #324
Open
mateeullahmalik wants to merge 1 commit into
Open
ci(security): add govulncheck, gosec and diff-only golangci-lint#324mateeullahmalik wants to merge 1 commit into
mateeullahmalik wants to merge 1 commit into
Conversation
Ports the three CI security/lint gates from the chain repo to supernode: - govulncheck (LumeraProtocol/lumera#212) - gosec (LumeraProtocol/lumera#213) - golangci-lint via reviewdog, diff-only (LumeraProtocol/lumera#126) Same tools, same flags, same goals, adapted to this repo's layout. Repo-specific adaptations: * Multi-module matrix. supernode has four Go modules (root, cmd/sncli, sn-manager, tests/system) where the chain repo has three. gosec and govulncheck each run per-module from that module's directory, because a root ./... invocation does not analyze nested modules. fail-fast is disabled so one module's findings cannot hide another's. * golangci-lint pinned to v2.13.2 rather than the chain's v2.11.3. go.mod declares go 1.26.2 and golangci-lint must be BUILT with a Go >= the targeted language version; v2.11.3 is built with go1.26.1. * .golangci.yml is new here (the repo had no lint config). Same linter set as the chain repo; exclusions retarget generated protobuf/mock surfaces instead of Cosmos SDK deprecations. * Uses the existing ./.github/actions/setup-env composite action, which installs libwebp-dev — required for the root module to type-check. Without it gosec fails SSA construction instead of reporting a clean scan. gosec baseline is clean on all four modules (0 findings, 0 SSA errors). Reaching that required five narrow suppressions, each rule-scoped and justified, at intentional trust boundaries: - G108 gateway/server.go: net/http/pprof registers on DefaultServeMux, which this server never serves. pprof routes are on a private mux, only registered when pprofEnabled, and the handlers re-check and return 403. - G703 x4: operator-selected config paths (own $HOME / explicit --config) and a system-test harness writing to a directory it created itself. No runtime behavior changes: the only non-CI edits are comments. Verification: - gosec: 0 issues / 0 SSA errors across all four modules - mutation probe (deliberate G703 taint) => gosec exits 1 and reports G703, proving the gate is non-vacuous; fixture removed - go build ./..., go vet ./pkg/..., and unit tests all pass - all workflow YAML parses; every pinned action ref verified to exist
|
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. |
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.
Ports the three CI gates from the chain repo to
supernode— same tools, same flags, same goals, adapted to this repo's layout..github/workflows/govulncheck.yml.github/workflows/gosec.yml.github/workflows/lint-pr.ymlBehavior change
Three new workflows run on every PR and on pushes to
master. No runtime behavior changes — the only non-CI edits are comments (#nosecannotations).Repo-specific adaptations
These are the places where a literal copy of the chain workflows would have been wrong:
1. Four Go modules, not one.
supernodehas.,cmd/sncli,sn-manager,tests/system. gosec and govulncheck each run per-module from that module's directory via a matrix — a root./...invocation does not analyze nested modules.fail-fast: falseso one module's findings can't hide another's.2. golangci-lint pinned to v2.13.2, not the chain's v2.11.3.
go.moddeclaresgo 1.26.2, and golangci-lint must be built with a Go >= the targeted language version or it hard-errors. v2.11.3 is built with go1.26.1. Verified locally:3.
.golangci.ymlis new here — the repo had no lint config at all. Same linter set as the chain repo; exclusions retarget generated protobuf/mock surfaces instead of Cosmos SDK deprecations.4. Uses the existing
./.github/actions/setup-env, which installslibwebp-dev. The root module needs it to type-check; without it gosec fails SSA construction rather than reporting a clean scan.5. Diff-only lint is the only lint gate here. In the chain repo,
lint-pr.ymlis an additive layer over an authoritative full-scanlint.yml.supernodehas no such gate and a legacy baseline of 89 findings (50 errcheck, 23 unused, 8 staticcheck, 4 ineffassign, 3 gofmt, 1 govet). A full-repo gate would be red on day one, so enforcement is scoped to the PR diff (filter_mode: added): new code must be clean, legacy debt is not retroactively blocking.gosec: baseline is clean ✅
0 findings, 0 SSA/type errors, all four modules:
Reaching that required five narrow, rule-scoped, justified suppressions at intentional trust boundaries — no
exclude-dir, no global rule exclusion, nocontinue-on-error:gateway/server.go:8net/http/pprofregisters onDefaultServeMux, which this server never serves. pprof routes are on a private mux, only registered whenpprofEnabled(testnet chain-id orENABLE_PPROF=true), and the handlers re-check the flag and return 403.sn-manager/cmd/init.go:240$HOME; onlystat'ed.sn-manager/cmd/helpers.go:53cmd/sncli/cli/utils.go:28--config, already cleaned.tests/system/system.go:208Mutation-tested (non-vacuous). Injected a deliberate G703 taint shape → gosec exited 1 and reported
G703in SARIF. Fixture deleted; no probe artifacts remain in the tree.govulncheck:⚠️ this job will be RED on merge — please read
This is the one place I could not make green without a judgement call that belongs to you.
Reachable-vulnerability baseline on current
master:.cmd/snclisn-managertests/systemThe overwhelming majority are Go stdlib advisories against
go1.26.2(net/http,crypto/tls,crypto/x509,net/url,html/template,encoding/asn1,net/textproto,net). They are fixed in later go1.26.x patches. I measured three options on a throwaway copy:go 1.26.2→1.26.6, one line per module, zero dependency changesv1.80.0→v1.82.1and x/imagev0.41.0→v0.43.0Under C, the only survivors repo-wide are the two advisories with no upstream fix, which are exactly the class the chain repo already accepts:
GO-2026-5932—golang.org/x/crypto@v0.52.0(Fixed in: N/A)GO-2025-3684—github.com/cosmos/evm@v0.6.0(Fixed in: N/A)I verified option C builds and passes:
go build ./...✅,go vet ./pkg/...✅, unit tests ✅.I deliberately did not include B or C in this PR. Bumping gRPC on a P2P daemon with custom ALTS credentials is a real production risk that deserves its own reviewed, devnet-validated PR — not a silent rider on a CI change. Note also that the chain repo's own
govulncheckis red onmastertoday for the same reason (5 vulns, allFixed in: N/A), so shipping red here is at least consistent with current chain behavior.Recommendation: merge this PR for the workflows, then land the toolchain bump (B, one line per module, zero dep churn) as an immediate follow-up to take root 18 → 5. Do C separately with devnet validation. Tell me which you want and I'll open it.
Risks
lint-pr.ymlposts inline review comments on same-repo PRs; fork PRs fall back toreporter: local(log-only) becauseGITHUB_TOKENis read-only there. The job still fails on new errors either way.levelis deliberately not set on the reviewdog steps: it rewrites every finding's severity rather than defaulting it, solevel: warning+fail_level: errorwould silently neuter the gate.Rollback
Delete the three workflow files and
.golangci.yml. The five#noseccomments are inert and can stay or go independently.Migration / upgrade impact
None. CI-only. No state keys, no ABCI phases, no replay/migration/upgrade-handler behavior touched.