syft/internal/capabilities/appconfig.yaml
Alex Goodman da745b13e8
feat(golang): add extended-stdlib scope and module patterns for symbol capture (#5154)
* feat(golang): add extended-stdlib scope and include patterns for symbol capture

`golang.capture-symbols` decides how much symbol data lands in the SBOM for grype's reachability analysis. It's `none`, `stdlib`, or `all` today, and the useful middle is missing: `stdlib` stops at the standard library, `all` multiplies SBOM size.

A new `extended-stdlib` configurable covers stdlib plus everything under `golang.org/x/`:

```yaml
golang:
  capture-symbols: extended-stdlib
```

Also, a new `capture-symbols-include` configurable for modules that are noisy in your binaries but not everyone's. It's unioned with whatever the scope selects, so it only ever widens:

```yaml
golang:
  capture-symbols: extended-stdlib
  capture-symbols-include:
    - github.com/klauspost/**
```

Patterns are standard doublestar globs, which matters because module paths carry `/v2`-style suffixes:

```yaml
golang:
  capture-symbols-include:
    - github.com/klauspost/*     # compress, but not compress/v2
    - github.com/klauspost/**    # both
    - k8s.io/client-go           # exact match only
```

Ordering is `none` < `stdlib` < `extended-stdlib` < `all`. The existing three values
and the `none` default are unchanged, and the include list is inert under `none`.
Presets compile into glob lists internally, so a single matcher answers "does this
module get symbols" instead of a preset branch sitting next to a separate glob branch.

An unrecognized `capture-symbols` value still falls back to `none`, but warns now
instead of doing it silently. A malformed include pattern warns and gets skipped.

One thing worth a look beyond the feature: the `Symbols` field description in the JSON
schema was wrong after this (it claimed only `all` and `stdlib` populate anything), and
that description lives in the already-published `16.1.10`. Rather than bump a version for
a sentence, `16.1.10` is amended in place and `schema/json/README.md` grows an explicit
exception for description-only changes: descriptions only, no shape change of any kind,
`$id` unchanged. Anything else still needs a bump. Happy to split that into its own PR if
you'd rather review the policy separately.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor(golang): rename capture-symbols-include to capture-symbols-modules

The key's entries are go module paths, and `-include` sitting next to `capture-symbols` reads as plausibly taking symbol or package names instead. Those spellings parse and match nothing, which is quieter than the confusion `-include` was picked to avoid, so the name now says what the list holds.

`golang.CatalogerConfig.CaptureSymbolsModules` and `WithCaptureSymbolsModules` rename with it. Nothing behavioral changes; the key is new in this PR so there is no compatibility surface.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* feat(golang): match capture-symbols-modules across major version suffixes

`github.com/anchore/*` covered `github.com/anchore/syft` and silently stopped covering it the day it became `github.com/anchore/syft/v2`. The config keeps parsing, nothing warns, and symbols quietly go missing from the SBOM. Exact paths had the same hole: `github.com/klauspost/compress` did not cover `compress/v2` either, so no spelling short of `**` survived a major bump.

A major version suffix is part of a module's path but not part of its identity, so patterns are now matched against the module path both with and without it, using `module.SplitPathVersion` from `golang.org/x/mod` (already a direct dep, already used in this package for `PseudoVersion`).

```yaml
golang:
  capture-symbols-modules:
    - github.com/klauspost/*          # compress and compress/v2
    - github.com/klauspost/compress   # same module at every major version
    - github.com/klauspost/compress/v2  # v2 alone
```

Only a trailing suffix is a version, which is Go's own rule. In `github.com/anchore/syft/v2/thing` the `v2` is an ordinary path element naming a major subdirectory a nested module lives in, so it stays literal and `github.com/anchore/**/thing` is how you reach it. `/v0` and `/v1` are not valid suffixes and are left alone.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-08-07 12:44:42 +00:00

71 lines
6.8 KiB
YAML

# Application-level configuration. See README.md for documentation.
# This file is partially auto-generated. Run 'go generate ./internal/capabilities' to regenerate.
application: # AUTO-GENERATED - application-level config keys
- key: cpp.vcpkg-allow-git-clone
description: enables Syft to use clone remote repositories for vcpkg custom git registries. (also useful if the builtin vcpkg registry is not cloned locally)
- key: dotnet.dep-packages-must-claim-dll
description: only keep dep.json packages which have a runtime/resource DLL claimed in the deps.json targets section (but not necessarily found on disk). The package is also included if any child package claims a DLL, even if the package itself does not claim a DLL.
- key: dotnet.dep-packages-must-have-dll
description: only keep dep.json packages which an executable on disk is found. The package is also included if a DLL is found for any child package, even if the package itself does not have a DLL.
- key: dotnet.exclude-project-references
description: exclude packages with type "project" from deps.json output (these are internal project references, not NuGet packages)
- key: dotnet.propagate-dll-claims-to-parents
description: treat DLL claims or on-disk evidence for child packages as DLL claims or on-disk evidence for any parent package
- key: dotnet.relax-dll-claims-when-bundling-detected
description: show all packages from the deps.json if bundling tooling is present as a dependency (e.g. ILRepack)
- key: golang.capture-symbols
description: 'capture function symbols from the binary symbol table (pclntab). valid values are: "none" (disabled), "stdlib" (only the synthetic stdlib package), "extended-stdlib" (stdlib plus every module under golang.org/x/), and "all" (all module packages plus stdlib)'
- key: golang.capture-symbols-modules
description: glob patterns matched against go module paths (e.g. github.com/klauspost/**) that should have symbols captured in addition to whatever capture-symbols selects. ** crosses path separators, * does not. a trailing major version suffix is ignored when matching, so github.com/foo/* covers github.com/foo/bar/v2; spelling a suffix out in the pattern selects only that major version. this can only widen the selection, never narrow it, and is inert when capture-symbols is none
- key: golang.local-mod-cache-dir
description: specify an explicit go mod cache directory, if unset this defaults to $GOPATH/pkg/mod or $HOME/go/pkg/mod
- key: golang.local-vendor-dir
description: specify an explicit go vendor directory, if unset this defaults to ./vendor
- key: golang.main-module-version.from-build-settings
description: use the build settings (e.g. vcs.version & vcs.time) to craft a v0 pseudo version (e.g. v0.0.0-20220308212642-53e6d0aaf6fb) when a more accurate version cannot be found otherwise
- key: golang.main-module-version.from-contents
description: search for semver-like strings in the binary contents
- key: golang.main-module-version.from-ld-flags
description: look for LD flags that appear to be setting a version (e.g. -X main.version=1.0.0)
- key: golang.no-proxy
description: specifies packages which should not be fetched by proxy if unset this defaults to $GONOPROXY
- key: golang.proxy
description: remote proxy to use when retrieving go packages from the network, if unset this defaults to $GOPROXY followed by https://proxy.golang.org
- key: golang.search-local-mod-cache-licenses
description: search for go package licences in the GOPATH of the system running Syft, note that this is outside the container filesystem and potentially outside the root of a local directory scan
- key: golang.search-local-vendor-licenses
description: search for go package licences in the vendor folder on the system running Syft, note that this is outside the container filesystem and potentially outside the root of a local directory scan
- key: golang.search-remote-licenses
description: search for go package licences by retrieving the package from a network proxy
- key: golang.use-packages-lib
description: use the golang.org/x/tools/go/packages library, which executes golang tooling found on the path in addition to potential network access to get the most accurate results
- key: java.maven-local-repository-dir
description: override the default location of the local Maven repository. the default is the subdirectory '.m2/repository' in your home directory
- key: java.maven-url
description: maven repository to use, defaults to Maven central
- key: java.max-parent-recursive-depth
description: depth to recursively resolve parent POMs, no limit if <= 0
- key: java.resolve-transitive-dependencies
description: resolve transient dependencies such as those defined in a dependency's POM on Maven central
- key: java.use-maven-local-repository
description: 'use the local Maven repository to retrieve pom files. When Maven is installed and was previously used for building the software that is being scanned, then most pom files will be available in this repository on the local file system. this greatly speeds up scans. when all pom files are available in the local repository, then ''use-network'' is not needed. TIP: If you want to download all required pom files to the local repository without running a full build, run ''mvn help:effective-pom'' before performing the scan with syft.'
- key: java.use-network
description: enables Syft to use the network to fetch version and license information for packages when a parent or imported pom file is not found in the local maven repository. the pom files are downloaded from the remote Maven repository at 'maven-url'
- key: javascript.include-dev-dependencies
description: include development-scoped dependencies
- key: javascript.npm-base-url
description: base NPM url to use
- key: javascript.search-remote-licenses
description: enables Syft to use the network to fill in more detailed license information
- key: linux-kernel.catalog-modules
description: whether to catalog linux kernel modules found within lib/modules/** directories
- key: nix.capture-owned-files
description: enumerate all files owned by packages found within Nix store paths
- key: python.guess-unpinned-requirements
description: when running across entries in requirements.txt that do not specify a specific version (e.g. "sqlalchemy >= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0"), attempt to guess what the version could be based on the version requirements specified (e.g. "1.0.0"). When enabled the lowest expressible version when given an arbitrary constraint will be used (even if that version may not be available/published).
- key: python.pypi-base-url
description: base Pypi url to use
- key: python.search-remote-licenses
description: enables Syft to use the network to fill in more detailed license information