Parse the age identity key once and accept every identity in it (closes #165)
check / check (pull_request) Successful in 2m29s
check / check (pull_request) Successful in 2m29s
Restore and verify --deep now parse the configured age secret key a single time through a new internal helper that uses age.ParseIdentities and hands every identity to age.Decrypt. A key file with several identities (a whole age-keygen file) is fully accepted, so a blob encrypted to any of its recipients decrypts, not just the first. The helper is the first step of both commands, so a missing or unparseable key now fails before anything is downloaded. Its error names the configuration source (VAULTIK_AGE_SECRET_KEY or age_secret_key) and never echoes the key value. config.extractAgeSecretKey and its silent fallback are removed; the key is stored raw and parsed only where decryption happens, so backup, list and prune are unaffected. README, the restore help, and the missing-key error now show the key read from a file with $(cat ...) rather than typed literally, keeping it out of shell history, and say the variable may hold the whole key file. Model: opus-4-8
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package cli //nolint:testpackage // exercises the unexported command constructor
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// TestRestoreCommandDoesNotTakeKeyAsArgument guards the fix for the age
|
||||
// key being echoed on the command line: restore must take the key only
|
||||
// from the environment, never as a flag value, and its help must show the
|
||||
// file-based form rather than a literal key that would land in shell
|
||||
// history.
|
||||
func TestRestoreCommandDoesNotTakeKeyAsArgument(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cmd := newSnapshotRestoreCommand()
|
||||
|
||||
cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
||||
lower := strings.ToLower(f.Name)
|
||||
for _, banned := range []string{"key", "secret", "age", "identity"} {
|
||||
if strings.Contains(lower, banned) {
|
||||
t.Errorf("restore must not accept the key as a flag; found --%s", f.Name)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
help := cmd.Long
|
||||
if strings.Contains(help, "AGE-SECRET-KEY-") {
|
||||
t.Error("restore help must not show a literal age private key to type")
|
||||
}
|
||||
|
||||
if !strings.Contains(help, "$(cat ") {
|
||||
t.Error("restore help should read the key from a file, e.g. $(cat ...)")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user