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
21 changes: 19 additions & 2 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,13 +223,19 @@ func flagsToLogFields(flags *pflag.FlagSet) []z.Field {
return fields
}

// redact returns a redacted version of the given flag value. It currently supports redacting
// passwords in valid URLs provided in ".*address.*" flags and redacting auth tokens.
// redact returns a redacted version of the given flag value. It supports:
// - Full redaction of auth token flags (e.g., keymanager-auth-token)
// - Value redaction of header flags (e.g., beacon-node-headers, otlp-headers) keeping keys visible
// - Password redaction in URLs for address flags (e.g., loki-addresses)
func redact(flag, val string) string {
if strings.Contains(flag, "auth-token") {
return "xxxxx"
}

if strings.Contains(flag, "header") {
return redactHeaderValue(val)
}

if !strings.Contains(flag, "address") {
return val
}
Expand All @@ -241,3 +247,14 @@ func redact(flag, val string) string {

return u.Redacted()
}

// redactHeaderValue redacts the value portion of a "key=value" header string,
// preserving the key for debuggability. E.g., "Authorization=Basic abc123" becomes "Authorization=xxxxx".
func redactHeaderValue(val string) string {
key, _, ok := strings.Cut(val, "=")
if !ok {
return val
}

return key + "=xxxxx"
}
37 changes: 37 additions & 0 deletions cmd/cmd_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,25 @@ func TestFlagsToLogFields(t *testing.T) {
}
}

func TestFlagsToLogFieldsRedactsHeaders(t *testing.T) {
set := pflag.NewFlagSet("test", pflag.PanicOnError)
set.StringSlice("beacon-node-headers", nil, "")
err := set.Parse([]string{
"--beacon-node-headers=Authorization=Basic b2JvbDpzZWNyZXQ=",
})
require.NoError(t, err)

for _, field := range flagsToLogFields(set) {
field(func(f zap.Field) {
if f.Key != "beacon-node-headers" {
return
}
require.NotContains(t, f.String, "b2JvbDpzZWNyZXQ=")
require.Contains(t, f.String, "Authorization=xxxxx")
})
}
}

func TestRedact(t *testing.T) {
tests := []struct {
name string
Expand All @@ -249,6 +268,24 @@ func TestRedact(t *testing.T) {
value: "https://obol.obol.tech/dv/0x0f481bbd06a596cb3ba569b9de0cbfcf822b209c2d6877c98173df986dd3c0ec",
expected: "https://obol.obol.tech/dv/0x0f481bbd06a596cb3ba569b9de0cbfcf822b209c2d6877c98173df986dd3c0ec",
},
{
name: "redact beacon-node-headers value",
flag: "beacon-node-headers",
value: "Authorization=Basic b2JvbDpzZWNyZXQ=",
expected: "Authorization=xxxxx",
},
{
name: "redact otlp-headers value",
flag: "otlp-headers",
value: "X-Api-Key=secret-api-key-12345",
expected: "X-Api-Key=xxxxx",
},
{
name: "header without value passes through",
flag: "beacon-node-headers",
value: "X-No-Value",
expected: "X-No-Value",
},
}

for _, tt := range tests {
Expand Down
6 changes: 2 additions & 4 deletions cmd/exit_fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,11 @@ func newFetchExitCmd(runFunc func(context.Context, exitConfig) error) *cobra.Com
valPubkPresent := cmd.Flags().Lookup(validatorPubkey.String()).Changed

if !valPubkPresent && !config.All {
//nolint:revive,perfsprint // we use our own version of the errors package; keep consistency with other checks.
return errors.New(fmt.Sprintf("%s must be specified when exiting single validator.", validatorPubkey.String()))
return errors.New(validatorPubkey.String() + " must be specified when exiting single validator.")
}

if config.All && valPubkPresent {
//nolint:revive // we use our own version of the errors package.
return errors.New(fmt.Sprintf("%s should not be specified when %s is, as it is obsolete and misleading.", validatorPubkey.String(), all.String()))
return errors.New(validatorPubkey.String() + " should not be specified when " + all.String() + " is, as it is obsolete and misleading.")
}

return nil
Expand Down
Loading