gomod
Last updated October 25, 2026View source (v0.30.0)
This page explains how Bomly builds a dependency graph for gomod projects: the detector chain it runs, what that chain needs, and what it can report.
| Property | Value |
|---|---|
| Package manager | gomod |
| Ecosystem | go |
| Detector chain | go-detector, syft-detector |
| Evidence patterns | go.mod |
| Ignored directories | vendor |
| Multi-module resolution | No |
| Install-first support | Yes |
| Remediation hints | direct-bump1, lockfile-refresh2 |
| Commands the chain may run | go. The Syft fallback is built in; the lite build runs an external syft from PATH instead. |
How gomod resolves
go-detector is the only native Go detector, and it is a build-tool primary chain. There is no committed-lockfile fallback. To resolve a graph, Bomly runs the Go toolchain.
| Step | Command | Working dir |
|---|---|---|
| Resolve graph | go list -deps -json all (with -tags <tags> when BOMLY_GO_TAGS is set) | the directory containing go.mod |
The output is a JSON stream of module and package descriptions, which Bomly turns into a transitive dependency graph with edges.
go list may download modules during a plain scan. If go.sum is incomplete, or a module version is not in the local module cache, the Go toolchain fetches it from GOPROXY. That is the toolchain's behavior, not Bomly's, and the same downloads happen when you run go build. See Network and privacy for the shared rule. To keep the scan offline, do one of these:
- Commit a complete
go.sum(rungo mod tidyand commit the result). - Fill the module cache with
go mod downloadbefore scanning. - Vendor everything with
go mod vendor, so the toolchain readsvendor/modules.txt.
Prerequisites
- A Go toolchain on
PATH. Bomly does not bundle one. - A
go.modin the scanned directory. Eachgo.modis its own subproject; to find modules in nested directories, pass--recursive. GOPROXYreachable whengo.sumis incomplete or the module cache is cold.- Set
BOMLY_GO_TAGS=integration,e2eto resolve the graph with build tags applied. Without it, the default tag set is used.
Examples
Fix a direct vulnerability
bomly scan --enrich --auditreportsgithub.com/example/lib v1.2.3asCVE-2024-xxxxx.- Find the fixed version in the finding's
fixed_infield or on the advisory page. - Bump it with
go get github.com/example/lib@v1.2.4, then rungo mod tidy. - Re-scan to confirm the finding is gone.
Fix a transitive vulnerability
Use a replace directive in go.mod to override the transitive version until the direct dependency upgrades:
require example.com/parent v1.0.0
replace github.com/example/lib => github.com/example/lib v1.2.4
Run go mod tidy, re-scan, and remove the replace once parent releases a fix.
Multiple modules
The detector resolves one module per go.mod and does not expand go.work workspaces itself, which is why the table above says no multi-module resolution. To scan several modules in one repository, pass --recursive so each go.mod directory becomes a subproject. Bomly resolves each one and merges the graphs into one report. The Go toolchain still honors a go.work file when it resolves each module.
Vendored mode
If your repository commits vendor/, the Go toolchain reads vendor/modules.txt and never uses the network.
--install-first
With --install-first, Bomly runs go mod download before resolving the graph. That fills the module cache from GOPROXY, so the following go list runs offline. Use it in CI on a clean checkout:
bomly scan --install-first
To append flags to that command, repeat --install-arg. This requires --detectors go-detector:
# Verbose download output for CI debugging
bomly scan --install-first --detectors go-detector --install-arg -x
Reachability (experimental)
With --analyze, the govulncheck analyzer builds a real call graph and reports a vulnerability as reachable only when your code can reach the vulnerable function or method. Reflection and dynamic plugin loading are blind spots. It needs a buildable module. A build failure appears as reachability.status=unknown with a reason such as build-failed, missing-toolchain, or module-resolution-failed. See Reachability for the tier model and its caveats.
bomly scan --analyze --enrich --audit \
--fail-on high --fail-on reachable
Limitations
- C dependencies linked through cgo are not in the graph. Bomly tracks Go modules, not system libraries.
go generateis not run. Generated files must be committed for the detector to see them.- Pre-release suffixes (
-rc1,-beta.2, pseudo-versions) are passed through as written. Advisory ranges that use semver pre-release ordering may produce false positives at the boundary. - Private modules (
GOPRIVATE) resolve through your localGOPROXYconfiguration. Bomly does not authenticate to private proxies on its own.