Repository: anchore/grype
Pull request #1662 (2024-01-17 15:50:02)

Upgrade syft with latest SBOM creation API
Bumps syft to integrate the unreleased SBOM API changes.


Patch:
diff --git a/cmd/grype/cli/commands/root.go b/cmd/grype/cli/commands/root.go
index 52212a96..64fc7edc 100644
--- a/cmd/grype/cli/commands/root.go
+++ b/cmd/grype/cli/commands/root.go
@@ -34,9 +34,9 @@ import (
 	"github.com/anchore/grype/internal/format"
 	"github.com/anchore/grype/internal/log"
 	"github.com/anchore/grype/internal/stringutil"
+	"github.com/anchore/syft/syft"
 	"github.com/anchore/syft/syft/linux"
 	syftPkg "github.com/anchore/syft/syft/pkg"
-	"github.com/anchore/syft/syft/pkg/cataloger"
 	"github.com/anchore/syft/syft/sbom"
 )
 
@@ -290,14 +290,15 @@ func getMatchers(opts *options.Grype) []matcher.Matcher {
 }
 
 func getProviderConfig(opts *options.Grype) pkg.ProviderConfig {
-	cfg := cataloger.DefaultConfig()
-	cfg.Search = opts.Search.ToConfig()
+	cfg := syft.DefaultCreateSBOMConfig()
+	cfg.Packages.JavaArchive.IncludeIndexedArchives = opts.Search.IncludeIndexedArchives
+	cfg.Packages.JavaArchive.IncludeUnindexedArchives = opts.Search.IncludeUnindexedArchives
 
 	return pkg.ProviderConfig{
 		SyftProviderConfig: pkg.SyftProviderConfig{
 			RegistryOptions:        opts.Registry.ToOptions(),
 			Exclusions:             opts.Exclusions,
-			CatalogingOptions:      cfg,
+			SBOMOptions:            cfg,
 			Platform:               opts.Platform,
 			Name:                   opts.Name,
 			DefaultImagePullSource: opts.DefaultImagePullSource,
diff --git a/cmd/grype/cli/options/search.go b/cmd/grype/cli/options/search.go
index e1c59e17..2e812d2a 100644
--- a/cmd/grype/cli/options/search.go
+++ b/cmd/grype/cli/options/search.go
@@ -4,7 +4,7 @@ import (
 	"fmt"
 
 	"github.com/anchore/clio"
-	"github.com/anchore/syft/syft/pkg/cataloger"
+	"github.com/anchore/syft/syft/cataloging"
 	"github.com/anchore/syft/syft/source"
 )
 
@@ -17,7 +17,7 @@ type search struct {
 var _ clio.PostLoader = (*search)(nil)
 
 func defaultSearch(scope source.Scope) search {
-	c := cataloger.DefaultSearchConfig()
+	c := cataloging.DefaultArchiveSearchConfig()
 	return search{
 		Scope:                    scope.String(),
 		IncludeUnindexedArchives: c.IncludeUnindexedArchives,
@@ -36,11 +36,3 @@ func (cfg *search) PostLoad() error {
 func (cfg search) GetScope() source.Scope {
 	return source.ParseScope(cfg.Scope)
 }
-
-func (cfg search) ToConfig() cataloger.SearchConfig {
-	return cataloger.SearchConfig{
-		IncludeIndexedArchives:   cfg.IncludeIndexedArchives,
-		IncludeUnindexedArchives: cfg.IncludeUnindexedArchives,
-		Scope:                    cfg.GetScope(),
-	}
-}
diff --git a/cmd/grype/internal/ui/ui.go b/cmd/grype/internal/ui/ui.go
index 4ca88e73..48afdc33 100644
--- a/cmd/grype/internal/ui/ui.go
+++ b/cmd/grype/internal/ui/ui.go
@@ -151,8 +151,11 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			return m, nil
 		}
 
-		newModels, _ := m.handler.Handle(msg)
-		for _, newModel := range newModels {
+		models, cmd := m.handler.Handle(msg)
+		if cmd != nil {
+			cmds = append(cmds, cmd)
+		}
+		for _, newModel := range models {
 			if newModel == nil {
 				continue
 			}
diff --git a/go.mod b/go.mod
index e522ff26..df55e019 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
 	github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501
 	github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54
-	github.com/anchore/syft v0.100.0
+	github.com/anchore/syft v0.100.1-0.20240117170637-297ece69045d
 	github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
 	github.com/bmatcuk/doublestar/v2 v2.0.4
 	github.com/charmbracelet/bubbletea v0.25.0
@@ -90,7 +90,7 @@ require (
 	github.com/becheran/wildmatch-go v1.0.0 // indirect
 	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
 	github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
-	github.com/charmbracelet/bubbles v0.16.1 // indirect
+	github.com/charmbracelet/bubbles v0.17.1 // indirect
 	github.com/charmbracelet/harmonica v0.2.0 // indirect
 	github.com/cloudflare/circl v1.3.7 // indirect
 	github.com/containerd/cgroups v1.1.0 // indirect
@@ -235,13 +235,13 @@ require (
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/goleak v1.2.0 // indirect
 	go.uber.org/multierr v1.9.0 // indirect
-	golang.org/x/crypto v0.17.0 // indirect
+	golang.org/x/crypto v0.18.0 // indirect
 	golang.org/x/mod v0.14.0 // indirect
-	golang.org/x/net v0.19.0 // indirect
+	golang.org/x/net v0.20.0 // indirect
 	golang.org/x/oauth2 v0.15.0 // indirect
 	golang.org/x/sync v0.5.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
-	golang.org/x/term v0.15.0 // indirect
+	golang.org/x/sys v0.16.0 // indirect
+	golang.org/x/term v0.16.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	golang.org/x/time v0.5.0 // indirect
 	golang.org/x/tools v0.13.0 // indirect
diff --git a/go.sum b/go.sum
index 79e226d7..95dc2679 100644
--- a/go.sum
+++ b/go.sum
@@ -251,8 +251,8 @@ github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 h1:AV7qjwM
 github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
 github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54 h1:i2YK5QEs9H2YB3B2zv+AGR44ves0nmAGOD07lMphH14=
 github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54/go.mod h1:IylG7ofLoUKHwS1XDF6rPhOmaE3GgpAgsMdvvYfooTU=
-github.com/anchore/syft v0.100.0 h1:XUpV4xWmD2cBS9hhhEdJEppItz0AxG8f5W3JhI2tQvY=
-github.com/anchore/syft v0.100.0/go.mod h1:laFRFA/okrA+ut+wPCU32hNkdPEwQfXyaB7E21ymWFc=
+github.com/anchore/syft v0.100.1-0.20240117170637-297ece69045d h1:Lbb5ljfx0g3uYBY11wF2oHYbdE2Nh5mmtQhZlhOI8C0=
+github.com/anchore/syft v0.100.1-0.20240117170637-297ece69045d/go.mod h1:oRQuHODu6IYHhb9SDw9kmNhAmdZngVbTU1kR2jVq48E=
 github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
@@ -273,6 +273,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
 github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
+github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
 github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 github.com/aws/aws-sdk-go v1.44.288 h1:Ln7fIao/nl0ACtelgR1I4AiEw/GLNkKcXfCaHupUW5Q=
 github.com/aws/aws-sdk-go v1.44.288/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
@@ -298,8 +300,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
-github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
+github.com/charmbracelet/bubbles v0.17.1 h1:0SIyjOnkrsfDo88YvPgAWvZMwXe26TP6drRvmkjyUu4=
+github.com/charmbracelet/bubbles v0.17.1/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o=
 github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
 github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
 github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
@@ -889,6 +891,8 @@ github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9c
 github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
 github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
 github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
+github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
+github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
 github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
 github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
 github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
@@ -1075,8 +1079,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
-golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
+golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1179,8 +1183,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
-golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
+golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1326,8 +1330,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1335,8 +1339,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
+golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/grype/deprecated.go b/grype/deprecated.go
index 5407d968..e9e4d4eb 100644
--- a/grype/deprecated.go
+++ b/grype/deprecated.go
@@ -7,8 +7,8 @@ import (
 	"github.com/anchore/grype/grype/store"
 	"github.com/anchore/grype/internal/log"
 	"github.com/anchore/stereoscope/pkg/image"
+	"github.com/anchore/syft/syft"
 	"github.com/anchore/syft/syft/linux"
-	"github.com/anchore/syft/syft/pkg/cataloger"
 	"github.com/anchore/syft/syft/source"
 )
 
@@ -16,11 +16,11 @@ import (
 func FindVulnerabilities(store store.Store, userImageStr string, scopeOpt source.Scope, registryOptions *image.RegistryOptions) (match.Matches, pkg.Context, []pkg.Package, error) {
 	providerConfig := pkg.ProviderConfig{
 		SyftProviderConfig: pkg.SyftProviderConfig{
-			RegistryOptions:   registryOptions,
-			CatalogingOptions: cataloger.DefaultConfig(),
+			RegistryOptions: registryOptions,
+			SBOMOptions:     syft.DefaultCreateSBOMConfig(),
 		},
 	}
-	providerConfig.CatalogingOptions.Search.Scope = scopeOpt
+	providerConfig.SBOMOptions.Search.Scope = scopeOpt
 
 	packages, context, _, err := pkg.Provide(userImageStr, providerConfig)
 	if err != nil {
diff --git a/grype/pkg/provider_config.go b/grype/pkg/provider_config.go
index 2fd8d97e..978f5da3 100644
--- a/grype/pkg/provider_config.go
+++ b/grype/pkg/provider_config.go
@@ -2,7 +2,7 @@ package pkg
 
 import (
 	"github.com/anchore/stereoscope/pkg/image"
-	"github.com/anchore/syft/syft/pkg/cataloger"
+	"github.com/anchore/syft/syft"
 )
 
 type ProviderConfig struct {
@@ -11,7 +11,7 @@ type ProviderConfig struct {
 }
 
 type SyftProviderConfig struct {
-	CatalogingOptions      cataloger.Config
+	SBOMOptions            *syft.CreateSBOMConfig
 	RegistryOptions        *image.RegistryOptions
 	Platform               string
 	Exclusions             []string
diff --git a/grype/pkg/syft_provider.go b/grype/pkg/syft_provider.go
index 0f1b725b..2f04da61 100644
--- a/grype/pkg/syft_provider.go
+++ b/grype/pkg/syft_provider.go
@@ -1,6 +1,9 @@
 package pkg
 
 import (
+	"context"
+	"errors"
+
 	"github.com/anchore/grype/internal/log"
 	"github.com/anchore/stereoscope/pkg/image"
 	"github.com/anchore/syft/syft"
@@ -22,34 +25,30 @@ func syftProvider(userInput string, config ProviderConfig) ([]Package, Context,
 		}
 	}()
 
-	catalog, relationships, theDistro, err := syft.CatalogPackages(src, config.CatalogingOptions)
+	s, err := syft.CreateSBOM(context.Background(), src, config.SBOMOptions)
 	if err != nil {
 		return nil, Context{}, nil, err
 	}
 
-	catalog = removePackagesByOverlap(catalog, relationships, theDistro)
+	if s == nil {
+		return nil, Context{}, nil, errors.New("no SBOM provided")
+	}
+
+	pkgCatalog := removePackagesByOverlap(s.Artifacts.Packages, s.Relationships, s.Artifacts.LinuxDistribution)
 
 	srcDescription := src.Describe()
 
-	packages := FromCollection(catalog, config.SynthesisConfig)
-	context := Context{
+	packages := FromCollection(pkgCatalog, config.SynthesisConfig)
+	pkgCtx := Context{
 		Source: &srcDescription,
-		Distro: theDistro,
-	}
-
-	sbom := &sbom.SBOM{
-		Source:        srcDescription,
-		Relationships: relationships,
-		Artifacts: sbom.Artifacts{
-			Packages: catalog,
-		},
+		Distro: s.Artifacts.LinuxDistribution,
 	}
 
-	return packages, context, sbom, nil
+	return packages, pkgCtx, s, nil
 }
 
 func getSource(userInput string, config ProviderConfig) (source.Source, error) {
-	if config.CatalogingOptions.Search.Scope == "" {
+	if config.SBOMOptions.Search.Scope == "" {
 		return nil, errDoesNotProvide
 	}
 


Test patch:
diff --git a/cmd/grype/cli/commands/root_test.go b/cmd/grype/cli/commands/root_test.go
index 953fa42c..82ed09b7 100644
--- a/cmd/grype/cli/commands/root_test.go
+++ b/cmd/grype/cli/commands/root_test.go
@@ -11,7 +11,7 @@ import (
 	"github.com/anchore/grype/cmd/grype/cli/options"
 	"github.com/anchore/grype/grype/pkg"
 	"github.com/anchore/stereoscope/pkg/image"
-	"github.com/anchore/syft/syft/pkg/cataloger"
+	"github.com/anchore/syft/syft"
 	"github.com/anchore/syft/syft/pkg/cataloger/binary"
 )
 
@@ -61,7 +61,7 @@ func Test_getProviderConfig(t *testing.T) {
 			}),
 			want: pkg.ProviderConfig{
 				SyftProviderConfig: pkg.SyftProviderConfig{
-					CatalogingOptions: cataloger.DefaultConfig(),
+					SBOMOptions: syft.DefaultCreateSBOMConfig(),
 					RegistryOptions: &image.RegistryOptions{
 						Credentials: []image.RegistryCredentials{},
 					},
@@ -71,8 +71,11 @@ func Test_getProviderConfig(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			opts := cmpopts.IgnoreFields(binary.Classifier{}, "EvidenceMatcher")
-			if d := cmp.Diff(tt.want, getProviderConfig(tt.opts), opts); d != "" {
+			opts := cmp.Options{
+				cmpopts.IgnoreFields(binary.Classifier{}, "EvidenceMatcher"),
+				cmpopts.IgnoreUnexported(syft.CreateSBOMConfig{}),
+			}
+			if d := cmp.Diff(tt.want, getProviderConfig(tt.opts), opts...); d != "" {
 				t.Errorf("getProviderConfig() mismatch (-want +got):\n%s", d)
 			}
 		})
diff --git a/grype/pkg/provider_test.go b/grype/pkg/provider_test.go
index 34dd9443..9829a5e7 100644
--- a/grype/pkg/provider_test.go
+++ b/grype/pkg/provider_test.go
@@ -6,8 +6,8 @@ import (
 	"github.com/stretchr/testify/assert"
 
 	"github.com/anchore/stereoscope/pkg/imagetest"
+	"github.com/anchore/syft/syft"
 	"github.com/anchore/syft/syft/file"
-	"github.com/anchore/syft/syft/pkg/cataloger"
 )
 
 func TestProviderLocationExcludes(t *testing.T) {
@@ -47,8 +47,8 @@ func TestProviderLocationExcludes(t *testing.T) {
 		t.Run(test.name, func(t *testing.T) {
 			cfg := ProviderConfig{
 				SyftProviderConfig: SyftProviderConfig{
-					Exclusions:        test.excludes,
-					CatalogingOptions: cataloger.DefaultConfig(),
+					Exclusions:  test.excludes,
+					SBOMOptions: syft.DefaultCreateSBOMConfig(),
 				},
 			}
 			pkgs, _, _, _ := Provide(test.fixture, cfg)
@@ -102,8 +102,8 @@ func TestSyftLocationExcludes(t *testing.T) {
 			userInput := imagetest.GetFixtureImageTarPath(t, test.fixture)
 			cfg := ProviderConfig{
 				SyftProviderConfig: SyftProviderConfig{
-					Exclusions:        test.excludes,
-					CatalogingOptions: cataloger.DefaultConfig(),
+					Exclusions:  test.excludes,
+					SBOMOptions: syft.DefaultCreateSBOMConfig(),
 				},
 			}
 			pkgs, _, _, err := Provide(userInput, cfg)
diff --git a/test/integration/match_by_image_test.go b/test/integration/match_by_image_test.go
index fc66b260..1b04b05c 100644
--- a/test/integration/match_by_image_test.go
+++ b/test/integration/match_by_image_test.go
@@ -1,6 +1,7 @@
 package integration
 
 import (
+	"context"
 	"sort"
 	"strings"
 	"testing"
@@ -21,9 +22,9 @@ import (
 	"github.com/anchore/grype/internal/stringutil"
 	"github.com/anchore/stereoscope/pkg/imagetest"
 	"github.com/anchore/syft/syft"
+	"github.com/anchore/syft/syft/cataloging/pkgcataloging"
 	"github.com/anchore/syft/syft/linux"
 	syftPkg "github.com/anchore/syft/syft/pkg"
-	"github.com/anchore/syft/syft/pkg/cataloger"
 	"github.com/anchore/syft/syft/source"
 )
 
@@ -672,14 +673,13 @@ func TestMatchByImage(t *testing.T) {
 			})
 
 			// TODO: relationships are not verified at this time
-			config := cataloger.DefaultConfig()
-			config.Search.Scope = source.SquashedScope
-
 			// enable all catalogers to cover non default cases
-			config.Catalogers = []string{"all"}
+			config := syft.DefaultCreateSBOMConfig().WithCatalogerSelection(pkgcataloging.NewSelectionRequest().WithDefaults("all"))
+			config.Search.Scope = source.SquashedScope
 
-			collection, _, theDistro, err := syft.CatalogPackages(theSource, config)
+			s, err := syft.CreateSBOM(context.Background(), theSource, config)
 			require.NoError(t, err)
+			require.NotNil(t, s)
 
 			matchers := matcher.NewDefaultMatchers(matcher.Config{})
 
@@ -693,7 +693,7 @@ func TestMatchByImage(t *testing.T) {
 				ExclusionProvider: ep,
 			}
 
-			actualResults := grype.FindVulnerabilitiesForPackage(str, theDistro, matchers, pkg.FromCollection(collection, pkg.SynthesisConfig{}))
+			actualResults := grype.FindVulnerabilitiesForPackage(str, s.Artifacts.LinuxDistribution, matchers, pkg.FromCollection(s.Artifacts.Packages, pkg.SynthesisConfig{}))
 			for _, m := range actualResults.Sorted() {
 				for _, d := range m.Details {
 					observedMatchers.Add(string(d.Matcher))
@@ -701,7 +701,7 @@ func TestMatchByImage(t *testing.T) {
 			}
 
 			// build expected matches from what's discovered from the catalog
-			expectedMatches := test.expectedFn(theSource, collection, theStore)
+			expectedMatches := test.expectedFn(theSource, s.Artifacts.Packages, theStore)
 
 			assertMatches(t, expectedMatches.Sorted(), actualResults.Sorted())
 		})
diff --git a/test/integration/utils_test.go b/test/integration/utils_test.go
index 0ec44733..64f6173f 100644
--- a/test/integration/utils_test.go
+++ b/test/integration/utils_test.go
@@ -2,6 +2,7 @@ package integration
 
 import (
 	"bytes"
+	"context"
 	"errors"
 	"fmt"
 	"os"
@@ -16,7 +17,6 @@ import (
 
 	"github.com/anchore/grype/grype/match"
 	"github.com/anchore/syft/syft"
-	"github.com/anchore/syft/syft/pkg/cataloger"
 	"github.com/anchore/syft/syft/sbom"
 	"github.com/anchore/syft/syft/source"
 )
@@ -73,35 +73,26 @@ func saveImage(t testing.TB, imageName string, destPath string) {
 
 func getSyftSBOM(t testing.TB, image string, encoder sbom.FormatEncoder) string {
 	detection, err := source.Detect(image, source.DetectConfig{})
-	if err != nil {
-		t.Fatalf("could not generate source input for packages command: %+v", err)
-	}
+	require.NoError(t, err)
 
 	src, err := detection.NewSource(source.DetectionSourceConfig{})
-	if err != nil {
-		t.Fatalf("can't get the source: %+v", err)
-	}
+	require.NoError(t, err)
+
 	t.Cleanup(func() {
 		require.NoError(t, src.Close())
 	})
 
-	config := cataloger.DefaultConfig()
+	config := syft.DefaultCreateSBOMConfig()
+
 	config.Search.Scope = source.SquashedScope
 	// TODO: relationships are not verified at this time
-	collection, relationships, distro, err := syft.CatalogPackages(src, config)
-
-	s := sbom.SBOM{
-		Artifacts: sbom.Artifacts{
-			Packages:          collection,
-			LinuxDistribution: distro,
-		},
-		Relationships: relationships,
-		Source:        src.Describe(),
-	}
+	s, err := syft.CreateSBOM(context.Background(), src, config)
+	require.NoError(t, err)
+	require.NotNil(t, s)
 
 	var buf bytes.Buffer
 
-	err = encoder.Encode(&buf, s)
+	err = encoder.Encode(&buf, *s)
 	require.NoError(t, err)
 
 	return buf.String()