// Package output removes credentials from diagnostics before they reach an operator terminal. package output import ( "fmt" "os" "regexp" "sort" "strings" ) var credentialField = regexp.MustCompile(`(?im)(\b[\w.-]*(?:password|token|key)[\w.-]*\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;]+)`) // Sanitize redacts common credential fields and every supplied secret value. func Sanitize(text string, secretValues []string) string { text = credentialField.ReplaceAllString(text, "${1}[REDACTED]") values := append([]string(nil), secretValues...) sort.Slice(values, func(i, j int) bool { return len(values[i]) > len(values[j]) }) for _, value := range values { if value != "" { text = strings.ReplaceAll(text, value, "[REDACTED]") } } return text } // SecretValuesFromFiles reads non-empty secret-file contents without exposing them to callers. func SecretValuesFromFiles(paths []string) ([]string, error) { values := make([]string, 0, len(paths)) for _, path := range paths { contents, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("read secret file: %w", err) } if value := strings.TrimSpace(string(contents)); value != "" { values = append(values, value) } } return values, nil }