Skip to content

Commit de9a76e

Browse files
authored
fix(kas): Ensure root key is not logged. (#2918)
### Proposed Changes 1.) Modify the `KasConfig` object to redact the `root_key` 2.) Modify the `ServiceConfig` object to check for the existence of `root_key`, if present redact it. Logs redacted: 1.) At startup: <img width="2437" height="82" alt="Screenshot 2025-11-19 at 8 28 18 AM" src="https://github.com/user-attachments/assets/abe29f91-a84c-43ca-86a1-1832175fa0e2" /> 2.) Update hook <img width="2447" height="104" alt="Screenshot 2025-11-19 at 8 26 13 AM" src="https://github.com/user-attachments/assets/7aff9a9e-38b5-48b6-a562-0ee3ca5c230e" /> 3.) Startup - Invalid Config <img width="2435" height="105" alt="Screenshot 2025-11-19 at 8 24 30 AM" src="https://github.com/user-attachments/assets/634c227c-3d01-4908-b3d3-05759a9cf756" /> ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions
1 parent 182b463 commit de9a76e

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

service/kas/access/provider.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package access
22

33
import (
44
"context"
5+
"fmt"
56
"log/slog"
67
"net/url"
78
"time"
@@ -135,6 +136,43 @@ func (kasCfg *KASConfig) UpgradeMapToKeyring(c *security.StandardCrypto) {
135136
}
136137
}
137138

139+
func (kasCfg KASConfig) String() string {
140+
rootKeySummary := ""
141+
if kasCfg.RootKey != "" {
142+
rootKeySummary = fmt.Sprintf("[REDACTED len=%d]", len(kasCfg.RootKey))
143+
}
144+
145+
return fmt.Sprintf(
146+
"KASConfig{Keyring:%v, ECCertID:%q, RSACertID:%q, RootKey:%s, KeyCacheExpiration:%s, ECTDFEnabled:%t, Preview:%+v, RegisteredKASURI:%q}",
147+
kasCfg.Keyring,
148+
kasCfg.ECCertID,
149+
kasCfg.RSACertID,
150+
rootKeySummary,
151+
kasCfg.KeyCacheExpiration,
152+
kasCfg.ECTDFEnabled,
153+
kasCfg.Preview,
154+
kasCfg.RegisteredKASURI,
155+
)
156+
}
157+
158+
func (kasCfg KASConfig) LogValue() slog.Value {
159+
rootKeyVal := ""
160+
if kasCfg.RootKey != "" {
161+
rootKeyVal = fmt.Sprintf("[REDACTED len=%d]", len(kasCfg.RootKey))
162+
}
163+
164+
return slog.GroupValue(
165+
slog.Any("keyring", kasCfg.Keyring),
166+
slog.String("eccertid", kasCfg.ECCertID),
167+
slog.String("rsacertid", kasCfg.RSACertID),
168+
slog.String("root_key", rootKeyVal),
169+
slog.Duration("key_cache_expiration", kasCfg.KeyCacheExpiration),
170+
slog.Bool("ec_tdf_enabled", kasCfg.ECTDFEnabled),
171+
slog.Any("preview", kasCfg.Preview),
172+
slog.String("registered_kas_uri", kasCfg.RegisteredKASURI),
173+
)
174+
}
175+
138176
// If there exists *any* legacy keys, returns empty list.
139177
// Otherwise, create a copy with legacy=true for all values
140178
func inferLegacyKeys(keys []CurrentKeyFor) []CurrentKeyFor {

service/pkg/config/config.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"github.com/spf13/viper"
1616
)
1717

18+
const rootKeyField = "root_key"
19+
1820
// ChangeHook is a function invoked when the configuration changes.
1921
type ChangeHook func(configServices ServicesMap) error
2022

@@ -24,6 +26,43 @@ type ServicesMap map[string]ServiceConfig
2426
// Config structure holding a single service.
2527
type ServiceConfig map[string]any
2628

29+
func (cfg ServiceConfig) String() string {
30+
// Create a shallow copy so we don't mutate the original map.
31+
redacted := make(map[string]any, len(cfg))
32+
33+
for k, v := range cfg {
34+
if k == rootKeyField {
35+
redacted[k] = redactRootKeyValue(v)
36+
continue
37+
}
38+
redacted[k] = v
39+
}
40+
41+
return fmt.Sprintf("%v", redacted)
42+
}
43+
44+
func (cfg ServiceConfig) LogValue() slog.Value {
45+
attrs := make([]slog.Attr, 0, len(cfg))
46+
47+
for k, v := range cfg {
48+
if k == rootKeyField {
49+
attrs = append(attrs, slog.String(k, redactRootKeyValue(v)))
50+
continue
51+
}
52+
53+
attrs = append(attrs, slog.Any(k, v))
54+
}
55+
56+
return slog.GroupValue(attrs...)
57+
}
58+
59+
func redactRootKeyValue(v any) string {
60+
if s, ok := v.(string); ok && s != "" {
61+
return fmt.Sprintf("REDACTED: len=%d", len(s))
62+
}
63+
return "REDACTED"
64+
}
65+
2766
// Config represents the configuration settings for the service.
2867
type Config struct {
2968
// DevMode specifies whether the service is running in development mode.

0 commit comments

Comments
 (0)