Skip to content

ci: run trivy on last release binary - #275

Merged
niemeyer merged 13 commits into
canonical:mainfrom
upils:feat/rework-trivy
Mar 30, 2026
Merged

niemeyer merged 13 commits into
canonical:mainfrom
upils:feat/rework-trivy

Conversation

@upils

@upils upils commented Mar 13, 2026 •

Copy link
Copy Markdown
Collaborator
  • Have you signed the CLA?

Trivy was previously executed on the main branch, so the report was not
reflecting the level of vulnerability in the binary actually distributed to
users. Moreover, fs type scan only uses the go version from go.mod as a
hint and so cannot conclude on the stdb lib actually used to build the binary.
As a consequence, the report produced was imprecise and incomplete.

This PR does two main changes:

  • Run the scan on the last release, on all architectures;
  • Run a rootfs type scan on the binary, ensuring the the std lib included
    is analysed.

Actions are also pinned to protect against supply chain attacks on them.

Note: I manually tested both type of trivy scan on the binary and confirmed
only the rootfs one identifies the vulnerabilities in the std lib.

@upils upils added the Simple Nice for a quick look on a minute or two label Mar 13, 2026
@upils
upils requested review from cjdcordeiro and letFunny March 13, 2026 13:41
Comment thread .github/workflows/security.yaml Resolved
Comment thread .github/workflows/security.yaml Outdated
id: release
run: |
url=$(gh release view --json assets --jq \
'.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this run on a matrix? I.e. to catch architecture-specific vulnerabilities

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should, tbh if it is easier we can download all the files, extract them and look for binaries.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would gh release download work as well? From documentation it says it downloads the latest release and it is simpler.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this run on a matrix? I.e. to catch architecture-specific vulnerabilities

In Go, dependencies in go.mod are not architecture-dependent. Vulnerabilities are not architecture-dependent either, so AFAIK when vulnerabilities are found, they are associated to a specific version (or a range) of a libraries, but not to a specific architecture. I agree that in reality, a vulnerability could only affect an arch-specific path, but this vulnerability will be associated to the library anyway. In go files, specific directive could be used to tune the imports based on the target arch, but these dependencies must be listed anyway in go.mod. So that could lead to false positives but not false negatives.

Given that, the architecture we select to scan is actually irrelevant. Do you agree?

I picked amd64 because this is the most common and the one we are most likely to keep building over time.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that in reality, a vulnerability could only affect an arch-specific path, but this vulnerability will be associated to the library anyway.

If this is true then we can only test amd64. I am not saying it is not, but if we were to use govulncheck or similar, then the scanners not only look at go.mod but instead they look at the actual call graph in which case architecture IS relevant, right?

IMHO either we add a comment saying why we are only testing amd64 or we test all architectures even if it is redundant for now. We may add more scanners in the future and I am almost certain we will forget to expand the list of architectures now that the assumption no longer holds. In this case, evident > clever IMO.

@upils upils Mar 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is true then we can only test amd64. I am not saying it is not, but if we were to use govulncheck or similar, then the scanners not only look at go.mod but instead they look at the actual call graph in which case architecture IS relevant, right?

I see your point. I agree that if we were to replace trivy with govulncheck, then the more precise analysis of govulncheck on a single arch could exclude false positives for this arch that are true positives for another arch.

I am adding the matrix. See cfd7a2a

Comment thread .github/workflows/security.yaml Resolved
Comment thread .github/workflows/security.yaml Resolved
Comment thread .github/workflows/security.yaml Resolved

@letFunny letFunny left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking more into this Paul, great diligence! Just a couple of comments.

Comment thread .github/workflows/security.yaml Outdated
id: release
run: |
url=$(gh release view --json assets --jq \
'.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should, tbh if it is easier we can download all the files, extract them and look for binaries.

uses: aquasecurity/trivy-action@master
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
with:
scan-type: 'fs'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we not going to do the 'fs' check then? If we could have it "for free" it would be even better as it would cause problems in the go.mod itself. Let's say that go.mod says go 1.23 is used but our CI uses go.24 to build the binary. Then the binary might not have vulnerabilities but users building the binary themselves might not be safe. In this case I think we should probably bump the minimal go version in go.mod as well even if it is more troublesome for us.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If our go.mod says Go 1.23, it only means our code needs at least this version to work properly. This is not a promise on the level of security, but a minimum functional requirement. In an ideal world (and forgetting about new language features) I suppose we would like this value to be as low as possible so the project could be built with a wide variety of go versions.

I don't think we can do any promise on binaries we do not distribute ourselves, nor should we try to.

Also, as explained in the PR description, in fs mode trivy is not looking at the go ... directive given in go.mod because it does not say what version of Go will actually be used. So in the case of a Go project, the fs mode executed on the code could only find less vulnerabilities than the rootfs mode on the binary, because the rootfs mode will identify the Go version used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can do any promise on binaries we do not distribute ourselves, nor should we try to.

Depends on how you look at it, but yes I get your point. If the minimal version is for the package to build then the expectation is as you say, if as a user I expect the package to build without known vulnerabilities then the minimum version should reflect that.

in fs mode trivy is not looking at the go ... directive given in go.mod

I didn't know this, I was under the impression trivy look at the minimum version and used that. Then it is okay if we don't keep it. Thanks for the context!

@upils upils Mar 16, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sticking to https://go.dev/ref/mod#go-mod-file-go for the meaning of the go directive. If we were to do what you suggest, the toolchain directive might be a better fit, but it still feels like a stretch.

Comment thread .github/workflows/security.yaml Outdated
id: release
run: |
url=$(gh release view --json assets --jq \
'.assets[] | select(.name | test("linux_amd64.tar.gz$")) | .url' \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would gh release download work as well? From documentation it says it downloads the latest release and it is simpler.

@upils
upils requested review from cjdcordeiro and letFunny March 17, 2026 12:48

@letFunny letFunny left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, thank you for working on this

Comment thread .github/workflows/security.yaml Resolved
Comment thread .github/workflows/security.yaml Resolved
Comment thread .github/workflows/security.yaml Resolved
@upils upils mentioned this pull request Mar 20, 2026
1 task
niemeyer pushed a commit that referenced this pull request Mar 30, 2026
Pin all actions used in workflows with hashes.
This also bumps setup-go and checkout actions version as I expect no breaking
change given how they are used.

Remaining actions not pinned in this PR are pinned or reworked in other PRs (see
#275, #274, #272)

@niemeyer niemeyer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay, but I'm trusting you both on this one as there are multiple action imports here. No relevant secrets being offers, so hopefully okay anyway. It is slightly ironic, considering the "security" name, though. Maybe "scanning" is a better term here.

@niemeyer
niemeyer merged commit f5accb2 into canonical:main Mar 30, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Simple Nice for a quick look on a minute or two

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants