Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable v6 database #2439

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3a336ab
feat: enable v6 database
kzantow Feb 11, 2025
f958241
chore: update some tests
kzantow Feb 11, 2025
b04dd62
chore: update URLs and docs
kzantow Feb 11, 2025
59af7cd
chore: update yardstick
kzantow Feb 12, 2025
c3848db
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 12, 2025
8ff1271
chore: update tests
kzantow Feb 12, 2025
f22c78c
fix: only log matcher errors
kzantow Feb 12, 2025
43cf25c
Merge branch 'fix/vulnerability-matcher-errors' into feat/v6
kzantow Feb 12, 2025
09ad2a3
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 12, 2025
6eaa028
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 13, 2025
0220aef
add details around DB deprecations
wagoodman Feb 13, 2025
9c00e1a
fix quality gate
wagoodman Feb 13, 2025
376986a
fix: filter unknown fix states
kzantow Feb 13, 2025
fde9506
chore: update tests
kzantow Feb 13, 2025
8a655b5
chore: update fix state unknown ignore rule
kzantow Feb 13, 2025
edfd2dc
fix: rpm modularity qualifiers in v6
kzantow Feb 13, 2025
c7c1213
fix: fail command when update check fails
kzantow Feb 13, 2025
c360e1b
allow for importing a db file
wagoodman Feb 14, 2025
cd26673
fix --by-cve
wagoodman Feb 14, 2025
536e491
fix: db update check tests
kzantow Feb 14, 2025
43cae40
chore: nil check
kzantow Feb 16, 2025
de934e2
Merge remote-tracking branch 'origin/main' into feat/v6
wagoodman Feb 18, 2025
af68a2f
fix jenkins plugin matching within client lookup
wagoodman Feb 18, 2025
d06d6cc
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 18, 2025
3b9a169
chore: update tests
kzantow Feb 18, 2025
2f25035
chore: update test db and match labels
kzantow Feb 18, 2025
bc66762
db list should be an array
wagoodman Feb 18, 2025
7b6f73e
fix: db update behaviors
kzantow Feb 20, 2025
b9e5416
chore: update test
kzantow Feb 20, 2025
8df035e
chore: add path to db status on errors
kzantow Feb 20, 2025
29496a6
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 20, 2025
784868a
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 20, 2025
1292091
chore: fix merge issues
kzantow Feb 21, 2025
4eaf2fd
chore: fix db update procedure, add tests, remove duplicate configura…
kzantow Feb 21, 2025
5cf2fee
chore: add db validation tests for hydration
kzantow Feb 21, 2025
6583010
chore: update tests
kzantow Feb 21, 2025
7282dc2
chore: improve latestURL + tests
kzantow Feb 21, 2025
1d1f292
chore: cleanup
kzantow Feb 21, 2025
46061fe
Merge remote-tracking branch 'origin/main' into feat/v6
wagoodman Feb 24, 2025
86c8ba2
chore: add test to ensure explicit ignores are working
kzantow Feb 24, 2025
4407668
fix: corrupt db re-downloads
kzantow Feb 24, 2025
13dd2ff
Merge remote-tracking branch 'origin/main' into feat/v6
wagoodman Feb 24, 2025
8ad1957
explicitly translate nvd cvss type to v6 rank
wagoodman Feb 25, 2025
000f3e1
Merge remote-tracking branch 'origin/main' into feat/v6
kzantow Feb 26, 2025
7b99947
allow for packages and cpes to be many to many
wagoodman Feb 26, 2025
a80d7b7
ensure fetching vuln decorators leverages nocase indexes
wagoodman Feb 26, 2025
10cd0bc
infer pkg type for cpe provider
wagoodman Feb 27, 2025
003e597
match on cpe any attributes when specific is provided
wagoodman Feb 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,17 @@ grype --add-cpes-if-none --distro alpine:3.10 sbom:some-alpine-3.10.spdx.json

### Supported versions

Any version of Grype before v0.51.0 (Oct 2022) is not supported. Unsupported releases will not receive any software updates or
Software updates are always applied to the latest version of Grype; fixes are not backported to any previous versions of Grype.

In terms of database updates, any version of Grype before v0.51.0 (Oct 2022, before schema v5) will not receive
vulnerability database updates. You can still build vulnerability databases for unsupported Grype releases by using previous
releases of [vunnel](https://github.com/anchore/vunnel) to gather the upstream data and [grype-db](https://github.com/anchore/grype-db)
to build databases for unsupported schemas.

Only the latest database schema is considered to be supported. When a new database schema is introduced then the one it replaces is
marked as deprecated. Deprecated schemas will continue to receive updates for at least one year after they are marked
as deprecated at which point they will no longer be supported.

### Working with attestations
Grype supports scanning SBOMs as input via stdin. Users can use [cosign](https://github.com/sigstore/cosign) to verify attestations
with an SBOM as its content to scan an image for vulnerabilities:
Expand Down Expand Up @@ -515,32 +521,33 @@ By default, Grype automatically manages this database for you. Grype checks for

Grype's vulnerability database is a SQLite file, named `vulnerability.db`. Updates to the database are atomic: the entire database is replaced and then treated as "readonly" by Grype.

Grype's first step in a database update is discovering databases that are available for retrieval. Grype does this by requesting a "listing file" from a public endpoint:
Grype's first step in a database update is discovering databases that are available for retrieval. Grype does this by requesting a "latest database file" from a public endpoint:

`https://toolbox-data.anchore.io/grype/databases/listing.json`
https://grype.anchore.io/databases/v6/latest.json

The listing file contains entries for every database that's available for download.
The latest database file contains an entry for the most recent database available for download.

Here's an example of an entry in the listing file:
Here's an example of an entry in the latest database file:

```json
{
"built": "2021-10-21T08:13:41Z",
"version": 3,
"url": "https://toolbox-data.anchore.io/grype/databases/vulnerability-db_v3_2021-10-21T08:13:41Z.tar.gz",
"checksum": "sha256:8c99fb4e516f10b304f026267c2a73a474e2df878a59bf688cfb0f094bfe7a91"
"status": "active",
"schemaVersion": "6.0.0",
"built": "2025-02-11T04:06:41Z",
"path": "vulnerability-db_v6.0.0_2025-02-11T01:30:51Z_1739246801.tar.zst",
"checksum": "sha256:79bfa04265c5a32d21773ad0da1bda13c31e932fa1e1422db635c8d714038868"
}
```

With this information, Grype can select the correct database (the most recently built database with the current schema version), download the database, and verify the database's integrity using the listed `checksum` value.
With this information, Grype can find the most recently built database with the current schema version, download the database, and verify the database's integrity using the `checksum` value.

### Managing Grype's database

> **Note:** During normal usage, _there is no need for users to manage Grype's database!_ Grype manages its database behind the scenes. However, for users that need more control, Grype provides options to manage the database more explicitly.

#### Local database cache directory

By default, the database is cached on the local filesystem in the directory `$XDG_CACHE_HOME/grype/db/<SCHEMA-VERSION>/`. For example, on macOS, the database would be stored in `~/Library/Caches/grype/db/3/`. (For more information on XDG paths, refer to the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).)
By default, the database is cached on the local filesystem in the directory `$XDG_CACHE_HOME/grype/db/<SCHEMA-VERSION>/`. For example, on macOS, the database would be stored in `~/Library/Caches/grype/db/6/`. (For more information on XDG paths, refer to the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).)

You can set the cache directory path using the environment variable `GRYPE_DB_CACHE_DIR`. If setting that variable alone does not work, then the `TMPDIR` environment variable might also need to be set.

Expand All @@ -550,11 +557,13 @@ Grype needs up-to-date vulnerability information to provide accurate matches. By

#### Offline and air-gapped environments

By default, Grype checks for a new database on every run, by making a network call over the Internet. You can tell Grype not to perform this check by setting the environment variable `GRYPE_DB_AUTO_UPDATE` to `false`.
By default, Grype checks for a new database on every run, by making a network request over the internet.
You can tell Grype not to perform this check by setting the environment variable `GRYPE_DB_AUTO_UPDATE` to `false`.

As long as you place Grype's `vulnerability.db` and `metadata.json` files in the cache directory for the expected schema version, Grype has no need to access the network. Additionally, you can get a listing of the database archives available for download from the `grype db list` command in an online environment, download the database archive, transfer it to your offline environment, and use `grype db import <db-archive-path>` to use the given database in an offline capacity.
As long as you place Grype's `vulnerability.db` and `import.json` files in the cache directory for the expected schema version, Grype has no need to access the network.
Additionally, you can get a reference to the latest database archive for download from the `grype db list` command in an online environment, download the database archive, transfer it to your offline environment, and use `grype db import <db-archive-path>` to use the given database in an offline capacity.

If you would like to distribute your own Grype databases internally without needing to use `db import` manually you can leverage Grype's DB update mechanism. To do this you can craft your own `listing.json` file similar to the one found publically (see `grype db list -o raw` for an example of our public `listing.json` file) and change the download URL to point to an internal endpoint (e.g. a private S3 bucket, an internal file server, etc). Any internal installation of Grype can receive database updates automatically by configuring the `db.update-url` (same as the `GRYPE_DB_UPDATE_URL` environment variable) to point to the hosted `listing.json` file you've crafted.
If you would like to distribute your own Grype databases internally without needing to use `db import` manually you can leverage Grype's DB update mechanism. To do this you can craft your own `latest.json` file similar to the public "latest database file" and change the download URL to point to an internal endpoint (e.g. a private S3 bucket, an internal file server, etc.). Any internal installation of Grype can receive database updates automatically by configuring the `db.update-url` (same as the `GRYPE_DB_UPDATE_URL` environment variable) to point to the hosted `latest.json` file you've crafted.

#### CLI commands for database management

Expand All @@ -566,7 +575,7 @@ Grype provides database-specific CLI commands for users that want to control the

`grype db update` — ensure the latest database has been downloaded to the cache directory (Grype performs this operation at the beginning of every scan by default)

`grype db list` — download the listing file configured at `db.update-url` and show databases that are available for download
`grype db list` — download the latest database file configured at `db.update-url` and show the database available for download

`grype db import` — provide grype with a database archive to explicitly use (useful for offline DB updates)

Expand Down Expand Up @@ -758,7 +767,7 @@ db:

# URL of the vulnerability database
# same as GRYPE_DB_UPDATE_URL env var
update-url: "https://toolbox-data.anchore.io/grype/databases/listing.json"
update-url: "https://grype.anchore.io/databases"

# it ensures db build is no older than the max-allowed-built-age
# set to false to disable check
Expand Down
2 changes: 1 addition & 1 deletion Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ tasks:
update-quality-gate-db:
desc: Update pinned version of quality gate database
cmds:
- cmd: "go run cmd/grype/main.go db list -o json | jq -r .[0].url > test/quality/test-db-url"
- cmd: "go run cmd/grype/main.go db list -o json | jq -r '.[0].path' > test/quality/test-db"
silent: true

list-tools:
Expand Down
4 changes: 2 additions & 2 deletions cmd/grype/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/anchore/grype/cmd/grype/cli/commands"
grypeHandler "github.com/anchore/grype/cmd/grype/cli/ui"
"github.com/anchore/grype/cmd/grype/internal/ui"
"github.com/anchore/grype/grype/db"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/internal/bus"
"github.com/anchore/grype/internal/log"
"github.com/anchore/grype/internal/redact"
Expand Down Expand Up @@ -106,5 +106,5 @@ func syftVersion() (string, any) {
}

func dbVersion() (string, any) {
return "Supported DB Schema", db.SchemaVersion
return "Supported DB Schema", v6.ModelVersion
}
1 change: 0 additions & 1 deletion cmd/grype/cli/commands/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ func DB(app clio.Application) *cobra.Command {
db.AddCommand(
DBCheck(app),
DBDelete(app),
DBDiff(app),
DBImport(app),
DBList(app),
DBStatus(app),
Expand Down
66 changes: 0 additions & 66 deletions cmd/grype/cli/commands/db_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (

"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
legacyDistribution "github.com/anchore/grype/grype/db/v5/distribution"
db "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/internal/log"
Expand Down Expand Up @@ -61,13 +60,6 @@ func DBCheck(app clio.Application) *cobra.Command {
}

func runDBCheck(opts dbCheckOptions) error {
if opts.DatabaseCommand.Experimental.DBv6 {
return newDBCheck(opts)
}
return legacyDBCheck(opts)
}

func newDBCheck(opts dbCheckOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
Expand Down Expand Up @@ -138,61 +130,3 @@ func presentNewDBCheck(format string, writer io.Writer, updateAvailable bool, cu
}
return nil
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// all legacy processing below ////////////////////////////////////////////////////////////////////////////////////////

type legacyDBCheckJSON struct {
CurrentDB *legacyDistribution.Metadata `json:"currentDB"`
CandidateDB *legacyDistribution.ListingEntry `json:"candidateDB"`
UpdateAvailable bool `json:"updateAvailable"`
}

func legacyDBCheck(opts dbCheckOptions) error {
dbCurator, err := legacyDistribution.NewCurator(opts.ToLegacyCuratorConfig())
if err != nil {
return err
}

updateAvailable, currentDBMetadata, updateDBEntry, err := dbCurator.IsUpdateAvailable()
if err != nil {
return fmt.Errorf("unable to check for vulnerability database update: %+v", err)
}

switch opts.Output {
case textOutputFormat:
if currentDBMetadata != nil {
fmt.Printf("Current DB version %d was built on %s\n", currentDBMetadata.Version, currentDBMetadata.Built.String())
}

if !updateAvailable {
fmt.Println("No update available")
return nil
}

fmt.Printf("Updated DB version %d was built on %s\n", updateDBEntry.Version, updateDBEntry.Built.String())
fmt.Printf("Updated DB URL: %s\n", updateDBEntry.URL.String())
fmt.Println("You can run 'grype db update' to update to the latest db")
case jsonOutputFormat:
data := legacyDBCheckJSON{
CurrentDB: currentDBMetadata,
CandidateDB: updateDBEntry,
UpdateAvailable: updateAvailable,
}

enc := json.NewEncoder(os.Stdout)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(&data); err != nil {
return fmt.Errorf("failed to db listing information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", opts.Output)
}

if updateAvailable {
os.Exit(exitCodeOnDBUpgradeAvailable) //nolint:gocritic
}

return nil
}
20 changes: 0 additions & 20 deletions cmd/grype/cli/commands/db_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
legacyDistribution "github.com/anchore/grype/grype/db/v5/distribution"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
)
Expand All @@ -34,13 +33,6 @@ func DBDelete(app clio.Application) *cobra.Command {
}

func runDBDelete(opts options.DatabaseCommand) error {
if opts.Experimental.DBv6 {
return newDBDelete(opts)
}
return legacyDBDelete(opts)
}

func newDBDelete(opts options.DatabaseCommand) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
Expand All @@ -56,15 +48,3 @@ func newDBDelete(opts options.DatabaseCommand) error {

return stderrPrintLnf("Vulnerability database deleted")
}

func legacyDBDelete(opts options.DatabaseCommand) error {
dbCurator, err := legacyDistribution.NewCurator(opts.ToLegacyCuratorConfig())
if err != nil {
return err
}
if err := dbCurator.Delete(); err != nil {
return fmt.Errorf("unable to delete vulnerability database: %+v", err)
}

return stderrPrintLnf("Vulnerability database deleted")
}
135 changes: 0 additions & 135 deletions cmd/grype/cli/commands/db_diff.go

This file was deleted.

Loading
Loading