diff --git a/sim/app/stores/console/store.ts b/sim/app/stores/console/store.ts index d165a181b..b07d7a911 100644 --- a/sim/app/stores/console/store.ts +++ b/sim/app/stores/console/store.ts @@ -5,6 +5,36 @@ import { ConsoleEntry, ConsoleStore } from './types' // MAX across all workflows const MAX_ENTRIES = 50 +/** + * Recursively redacts API keys in an object + * @param obj The object to redact API keys from + * @returns A new object with API keys redacted + */ +const redactApiKeys = (obj: any): any => { + if (!obj || typeof obj !== 'object') { + return obj + } + + if (Array.isArray(obj)) { + return obj.map(redactApiKeys) + } + + const result: Record = {} + + for (const [key, value] of Object.entries(obj)) { + // Check if the key is 'apiKey' (case insensitive) + if (key.toLowerCase() === 'apikey' || key.toLowerCase() === 'api_key' || key.toLowerCase() === 'access_token') { + result[key] = '***REDACTED***' + } else if (typeof value === 'object' && value !== null) { + result[key] = redactApiKeys(value) + } else { + result[key] = value + } + } + + return result +} + export const useConsoleStore = create()( devtools( persist( @@ -14,8 +44,16 @@ export const useConsoleStore = create()( addConsole: (entry) => { set((state) => { + // Create a new entry with redacted API keys + const redactedEntry = { ...entry } + + // If the entry has output and it's an object, redact API keys + if (redactedEntry.output && typeof redactedEntry.output === 'object') { + redactedEntry.output = redactApiKeys(redactedEntry.output) + } + const newEntry: ConsoleEntry = { - ...entry, + ...redactedEntry, id: crypto.randomUUID(), timestamp: new Date().toISOString(), }