vulncheck: allowlist is count-based, so any new advisory hard-blocks every PR
- Dominant language
- Go
- Stars
- 28
- Forks
- 11
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 55
Description
## Problem
`make vulncheck` accepts a govulncheck failure only when the output matches a literal string:
```make
if grep -q 'affected by 1 vulnerability' "$$tmpf" && grep -q 'GO-2024-3218' "$$tmpf"; then
echo "vulncheck: only known-unfixable GO-2024-3218 found (accepted)"; \
```
The allowlist is therefore **count-based rather than identity-based**. It does not mean "GO-2024-3218 is accepted", it means "exactly one finding, and GO-2024-3218 is somewhere in the output". Any additional advisory, however minor, makes the grep miss and fails the job.
`Vulnerability Check` is a required status check and the `main` ruleset has `bypass_actors: null`, so there is no override. The result is that a single new advisory blocks **every** pull request in the repo until someone lands a fix.
## This already happened
On 2026-08-13, Go 1.26.6 was published with seven standard library advisories (GO-2026-6218, 6091, 6090, 6089, 6088, 5972, 5026). govulncheck went from 1 finding to 8, the grep missed, and the repo was blocked. PR #611 was ejected from the merge queue twice before the cause was identified, and #613 was needed to unblock.
The failure mode is especially confusing because it is time-based, not content-based: a PR goes green on its own branch and is then rejected by the merge queue minutes later with no code change. #611's branch run at 22:29 UTC passed; its queue runs at 22:43 and 23:06 failed on identical content.
It also produces a misleading secondary symptom. Ejection deletes the `gh-readonly-queue` ref, so an in-flight CodeQL job fails its SARIF upload with `ref ... not found`, which surfaces as an unrelated-looking `Analyze (rust)` failure.
## Suggested fix
Make the allowlist identity-based: maintain an explicit set of accepted advisory IDs and fail only when a finding falls outside it. `govulncheck -format json` (or `-format sarif`) gives a machine-readable list of IDs rather than requiring prose matching.
That way a newly disclosed advisory still fails the build, which is correct, but an accepted one does not become order- or count-sensitive, and adding a second accepted exception does not silently disable the check.
## Notes
Related: `.github/dependabot.yml` configures only the `github-actions` and `gomod` ecosystems. Neither bumps the `go` directive's patch version nor the `golang:` base image pins in `images/*/Containerfile`, so this class of breakage is always discovered as a repo-wide merge block rather than as a dependency PR. Adding the `docker` ecosystem would at least keep the base images current.
Contributor guide
Research direction
Start with the `make vulncheck` entry point and locate the check that greps govulncheck output for `GO-2024-3218`. Review govulncheck's JSON or SARIF output format and the existing required Vulnerability Check workflow. Done means accepted advisory IDs remain allowed independently of finding count, while any unlisted advisory still fails the check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, go
- Domain
- ci-cd, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100