fix(config): redact resolved field in config snapshots

The newly added 'resolved' field contains secrets after ${ENV}
substitution. This commit ensures redactConfigSnapshot also redacts
the resolved field to prevent credential leaks in config.get responses.
This commit is contained in:
Marcus Castro
2026-02-08 13:03:54 -03:00
committed by Peter Steinberger
parent 3189e2f11b
commit 2a9745c9a1
2 changed files with 15 additions and 0 deletions

View File

@@ -12,6 +12,7 @@ function makeSnapshot(config: Record<string, unknown>, raw?: string): ConfigFile
exists: true,
raw: raw ?? JSON.stringify(config),
parsed: config,
resolved: config as ConfigFileSnapshot["resolved"],
valid: true,
config: config as ConfigFileSnapshot["config"],
hash: "abc123",
@@ -188,12 +189,23 @@ describe("redactConfigSnapshot", () => {
expect(parsed.channels.discord.token).toBe(REDACTED_SENTINEL);
});
it("redacts resolved object as well", () => {
const config = {
gateway: { auth: { token: "supersecrettoken123456" } },
};
const snapshot = makeSnapshot(config);
const result = redactConfigSnapshot(snapshot);
const resolved = result.resolved as Record<string, Record<string, Record<string, string>>>;
expect(resolved.gateway.auth.token).toBe(REDACTED_SENTINEL);
});
it("handles null raw gracefully", () => {
const snapshot: ConfigFileSnapshot = {
path: "/test",
exists: false,
raw: null,
parsed: null,
resolved: {} as ConfigFileSnapshot["resolved"],
valid: false,
config: {} as ConfigFileSnapshot["config"],
issues: [],

View File

@@ -137,12 +137,15 @@ export function redactConfigSnapshot(snapshot: ConfigFileSnapshot): ConfigFileSn
const redactedConfig = redactConfigObject(snapshot.config);
const redactedRaw = snapshot.raw ? redactRawText(snapshot.raw, snapshot.config) : null;
const redactedParsed = snapshot.parsed ? redactConfigObject(snapshot.parsed) : snapshot.parsed;
// Also redact the resolved config (contains values after ${ENV} substitution)
const redactedResolved = redactConfigObject(snapshot.resolved);
return {
...snapshot,
config: redactedConfig,
raw: redactedRaw,
parsed: redactedParsed,
resolved: redactedResolved,
};
}