Skip to content
Open
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
19 changes: 19 additions & 0 deletions go/core/pkg/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"net/http"
"net/http/pprof"
"net/url"
"os"
"path/filepath"
"slices"
Expand Down Expand Up @@ -131,6 +132,24 @@ type Config struct {
}
}

// redactedConfig is a type alias for Config without MarshalLog to avoid recursion.
type redactedConfig Config

// MarshalLog implements logr.Marshaler to redact sensitive fields when logging.
func (c Config) MarshalLog() interface{} {
rc := redactedConfig(c)
rc.Database.Url = redactURL(rc.Database.Url)
return rc
}

func redactURL(rawURL string) string {
u, err := url.Parse(rawURL)
if err != nil {
return "***"
}
return u.Redacted()
}

func (cfg *Config) SetFlags(commandLine *flag.FlagSet) {
commandLine.StringVar(&cfg.Metrics.Addr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
Expand Down
58 changes: 58 additions & 0 deletions go/core/pkg/app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,64 @@ func TestMapValueWithLoadFromEnvEqualsInValue(t *testing.T) {
assert.Equal(t, map[string]string{"token": "abc=def", "team": "platform"}, target)
}

func TestRedactURL(t *testing.T) {
tests := []struct {
name string
url string
want string
}{
{
name: "postgres URL with credentials",
url: "postgres://postgres:kagent@kagent-postgresql.kagent.svc.cluster.local:5432/postgres",
want: "postgres://postgres:xxxxx@kagent-postgresql.kagent.svc.cluster.local:5432/postgres",
},
{
name: "URL without credentials",
url: "postgres://kagent-postgresql.kagent.svc.cluster.local:5432/postgres",
want: "postgres://kagent-postgresql.kagent.svc.cluster.local:5432/postgres",
},
{
name: "URL with username only",
url: "postgres://postgres@localhost:5432/db",
want: "postgres://postgres@localhost:5432/db",
},
{
name: "empty string",
url: "",
want: "",
},
{
name: "invalid URL",
url: "://invalid",
want: "***",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := redactURL(tt.url)
assert.Equal(t, tt.want, got)
})
}
}

func TestConfigMarshalLog(t *testing.T) {
cfg := Config{}
cfg.Database.Url = "postgres://postgres:supersecret@localhost:5432/mydb"
cfg.Database.VectorEnabled = true
cfg.HttpServerAddr = ":8083"

result := cfg.MarshalLog()
rc, ok := result.(redactedConfig)
assert.True(t, ok, "MarshalLog should return redactedConfig")
assert.Equal(t, "postgres://postgres:xxxxx@localhost:5432/mydb", rc.Database.Url)
assert.Equal(t, true, rc.Database.VectorEnabled)
assert.Equal(t, ":8083", rc.HttpServerAddr)

// Original config should not be modified
assert.Equal(t, "postgres://postgres:supersecret@localhost:5432/mydb", cfg.Database.Url)
}

func TestLoadFromEnvIntegration(t *testing.T) {
envVars := map[string]string{
"METRICS_BIND_ADDRESS": ":9090",
Expand Down