Skip to content

Commit

Permalink
Add OpenVEX matching on local package name + tags
Browse files Browse the repository at this point in the history
Add local package name and image tag information to the list of identifiers
that OpenVEX products are matched against.

Where tags are provided, create a product identifier matching the pURL spec in
https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#oci.

Also add a basic test for the functionality.

Signed-off-by: Feroz Salam <[email protected]>
  • Loading branch information
ferozsalam committed Dec 29, 2024
1 parent e64eedd commit 836de65
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
28 changes: 24 additions & 4 deletions grype/vex/openvex/implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/url"
"slices"
"strings"

"github.com/google/go-containerregistry/pkg/name"
Expand Down Expand Up @@ -61,16 +62,35 @@ func (ovm *Processor) ReadVexDocuments(docs []string) (interface{}, error) {
func productIdentifiersFromContext(pkgContext *pkg.Context) ([]string, error) {
switch v := pkgContext.Source.Metadata.(type) {
case source.ImageMetadata:
// TODO(puerco): We can create a wider definition here. This effectively
// adds the multiarch image and the image of the OS running grype. We
// could generate more identifiers to match better.
return identifiersFromDigests(v.RepoDigests), nil
tagIdentifiers := identifiersFromTags(v.Tags, pkgContext.Source.Name)
digestIdentifiers := identifiersFromDigests(v.RepoDigests)
identifiers := slices.Concat(tagIdentifiers, digestIdentifiers)
return identifiers, nil
default:
// Fail for now
return nil, errors.New("source type not supported for VEX")
}
}

func identifiersFromTags(tags []string, name string) []string {
identifiers := []string{}

for _, tag := range tags {
identifiers = append(identifiers, tag)

tagMap := map[string]string{}
_, splitTag, found := strings.Cut(tag, ":")
if found {
tagMap["tag"] = splitTag
qualifiers := packageurl.QualifiersFromMap(tagMap)

identifiers = append(identifiers, packageurl.NewPackageURL("oci", "", name, "", qualifiers, "").String())
}
}

return identifiers
}

func identifiersFromDigests(digests []string) []string {
identifiers := []string{}

Expand Down
22 changes: 22 additions & 0 deletions grype/vex/openvex/implementation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,28 @@ import (
"github.com/stretchr/testify/require"
)

func TestIdentifiersFromTags(t *testing.T) {
for _, tc := range []struct {
sut string
name string
expected []string
}{
{
"alpine:v1.2.3",
"alpine",
[]string{"alpine:v1.2.3", "pkg:oci/alpine?tag=v1.2.3"},
},
{
"alpine",
"alpine",
[]string{"alpine"},
},
} {
res := identifiersFromTags([]string{tc.sut}, tc.name)
require.Equal(t, tc.expected, res)
}
}

func TestIdentifiersFromDigests(t *testing.T) {
for _, tc := range []struct {
sut string
Expand Down

0 comments on commit 836de65

Please sign in to comment.