Reject invalid secret names before any command builds a path (closes #33)
check / check (push) Successful in 49s

`secret rm ..` resolved to the vault directory and deleted the whole
vault; `secret rm .` and `secret rm ""` deleted every secret. rm, mv,
the version commands, encrypt and decrypt built paths from the name
without checking it; import checked it only after reading the source
file.

vault.ValidateSecretName wraps the existing name rule; its error and
README.md state the rule. Each of those commands calls it on the name
as given, before building any path; MoveSecret checks both names once,
for every form of the move, before switching the current vault.
AddSecret, GetSecretVersion and GetSecretObject use it too.

The regression test copies two in-memory vaults for each rejected
command and requires the exact error and an unchanged state directory.

Model: opus-5-5
This commit is contained in:
2026-10-03 14:54:16 +00:00
parent d52b4f1240
commit 720fa80235
8 changed files with 338 additions and 36 deletions
+15
View File
@@ -112,6 +112,11 @@ func VersionCommands(cli *Instance) *cobra.Command {
func (cli *Instance) ListVersions(cmd *cobra.Command, secretName string) error {
secret.Debug("ListVersions called", "secret_name", secretName)
err := vault.ValidateSecretName(secretName)
if err != nil {
return err
}
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -239,6 +244,11 @@ func formatVersionTime(t *time.Time) string {
func (cli *Instance) PromoteVersion(
cmd *cobra.Command, secretName string, version string,
) error {
err := vault.ValidateSecretName(secretName)
if err != nil {
return err
}
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {
@@ -282,6 +292,11 @@ func (cli *Instance) PromoteVersion(
func (cli *Instance) RemoveVersion(
cmd *cobra.Command, secretName string, version string,
) error {
err := vault.ValidateSecretName(secretName)
if err != nil {
return err
}
// Get current vault
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
if err != nil {