Skip to content

feat: warn when picking up .grype.yaml from CWD#3428

Open
ChrisJr404 wants to merge 1 commit into
anchore:mainfrom
ChrisJr404:feat/warn-cwd-config-3427
Open

feat: warn when picking up .grype.yaml from CWD#3428
ChrisJr404 wants to merge 1 commit into
anchore:mainfrom
ChrisJr404:feat/warn-cwd-config-3427

Conversation

@ChrisJr404

Copy link
Copy Markdown

Closes #3427.

Grype's default fangs config search walks the current working directory before ~/.grype.yaml and the XDG locations, so a hidden .grype.yaml (or .grype/config.yaml) sitting in CWD is silently applied. @joshbressers flagged this on the issue: "I'm not entirely comfortable having Grype read a hidden file in the CWD without any sort of warning." This change adds the warning.

What this does

On startup, if grype is about to pick up a config file from CWD via the implicit finder, it logs:

[0000]  WARN using configuration file from current directory: .grype.yaml

The warning suppresses itself when the file came from anywhere explicit:

  • --config / -c <path> (and the --config=path, -c=path, -cpath short forms)
  • GRYPE_CONFIG environment variable
  • ~/.grype.yaml or any XDG config location

It also stays quiet when there's no CWD config to warn about.

Where it lives

A small cmd/grype/cli/internal/configwarn package owns the detection so the logic is unit-testable without the whole config loader stack. The detector uses the same extension list viper supports (yaml, yml, json, toml, properties, etc.) and checks both finder layouts that fangs uses by default: ./.grype.<ext> and ./.grype/config.<ext>.

The hook fires from the existing WithInitializers block in cmd/grype/cli/cli.go, right after the logger is hoisted into place, so the warning goes through the regular logging pipeline (respects --quiet, log file routing, redaction, etc.).

Manual verification

Built locally and verified the four cases:

$ cd /tmp/has-cwd-cfg && grype purl
[0000]  WARN using configuration file from current directory: .grype.yaml
...

$ cd /tmp/has-cwd-cfg && grype -c .grype.yaml purl
[0000] (no warn)
...

$ cd /tmp/has-cwd-cfg && GRYPE_CONFIG=.grype.yaml grype purl
[0000] (no warn)
...

$ cd /tmp/no-cwd-cfg && grype purl
[0000] (no warn)
...

Subdir form (.grype/config.yaml) also fires correctly.

Tests

  • cmd/grype/cli/internal/configwarn/configwarn_test.go covers: no file present, each supported extension, subdir layout, all --config / -c / --config= / -c= / -cpath forms, GRYPE_CONFIG env, and a trailing--c-with-no-value edge case (treated as not explicit, so the warning still fires).
  • go test ./... passes for the whole tree minus pre-existing docker-daemon-required integration tests in this environment (test/integration, test/cli, grype/pkg image fixtures), which fail with "could not build docker image" unrelated to this change.
  • go vet ./cmd/... is clean. The pre-existing vet warnings on grype/db/v5/differ, grype/db/v6/installation, and grype/version are present on main already.

Notes

  • I picked WARN over INFO because the default log level is warn, which matches the spirit of the issue (the user has to actually see it for it to help).
  • Wording: "using configuration file from current directory: " is short and tells the user both that something happened and where to look.

Grype's config search includes the current working directory, so a
hidden .grype.yaml (or .grype/config.yaml) in CWD is silently applied
when you run grype. That's surprising if you wandered into a directory
that happens to contain one, and it's hard to spot when debugging
unexpected scan behaviour.

Emit a WARN-level log on startup naming the picked-up file when the
implicit CWD finder is what produced the config. Stay quiet when the
user passed --config / -c or set GRYPE_CONFIG, and stay quiet when the
config came from the user's home directory or an XDG location.

Closes anchore#3427.

Signed-off-by: ChrisJr404 <chris@hacknow.com>

@willmurphyscode willmurphyscode left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am not sure this is the right approach. Does it make sense instead to hook into actual config parsing in Fangs or Clio and update the behavior there to return a warning if config values are changed?

That would have a couple of advantages:

  1. It would address the issue in other tools, not just grype
  2. If we changed how config file parsing works (e.g. add or remove support for toml, support --configuration-file as an alias for --config, etc.) we wouldn't need to coordinate across repositories.

// It looks for both finder layouts that fangs uses by default:
// - ./.<appName>.<ext>
// - ./.<appName>/config.<ext>
func Detect(appName string, args []string, env func(string) string) string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This just checks whether a file exists, not whether content is loaded from it. Do we want to log.Warn based on file names, or based on unexpectedly loading configs?

// supportedExts mirrors viper.SupportedExts. We hard-code the list rather
// than depend on viper here so this package can be used without pulling the
// configuration loader stack into tests.
var supportedExts = []string{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are formats in here grype doesn't currently support (.ini for one), and we don't want to have to keep this in sync with the formats we support.

// the bundled short form "-cfoo"). We intentionally accept false positives
// here over false negatives: if anything that looks like a config flag is
// present, suppress the warning.
func explicitConfigFlag(args []string) bool {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This duplicates flag parsing elsewhere. If we added --configuration as a valid option in Grype (or Fangs/Clio) we would have a bug here.

return true
case strings.HasPrefix(a, "-c=") && len(a) > 3:
return true
case strings.HasPrefix(a, "-c") && len(a) > 2 && !strings.HasPrefix(a, "--"):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is this case for? when does a have the prefix -c and the prefix --? I feel like I'm missing something here.

@kzantow

kzantow commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

fangs already includes the list of config files being loaded:

% touch .syft.yaml ~/.syft.yaml && go run ./cmd/syft alpine:latest -vv
[0000]  INFO syft version: [not provided]
[0000] DEBUG config:
...
  config: .syft.yaml,/Users/kzantow/.syft.yaml

... so a tool can detect if a config file in the current directory was used fairly easily. Syft has an explicit spot for this config to land that probably needs to get added to grype and then read. I'm pretty sure it can be a []string but isn't in syft for historical reasons and instead concats the files together.

This PR should be adjusted to use this ☝️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Grype reads .grype.yaml from the CWD

3 participants