1
0
mirror of https://github.com/getsops/sops.git synced 2026-02-05 12:45:21 +01:00

Pass SOPS_AGE_RECIPIENT environment variable to SOPS_AGE_KEY_CMD

Signed-off-by: Defelo <mail@defelo.de>
This commit is contained in:
Defelo
2026-01-21 22:27:47 +01:00
parent 3ef80dceac
commit e86db7cf72
3 changed files with 29 additions and 2 deletions

View File

@@ -241,7 +241,8 @@ You can override the default lookup by:
- setting the environment variable **SOPS_AGE_KEY_FILE**; - setting the environment variable **SOPS_AGE_KEY_FILE**;
- setting the **SOPS_AGE_KEY** environment variable; - setting the **SOPS_AGE_KEY** environment variable;
- providing a command to output the age keys by setting the **SOPS_AGE_KEY_CMD** environment variable.. - providing a command to output the age keys by setting the **SOPS_AGE_KEY_CMD** environment variable.
This command can read the age recipient for which to return the private key from the **SOPS_AGE_RECIPIENT** environment variable.
The contents of this key file should be a list of age X25519 identities, one The contents of this key file should be a list of age X25519 identities, one
per line. Lines beginning with ``#`` are considered comments and ignored. Each per line. Lines beginning with ``#`` are considered comments and ignored. Each

View File

@@ -32,6 +32,10 @@ const (
// SopsAgeKeyCmdEnv can be set as an environment variable with a command // SopsAgeKeyCmdEnv can be set as an environment variable with a command
// to execute that returns the age keys. // to execute that returns the age keys.
SopsAgeKeyCmdEnv = "SOPS_AGE_KEY_CMD" SopsAgeKeyCmdEnv = "SOPS_AGE_KEY_CMD"
// SopsAgeRecipientEnv is passed as an environment variable to the command
// set in SopsAgeKeyCmdEnv and contains the Bech32-encoded age public key
// for which the private key should be returned.
SopsAgeRecipientEnv = "SOPS_AGE_RECIPIENT"
// SopsAgeSshPrivateKeyFileEnv can be set as an environment variable pointing to // SopsAgeSshPrivateKeyFileEnv can be set as an environment variable pointing to
// a private SSH key file. // a private SSH key file.
SopsAgeSshPrivateKeyFileEnv = "SOPS_AGE_SSH_PRIVATE_KEY_FILE" SopsAgeSshPrivateKeyFileEnv = "SOPS_AGE_SSH_PRIVATE_KEY_FILE"
@@ -382,7 +386,9 @@ func (key *MasterKey) loadIdentities() (ParsedIdentities, []string, errSet) {
if err != nil { if err != nil {
errs = append(errs, fmt.Errorf("failed to parse command %s from %s: %w", ageKeyCmd, SopsAgeKeyCmdEnv, err)) errs = append(errs, fmt.Errorf("failed to parse command %s from %s: %w", ageKeyCmd, SopsAgeKeyCmdEnv, err))
} else { } else {
out, err := exec.Command(args[0], args[1:]...).Output() cmd := exec.Command(args[0], args[1:]...)
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", SopsAgeRecipientEnv, key.Recipient))
out, err := cmd.Output()
if err != nil { if err != nil {
errs = append(errs, fmt.Errorf("failed to execute command %s from %s: %w", ageKeyCmd, SopsAgeKeyCmdEnv, err)) errs = append(errs, fmt.Errorf("failed to execute command %s from %s: %w", ageKeyCmd, SopsAgeKeyCmdEnv, err))
} else { } else {

View File

@@ -510,6 +510,26 @@ func TestMasterKey_loadIdentities(t *testing.T) {
assert.Len(t, unusedLocations, 5) assert.Len(t, unusedLocations, 5)
}) })
t.Run(SopsAgeRecipientEnv, func(t *testing.T) {
tmpDir := t.TempDir()
// Overwrite to ensure local config is not picked up by tests
overwriteUserConfigDir(t, tmpDir)
t.Setenv(SopsAgeKeyCmdEnv, fmt.Sprintf("bash -c 'if [[ $SOPS_AGE_RECIPIENT = %s ]]; then echo %s; fi'", mockRecipient, mockIdentity))
key := &MasterKey{Recipient: mockRecipient}
got, unusedLocations, errs := key.loadIdentities()
assert.Len(t, errs, 0)
assert.Len(t, got, 1)
assert.Len(t, unusedLocations, 5)
key = &MasterKey{Recipient: mockRecipient + "abc"}
got, unusedLocations, errs = key.loadIdentities()
assert.Len(t, errs, 0)
assert.Len(t, got, 0)
assert.Len(t, unusedLocations, 6)
})
t.Run("cmd error", func(t *testing.T) { t.Run("cmd error", func(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
// Overwrite to ensure local config is not picked up by tests // Overwrite to ensure local config is not picked up by tests