Skip to content

scan: make max db allowed build age configurable #1677

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

Merged
merged 4 commits into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
25 changes: 13 additions & 12 deletions docs/cmd/wolfictl_scan.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,19 @@ wolfictl scan package1 package2 --remote
### Options

```
-a, --advisories-repo-dir string directory containing the advisories repository
-f, --advisory-filter string exclude vulnerability matches that are referenced from the specified set of advisories (resolved|all|concluded)
--build-log treat input as a package build log file (or a directory that contains a packages.log file)
-D, --disable-sbom-cache don't use the SBOM cache
--distro string distro to use during vulnerability matching (default "wolfi")
-h, --help help for scan
--local-file-grype-db string import a local grype db file
-o, --output string output format (outline|json), defaults to outline
-r, --remote treat input(s) as the name(s) of package(s) in the Wolfi package repository to download and scan the latest versions of
--require-zero exit 1 if any vulnerabilities are found
-s, --sbom treat input(s) as SBOM(s) of APK(s) instead of as actual APK(s)
--use-cpes turn on all CPE matching in Grype
-a, --advisories-repo-dir string directory containing the advisories repository
-f, --advisory-filter string exclude vulnerability matches that are referenced from the specified set of advisories (resolved|all|concluded)
--build-log treat input as a package build log file (or a directory that contains a packages.log file)
-D, --disable-sbom-cache don't use the SBOM cache
--distro string distro to use during vulnerability matching (default "wolfi")
-h, --help help for scan
--local-file-grype-db string import a local grype db file
--max-allowed-built-age duration Max allowed age for vulnerability database, age being the time since it was built. Default max age is 120h (or five days) (default 120h0m0s)
-o, --output string output format (outline|json), defaults to outline
-r, --remote treat input(s) as the name(s) of package(s) in the Wolfi package repository to download and scan the latest versions of
--require-zero exit 1 if any vulnerabilities are found
-s, --sbom treat input(s) as SBOM(s) of APK(s) instead of as actual APK(s)
--use-cpes turn on all CPE matching in Grype
```

### Options inherited from parent commands
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/wolfictl-scan.1
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ found and the \-\-require\-zero flag is specified.
\fB\-\-local\-file\-grype\-db\fP=""
import a local grype db file

.PP
\fB\-\-max\-allowed\-built\-age\fP=120h0m0s
Max allowed age for vulnerability database, age being the time since it was built. Default max age is 120h (or five days)

.PP
\fB\-o\fP, \fB\-\-output\fP=""
output format (outline|json), defaults to outline
Expand Down
6 changes: 6 additions & 0 deletions pkg/cli/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"sort"
"strings"
"sync"
"time"

"chainguard.dev/apko/pkg/apk/apk"
"chainguard.dev/apko/pkg/apk/auth"
Expand Down Expand Up @@ -235,6 +236,9 @@ func scanEverything(ctx context.Context, p *scanParams, inputs []string, advGett
opts := scan.DefaultOptions
opts.UseCPEs = p.useCPEMatching
opts.PathOfDatabaseArchiveToImport = p.localDBFilePath
if p.dbMaxAllowedBuildAge > 0 {
opts.MaxAllowedBuildAge = p.dbMaxAllowedBuildAge
}

// Immediately start a goroutine, so we can initialize the vulnerability database.
// Once that's finished, we will start to pull sboms off of done as they become ready.
Expand Down Expand Up @@ -338,6 +342,7 @@ type scanParams struct {
disableSBOMCache bool
remoteScanning bool
useCPEMatching bool
dbMaxAllowedBuildAge time.Duration
}

func (p *scanParams) addFlagsTo(cmd *cobra.Command) {
Expand All @@ -352,6 +357,7 @@ func (p *scanParams) addFlagsTo(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&p.disableSBOMCache, "disable-sbom-cache", "D", false, "don't use the SBOM cache")
cmd.Flags().BoolVarP(&p.remoteScanning, "remote", "r", false, "treat input(s) as the name(s) of package(s) in the Wolfi package repository to download and scan the latest versions of")
cmd.Flags().BoolVar(&p.useCPEMatching, "use-cpes", false, "turn on all CPE matching in Grype")
cmd.Flags().DurationVar(&p.dbMaxAllowedBuildAge, "max-allowed-built-age", 120*time.Hour, "Max allowed age for vulnerability database, age being the time since it was built. Default max age is 120h (or five days)")
}

func (p *scanParams) resolveInputsToScan(ctx context.Context, args []string) (inputs []string, cleanup func() error, err error) {
Expand Down
17 changes: 15 additions & 2 deletions pkg/scan/apk.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,22 @@ type Options struct {
// except for testing purposes.
DisableDatabaseAgeValidation bool

// MaxAllowedBuildAge defines the maximum allowed age for the vulnerability database.
// If the database is older than this duration, it will be considered invalid unless
// DisableDatabaseAgeValidation is set to true. If not specified, the default value
// of 48 hours will be used.
MaxAllowedBuildAge time.Duration

// DisableSBOMCache controls whether the scanner will cache SBOMs generated from
// APKs. If true, the scanner will not cache SBOMs or use existing cached SBOMs.
DisableSBOMCache bool
}

// DefaultOptions is the recommended default configuration for a new Scanner.
// These options are suitable for most use scanning cases.
var DefaultOptions = Options{}
var DefaultOptions = Options{
MaxAllowedBuildAge: 120 * time.Hour,
Copy link
Contributor

Choose a reason for hiding this comment

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

are we planning to keep the 120 permanently or temporary?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a temporary change, I've added a warning suggesting a recommended age. I also added a note to the code.

Copy link
Contributor

Choose a reason for hiding this comment

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

this seems really confusing
we have a recommended age of 48hrs, but default to 120hrs

i guess until we better understand the reasoning behind the 48hr
i would recommend keeping the default behavior and allowing users to avoid it as necessary
rather than setting a new default that really shouldnt be the default

}

// NewScanner initializes the grype DB for reuse across multiple scans.
func NewScanner(opts Options) (*Scanner, error) {
Expand All @@ -182,11 +190,16 @@ func NewScanner(opts Options) (*Scanner, error) {
dbDestDir = DefaultGrypeDBDir
}

maxAllowedBuildAge := opts.MaxAllowedBuildAge
if maxAllowedBuildAge == 0 {
maxAllowedBuildAge = 120 * time.Hour
}

installCfg := installation.Config{
DBRootDir: dbDestDir,
ValidateChecksum: true,
ValidateAge: !opts.DisableDatabaseAgeValidation,
MaxAllowedBuiltAge: 48 * time.Hour,
MaxAllowedBuiltAge: maxAllowedBuildAge,
UpdateCheckMaxFrequency: 1 * time.Hour,
}

Expand Down