From 768bb4abc6dc96fa53346127545f4ac394ce7aed Mon Sep 17 00:00:00 2001 From: bpatra3 Date: Tue, 15 Sep 2026 10:08:56 +0000 Subject: [PATCH] Expose access token environment variable without leaking its value in help output Signed-off-by: bpatra3 --- internal/cmd/root/root.go | 5 ++++- internal/cmd/root/root_test.go | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/internal/cmd/root/root.go b/internal/cmd/root/root.go index a917032c..f478f427 100644 --- a/internal/cmd/root/root.go +++ b/internal/cmd/root/root.go @@ -38,10 +38,13 @@ Complete documentation is available at https://docs.debricked.com/tools-and-inte &accessToken, OldAccessTokenFlag, "t", - viper.GetString(AccessTokenFlag), + "", `Debricked access token. Read more: https://docs.debricked.com/product/administration/generate-access-token`, ) + // Set the env var value directly on the variable (not as the flag's registered default) so it + // isn't echoed back in --help/usage output, while still allowing -t/--access-token to override it. + accessToken = viper.GetString(AccessTokenFlag) var debClient = container.DebClient() debClient.SetAccessToken(&accessToken) diff --git a/internal/cmd/root/root_test.go b/internal/cmd/root/root_test.go index 7f576af2..5dc1ca7f 100644 --- a/internal/cmd/root/root_test.go +++ b/internal/cmd/root/root_test.go @@ -1,6 +1,7 @@ package root import ( + "bytes" "testing" "github.com/debricked/cli/internal/wire" @@ -42,3 +43,41 @@ func TestPreRun(t *testing.T) { cmd := NewRootCmd("", wire.GetCliContainer()) cmd.PreRun(cmd, nil) } + +func TestAccessTokenFlagDoesNotLeakEnvValueAsDefault(t *testing.T) { + t.Setenv("DEBRICKED_TOKEN", "supersecrettoken") + + cmd := NewRootCmd("v0.0.0", wire.GetCliContainer()) + + flag := cmd.PersistentFlags().Lookup(OldAccessTokenFlag) + assert.NotNil(t, flag) + assert.Empty(t, flag.DefValue, "flag default must not expose the env var value") + assert.NotContains(t, cmd.UsageString(), "supersecrettoken") +} + +func TestAccessTokenFallsBackToEnvValue(t *testing.T) { + t.Setenv("DEBRICKED_TOKEN", "env-token") + + NewRootCmd("v0.0.0", wire.GetCliContainer()) + + assert.Equal(t, "env-token", accessToken, "env var must still be used when the flag is omitted") +} + +func TestAccessTokenFlagOverridesEnvValue(t *testing.T) { + cases := []string{"--" + OldAccessTokenFlag, "-t"} + for _, flagName := range cases { + t.Run(flagName, func(t *testing.T) { + t.Setenv("DEBRICKED_TOKEN", "env-token") + + cmd := NewRootCmd("v0.0.0", wire.GetCliContainer()) + output := &bytes.Buffer{} + cmd.SetOut(output) + cmd.SetErr(output) + cmd.SetArgs([]string{flagName, "flag-token"}) + + assert.NoError(t, cmd.Execute()) + assert.Equal(t, "flag-token", accessToken, "flag must take precedence over the env var") + assert.NotContains(t, output.String(), "env-token", "help output must not contain the env var value") + }) + } +}