govulncheck: Go vulnerability checks explained
govulncheck is the Go team's vulnerability checker for Go modules; DevFlow runs it on every changed repository with a root go.mod, bounded by a 300-second timeout.
What the tool is
govulncheck is the vulnerability checker maintained by the Go team. It compares the modules a Go program uses with the Go vulnerability database and reports each match as a finding, with a trace that points at the affected module, package or function.
How DevFlow runs it
DevFlow's Go scanner runs govulncheck with the -json flag in the task's worktree, over every package of the module (./...). The run is bounded by the shared per-scan timeout, 300 seconds by default and tunable through SCANNER_TIMEOUT_SECONDS.
Reading the JSON stream
With that flag, govulncheck prints a stream of JSON objects, one per message. DevFlow reads two kinds: osv entries, which describe an advisory, and finding messages, which tie an advisory to the code being scanned.
Findings are deduplicated by advisory id, so repeated traces of the same flaw do not inflate the count. No finding is dropped because of what its trace points at, whether a module, a package or a function. The affected package comes from the first frame of the finding's trace, preferring the package path over the module path.
What each finding records
For every finding, DevFlow fills the shared vulnerability shape:
- the Go advisory id, which also builds the advisory link
https://pkg.go.dev/vuln/<id>; - the summary of the osv entry as the title;
- the first fixed version listed in the entry's affected ranges;
- a severity taken from the entry's
database_specificlabel.
The label is mapped to critical, high, moderate or low, with medium treated as moderate. An entry without a label, or with one DevFlow does not recognise, is recorded as unknown instead of guessed.
A worked example
Suppose a task changes a Go service whose go.mod still requires an old release of a networking library with two published advisories, and the stream shows two traces for one of them. The report then holds two findings, not three, each with its own advisory link and the first release that fixes it.
Where results go
The result joins the scans of the other ecosystems in the task's scan report, where each finding is listed by id. The merge evidence section of the pull request gives one line per repository: the names of the scanners that ran when nothing was found, otherwise the total and the count per severity.
The same scanner also runs on the recurring vulnerability poll, which checks each repository's default branch every 12 hours by default.
FAQ
Does DevFlow run govulncheck on a Go module in a subdirectory?
No. DevFlow's Go scanner runs govulncheck only when go.mod sits at the repository root, so a module nested in a subdirectory gets no audit.
Does DevFlow treat a non-zero exit from govulncheck as a failure?
Only when nothing was printed. govulncheck exits non-zero when it finds vulnerabilities, so DevFlow counts a run as failed only when that exit comes with no output at all.