package configkit import ( "bytes" "errors" "fmt" "io" "strings" "sync/atomic" "testing" ) const ( taggedCanary = "TAGGED_CANARY_7c65" dynamicCanary = "DYNAMIC_CANARY_6a12" historicalCanary = "HISTORICAL_CANARY_91ef" derivedACanary = "DERIVED_A_CANARY_4c20" derivedBCanary = "DERIVED_B_CANARY_831d" ) var renderTextMarshalCalls atomic.Int64 var renderYAMLMarshalCalls atomic.Int64 type renderText string func (value renderText) MarshalText() ([]byte, error) { renderTextMarshalCalls.Add(1) return []byte(value), nil } func (value *renderText) UnmarshalText(text []byte) error { *value = renderText(text) return nil } type renderCredentials struct { Token string `yaml:"token"` Nested []string `yaml:"nested"` } type renderConfig struct { Credentials renderCredentials `yaml:"credentials" configkit:"secret"` Custom renderText `yaml:"custom"` DerivedA string `yaml:"derived_a"` DerivedB string `yaml:"derived_b"` Dynamic any `yaml:"dynamic"` EmptyMap map[string]string `yaml:"empty_map"` EmptySequence []string `yaml:"empty_sequence"` Labels map[string]string `yaml:"labels"` NilMap map[string]string `yaml:"nil_map"` NilSequence []string `yaml:"nil_sequence"` Sequence []string `yaml:"sequence"` } func (renderConfig) MarshalYAML() (any, error) { renderYAMLMarshalCalls.Add(1) return map[string]string{"forbidden": "application YAML hook ran"}, nil } func TestWriteEffectiveRedactsTagsDynamicHistoryAndDependencyCycles(t *testing.T) { renderTextMarshalCalls.Store(0) renderYAMLMarshalCalls.Store(0) directory := t.TempDir() mainPath := writeImportFile(t, directory, "main.yml", `credentials: token: TAGGED_CANARY_7c65 nested: [nested-secret] custom: custom value dynamic: {retired: HISTORICAL_CANARY_91ef} empty_map: {} empty_sequence: [] labels: {hidden: DYNAMIC_CANARY_6a12, public: visible} sequence: [second, first] `) writeImportFile(t, directory, "profiles/testing.yml", "dynamic: selected\n") definition := Definition[renderConfig]{ Secret: func(path Path) bool { return path.String() == "/labels/hidden" || path.String() == "/dynamic/retired" }, Resolve: func(configuration *renderConfig, resolution *Resolution) error { Normalize(resolution, Keys("derived_a"), &configuration.DerivedA, derivedACanary, "derived through cycle", Keys("derived_b")) Normalize(resolution, Keys("derived_b"), &configuration.DerivedB, derivedBCanary, "derived from retired secret", Keys("derived_a"), Keys("dynamic")) resolution.Warning(Keys("derived_a"), "derived output is configured") return nil }, } result, err := Load[renderConfig](File(mainPath), Options[renderConfig]{Definition: definition, Profile: "testing"}) if err != nil { t.Fatal(err) } if result.Config.Credentials.Token != taggedCanary || result.Config.Labels["hidden"] != dynamicCanary || result.Config.DerivedA != derivedACanary || result.Config.DerivedB != derivedBCanary { t.Fatal("typed configuration did not retain trusted values") } if !result.secrets["/dynamic/retired"] || !result.secrets["/derived_a"] || !result.secrets["/derived_b"] { t.Fatalf("secret closure = %#v", result.secrets) } if renderYAMLMarshalCalls.Load() != 0 { t.Fatal("loading called an application YAML marshal hook") } textCalls := renderTextMarshalCalls.Load() var output bytes.Buffer if err := result.WriteEffective(&output); err != nil { t.Fatal(err) } want := "credentials: '[REDACTED]'\ncustom: custom value\nderived_a: '[REDACTED]'\nderived_b: '[REDACTED]'\ndynamic: selected\nempty_map: {}\nempty_sequence: []\nlabels:\n hidden: '[REDACTED]'\n public: visible\nnil_map: null\nnil_sequence: null\nsequence:\n - second\n - first\n" if output.String() != want { t.Fatalf("effective output:\n%s\nwant:\n%s", output.String(), want) } if renderTextMarshalCalls.Load() != textCalls || renderYAMLMarshalCalls.Load() != 0 { t.Fatal("rendering called an application marshal hook") } for _, canary := range []string{taggedCanary, dynamicCanary, historicalCanary, derivedACanary, derivedBCanary, "nested-secret"} { if strings.Contains(output.String(), canary) { t.Fatalf("effective output contains %q", canary) } formatted := fmt.Sprintf("%v %#v %v %#v", result.Metadata(), result.Metadata(), result.Diagnostics(), result.Diagnostics()) if strings.Contains(formatted, canary) { t.Fatalf("metadata formatting contains %q", canary) } } beforeMutation := output.String() result.Config.Credentials.Token = "MUTATED_SECRET" result.Config.Labels["hidden"] = "MUTATED_DYNAMIC_SECRET" result.Config.Sequence[0] = "mutated" output.Reset() if err := result.WriteEffective(&output); err != nil || output.String() != beforeMutation { t.Fatalf("frozen output after caller mutation = %q, %v", output.String(), err) } wantWriteError := errors.New("write failed") if err := result.WriteEffective(errorWriter{err: wantWriteError}); !errors.Is(err, wantWriteError) { t.Fatalf("writer error = %v", err) } if err := result.WriteEffective(shortWriter{}); !errors.Is(err, io.ErrShortWrite) { t.Fatalf("short writer error = %v", err) } var nilResult *Result[renderConfig] if err := nilResult.WriteEffective(io.Discard); !errors.Is(err, errEffectiveUnavailable) { t.Fatalf("nil result error = %v", err) } } func TestSecretValuesStayOutOfLoadFailuresAndWarnings(t *testing.T) { tests := []struct { name string input string definition Definition[renderConfig] }{ {name: "parse", input: "credentials: [" + taggedCanary + "\n"}, {name: "decode", input: "credentials: " + taggedCanary + "\n"}, {name: "returned hook error", input: "credentials: {token: " + taggedCanary + "}\n", definition: Definition[renderConfig]{ Resolve: func(*renderConfig, *Resolution) error { return errors.New(taggedCanary) }, }}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { test.definition.Secret = func(path Path) bool { return path.String() == "/credentials" } result, err := Load[renderConfig](Bytes("secret-failure.yml", []byte(test.input)), Options[renderConfig]{Definition: test.definition}) if result != nil || err == nil { t.Fatalf("result, error = %#v, %v", result, err) } var loadError *LoadError if !errors.As(err, &loadError) { t.Fatalf("error type = %T", err) } formatted := fmt.Sprintf("%v %#v %v %#v %v %#v", err, err, loadError.Diagnostics(), loadError.Diagnostics(), loadError.Sources(), loadError.Sources()) if strings.Contains(formatted, taggedCanary) { t.Fatalf("failure formatting disclosed a secret: %s", formatted) } }) } } func TestDynamicConcreteTagsRemainSecretThroughHistory(t *testing.T) { type sensitive struct { Token string `yaml:"token" configkit:"secret"` } type cfg struct { Payload any `yaml:"payload"` Derived string `yaml:"derived"` } for _, change := range []string{"retain", "replace", "delete", "introduce"} { t.Run(change, func(t *testing.T) { const canary = "DYNAMIC_TAG_CANARY" definition := Definition[cfg]{Defaults: func() cfg { return cfg{Payload: map[string]any{"nested": []any{sensitive{Token: canary}}}} }} path := Keys("payload", "nested").Index(0).Key("token") if change == "introduce" { definition.Defaults = nil } definition.Resolve = func(c *cfg, r *Resolution) error { if change == "introduce" { Normalize(r, Keys("payload"), &c.Payload, any(map[string]any{"nested": []any{sensitive{Token: canary}}}), "create") } if change == "replace" { Normalize(r, Keys("payload"), &c.Payload, any("public"), "replace") } if change == "delete" { Normalize(r, Keys("payload"), &c.Payload, any(nil), "remove") } Normalize(r, Keys("derived"), &c.Derived, canary, "derive", path) return nil } result, err := Load(NoSource(), Options[cfg]{Definition: definition}) if err != nil { t.Fatal(err) } var output bytes.Buffer if err := result.WriteEffective(&output); err != nil { t.Fatal(err) } for _, query := range []Path{Keys(), path, Keys("derived")} { explanation, _ := result.Explain(query) output.WriteString(fmt.Sprintf("%#v", explanation)) } if strings.Contains(output.String(), canary) { t.Fatal("dynamic secret escaped inspection") } if !result.secrets[path.String()] || !result.secrets["/derived"] { t.Fatal("dynamic tag or dependency classification missing") } }) } }