A vendor directory holds copies of a Go module's dependencies inside the repository, so builds can run without fetching them. When onboarding a scanner, confirm that vendor matches go.mod and go.sum, scan one source of truth, and avoid counting the same package twice.
What the vendor directory is
The Go modules reference describes vendoring as keeping dependency copies in a vendor directory created by the go mod vendor command, with a vendor/modules.txt file that records what was copied. It also says that automatic vendoring may be enabled when the go version in go.mod is 1.14 or higher and the vendor directory exists, so the build may use the copies without any extra flag.
That has a direct consequence for security tooling. What the compiler uses can be the vendor copy, not what go.mod says it resolves online.
Why this matters at onboarding
- If vendor and go.mod disagree, the build uses vendor, and a scan of go.mod alone is wrong.
- If you scan both, every package may appear twice, once as a dependency and once as files.
- A vendored package can be edited by hand. Then it is no longer the published version, and a scanner matching on version number may miss or misjudge it.
Checks to run
- Find every go.mod in the monorepo. Large repositories often have many modules, or a single go.work file tying several together.
- For each module, check whether a vendor directory exists beside it.
- Compare the packages in vendor/modules.txt with go.mod. Differences mean the vendor copy is stale or was edited.
- Search vendored directories for local changes by comparing against a fresh download of the same version.
- Choose the scan source: for built services, usually go.mod plus go.sum; add a vendor check as a second pass.
Decision table
| Condition | Scan source | Extra step |
|---|---|---|
| vendor matches modules.txt and go.mod | go.mod and go.sum | None |
| vendor older than go.mod | vendor, as that is what builds | Plan a refresh |
| Hand edited vendored package | Mark as modified | Review by a developer |
| No vendor directory | go.mod and go.sum | None |
Refreshing vendor safely
When you refresh a vendor directory, the pull request is large. Reviewers cannot read thousands of changed lines, so make the pull request contain only the refresh, and add a short note listing versions that changed. Run the full test suite. Keep security fixes and refreshes in separate changes so a rollback is clean.
Keep one number
Tell stakeholders how you count. Say "we count packages from go.mod, and use vendor only to confirm it" and stick to it. Switching counting rules between reports makes trends meaningless.
Where Safeguard fits
Safeguard's dependency scanning and SBOM output cover Go modules, and reachability analysis can help show whether a vulnerable function is called. The CLI 1.4.0 and the free scan at https://gold.safeguard.sh/scan are good ways to test a single module first.
Quick check
Should vendor directories be excluded from scans?
Not blindly. Use them to confirm versions, because they may be what actually builds. Just avoid counting the same package twice.
How do I know whether a vendored package was edited?
Download the same version fresh and compare the files. Any difference means the copy was changed locally.
Sources
Last reviewed: 19 October 2026.