Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/profiles/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ func createNewDisplay(bin string, ca, cert, key []byte, profile *types.Profile,
grabberShortcut())
}

slog.Debug("exec", "binary", bin, "args", dockerArgs)
slog.Debug("exec", "binary", bin, "args", container.RedactEnvArgs(dockerArgs))
cmd := execabs.Command(bin, dockerArgs...)
cmd.Env = append(cmd.Env, os.Environ()...)

Expand Down
2 changes: 1 addition & 1 deletion internal/runners/docker/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func Run(ew types.EffectiveWorkload) error {
args = append(args, wl.Command)
args = append(args, wl.Args...)

slog.Debug("exec", "binary", runnerBinary, "args", args)
slog.Debug("exec", "binary", runnerBinary, "args", container.RedactEnvArgs(args))
cmd := execabs.Command(runnerBinary, args...)

if ew.Workload.HostAccess.Mime {
Expand Down
2 changes: 1 addition & 1 deletion internal/runners/podman/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ func Run(ew types.EffectiveWorkload) error {
args = append(args, wl.Command)
args = append(args, wl.Args...)

slog.Debug("exec", "binary", runnerBinary, "args", args)
slog.Debug("exec", "binary", runnerBinary, "args", container.RedactEnvArgs(args))
cmd := execabs.Command(runnerBinary, args...)

if ew.Workload.HostAccess.Mime {
Expand Down
41 changes: 41 additions & 0 deletions internal/runners/util/container/redact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package container

import "strings"

const redactedEnvValue = "REDACTED"

// RedactEnvArgs returns a copy of container runner arguments with explicit
// environment variable values removed. The original arguments are left
// untouched so callers can safely use the result for logging and the original
// slice for execution.
func RedactEnvArgs(args []string) []string {
redacted := append([]string(nil), args...)

for i := 0; i < len(redacted); i++ {
switch redacted[i] {
case "-e", "--env":
if i+1 < len(redacted) {
redacted[i+1] = redactEnvSpec(redacted[i+1])
i++
}
default:
for _, prefix := range []string{"-e=", "--env="} {
if spec, ok := strings.CutPrefix(redacted[i], prefix); ok {
redacted[i] = prefix + redactEnvSpec(spec)
break
}
}
}
}

return redacted
}
Comment on lines +11 to +32

func redactEnvSpec(spec string) string {
name, _, ok := strings.Cut(spec, "=")
if !ok {
return spec
}

return name + "=" + redactedEnvValue
}
64 changes: 64 additions & 0 deletions internal/runners/util/container/redact_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package container

import (
"reflect"
"testing"
)

func TestRedactEnvArgs(t *testing.T) {
t.Parallel()

tests := []struct {
name string
args []string
want []string
}{
{
name: "short flag with separate value",
args: []string{"run", "-e", "TOKEN=secret", "image"},
want: []string{"run", "-e", "TOKEN=REDACTED", "image"},
},
{
name: "long flag with separate value",
args: []string{"run", "--env", "PASSWORD=two=parts", "image"},
want: []string{"run", "--env", "PASSWORD=REDACTED", "image"},
},
{
name: "short flag with inline value",
args: []string{"run", "-e=API_KEY=secret", "image"},
want: []string{"run", "-e=API_KEY=REDACTED", "image"},
},
{
name: "long flag with inline value",
args: []string{"run", "--env=CLIENT_SECRET=secret", "image"},
want: []string{"run", "--env=CLIENT_SECRET=REDACTED", "image"},
},
{
name: "inherited environment variable",
args: []string{"run", "-e", "TOKEN", "--env=PASSWORD", "image"},
want: []string{"run", "-e", "TOKEN", "--env=PASSWORD", "image"},
},
{
name: "unrelated arguments",
args: []string{"run", "--entrypoint=/bin/env", "image", "TOKEN=secret"},
want: []string{"run", "--entrypoint=/bin/env", "image", "TOKEN=secret"},
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

original := append([]string(nil), tc.args...)
got := RedactEnvArgs(tc.args)

if !reflect.DeepEqual(got, tc.want) {
t.Fatalf("RedactEnvArgs() = %q, want %q", got, tc.want)
}
if !reflect.DeepEqual(tc.args, original) {
t.Fatalf("RedactEnvArgs() mutated input: got %q, want %q", tc.args, original)
}
})
}
}
Loading