/** * Conservative log-line redaction for API/SSE responses. * * Preserves raw log files on disk; only use this when serializing lines to * HTTP/SSE clients. The regexes are intentionally anchored to known secret * markers so ordinary error messages, file paths, ports, and throughput metrics * are not eaten. */ const REDACTED = "[redacted]"; /** * Token-like value that stops at common separators/punctuation so surrounding * log context (semicolons, commas, quotes) is preserved. */ const TOKEN = String.raw`[^\s;,"']+`; /** * Redact common secret-bearing patterns from a single log line. * * Covered: * - Authorization: Bearer * - X-Api-Key: * - Env assignments: HF_TOKEN=..., OPENAI_API_KEY=..., *_API_KEY=..., *_TOKEN=... * - JSON-ish pairs: "api_key": "...", 'token': '...' * - CLI flags: --api-key , --hf-token , --token , etc. * - URL query params: ?api_key=...&token=... */ export function redactLogLine(line: string): string { let redacted = line; // Authorization / Bearer headers. redacted = redacted.replace( new RegExp(String.raw`(Authorization:\s*Bearer\s+)` + TOKEN, "gi"), `$1${REDACTED}`, ); // X-Api-Key style headers. redacted = redacted.replace( new RegExp(String.raw`((?:^|[\r\n])[Xx]-[Aa]pi-[Kk]ey:\s+)` + TOKEN, "g"), `$1${REDACTED}`, ); // Env-style assignments: KEY=VALUE or export KEY=VALUE. // Covers explicit keys plus generic *_API_KEY / *_TOKEN patterns. redacted = redacted.replace( new RegExp( String.raw`((?:^|[\s;{"'|&]|export\s+)(?:HF_TOKEN|HUGGING_FACE_HUB_TOKEN|OPENAI_API_KEY|ANTHROPIC_API_KEY|[A-Za-z_][A-Za-z0-9_]*_API_KEY|[A-Za-z_][A-Za-z0-9_]*_TOKEN)\s*=\s*)(?:"[^"]*"|'[^']*'|` + TOKEN + ")", "g", ), `$1${REDACTED}`, ); // JSON-ish key/value pairs: "api_key": "...", 'token': '...'. // Preserves the quote style of the value. redacted = redacted.replace( /(["']?(?:api_key|api-key|apikey|auth_token|access_token|token|secret|password|hf_token|openai_api_key|anthropic_api_key)["']?\s*:\s*)(["'])[^"']*\2/gi, `$1$2${REDACTED}$2`, ); // CLI long flags: --api-key , --hf-token , etc. redacted = redacted.replace( new RegExp( String.raw`(\s)(--(?:api-key|apikey|api_token|auth-token|access-token|hf-token|token|secret|password))\s+` + TOKEN, "gi", ), `$1$2 ${REDACTED}`, ); // URL query parameters: api_key=..., token=..., etc. redacted = redacted.replace( /([?&])(api_key|api-key|apikey|token|access_token|auth_token|key|secret|hf_token|openai_api_key|anthropic_api_key)=([^&\s]*)/gi, `$1$2=${REDACTED}`, ); return redacted; }