Skip to content

Add --config-from-file-dir to look up .sops.yaml from the target file's directory - #2322

Open
0x000NULL wants to merge 1 commit into
getsops:mainfrom
0x000NULL:fix/242
Open

0x000NULL wants to merge 1 commit into
getsops:mainfrom
0x000NULL:fix/242

Conversation

@0x000NULL

Copy link
Copy Markdown

sops searches for .sops.yaml starting at the current working directory. If you run sops -e path/to/secret.yaml from somewhere else, the config next to the file is not found.

This adds an opt-in global flag, --config-from-file-dir (env SOPS_CONFIG_FROM_FILE_DIR). When set, the search starts at the directory of the file being operated on and walks up from there, as it does today from the cwd.

On the precedence question raised in the issue: the flag only replaces the starting point of the search. Exactly one config is ever used, two configs are never merged, and --config still wins when given. Without the flag nothing changes, so the current cwd behavior stays the default. Looking in the cwd was an explicit choice in 597acb7 ("Look for config file in cwd, not in the directory of the edited file"), and autrilla's 2017 comment on this issue explains why, so I did not want to change it for everyone.

Details:

  • findConfigFile now takes the target file and uses it as the start when the flag is set. loadConfig and loadStoresConfig already receive the file, so encrypt, decrypt, edit, rotate, set, unset, exec-env, exec-file, filestatus and groups are covered. With --filename-override the override is used, the same path that is matched against path_regex.
  • updatekeys does the lookup per file when the flag is set, since each file may have a different config. A file with no config is reported as a failure and the others still run.
  • publish starts from its argument (a directory argument is searched from inside that directory). With publish --recursive, the destination rules come from the config found for the top-level argument, not per subfile. path_regex in destination rules is still matched against the path as given on the command line, as before.
  • LookupConfigFile used path.Dir/path.Join, which do not handle Windows separators: path.Dir("C:\a\f.yaml") returns ".", which would silently fall back to the cwd. It now uses path/filepath. Behavior for "." and POSIX paths is unchanged.

Testing:

  • New unit test in config that starts the lookup at a nested file path through the existing mock fs.
  • make test in golang:1.25 passes except TestMasterKey_Identities_Passphrase in age, which also fails on main. go vet, make vendor && git diff --exit-code and GOOS=windows go build ./cmd/sops are clean.
  • Manual (also with a path_regex: ^b/ rule in a/.sops.yaml, where encrypt and updatekeys on a/b/secret.yaml match correctly with relative paths; publish a/b/secret.yaml finds the destination): with a/b/.sops.yaml (age rule) and a/b/secret.yaml, running sops -e a/b/secret.yaml from the parent fails with "config file not found, or has no creation rules..." without the flag, and succeeds with --config-from-file-dir and with SOPS_CONFIG_FROM_FILE_DIR=1. With --config other.yaml added, other.yaml is used.

I did not add a cmd-level test, as there is no existing harness for invoking the CLI actions.

Suggested text for getsops/docs (config file section):

By default sops searches for .sops.yaml starting in the current working directory and walking up. Pass --config-from-file-dir (or set SOPS_CONFIG_FROM_FILE_DIR=1) to start the search in the directory of the file you are encrypting, decrypting or editing instead. Only one config file is used; the flag is ignored if --config is given.

Closes #242

…ile's directory.

By default sops looks for .sops.yaml starting at the current working
directory. With the new opt-in flag (or SOPS_CONFIG_FROM_FILE_DIR) the
search starts at the directory of the file being operated on instead, and
walks up from there. The flag only changes the starting point, it never
merges two configs, and --config still takes precedence. Default behavior
is unchanged.

updatekeys looks the config up per file when the flag is set, and publish
starts from its file argument.

Also switch LookupConfigFile from path to path/filepath. path.Dir does not
understand Windows separators, so an absolute Windows file path would have
silently fallen back to the current directory.

Fixes getsops#242

Signed-off-by: Ethan Aldrich <ethan@ethanaldrich.net>
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.

Look for .sops.yaml relative to target

1 participant