import path from "node:path"; import { readTextFileIfSmall, relative, walkFiles, } from "./repository-files.mjs"; const patterns = [ ["private key block", /-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/u], ["GitHub token", /\bgh[pousr]_[A-Za-z0-9]{30,}\b/u], ["OpenAI-style key", /\bsk-[A-Za-z0-9_-]{20,}\b/u], ["Google API key", /\bAIza[0-9A-Za-z_-]{35}\b/u], ["AWS access key", /\bAKIA[0-9A-Z]{16}\b/u], ]; const excludedExtensions = new Set([ ".gif", ".ico", ".jpeg", ".jpg", ".pdf", ".png", ".webp", ".zip", ]); const findings = []; for (const file of await walkFiles()) { if (excludedExtensions.has(path.extname(file).toLowerCase())) continue; const content = await readTextFileIfSmall(file); if (content === null) continue; for (const [label, pattern] of patterns) { const match = pattern.exec(content); if (!match) continue; const line = content.slice(0, match.index).split(/\r?\n/u).length; findings.push(`${relative(file)}:${line} (${label})`); } } if (findings.length > 0) { console.error("Potential secrets found; values are intentionally redacted:"); for (const finding of findings) console.error(`- ${finding}`); process.exitCode = 1; } else { console.log("High-confidence secret scan passed."); }