#!/usr/bin/env node /** * secret-scan (Машина 5 Пакет 7, Блок 4) — общий скан секрет-паттернов в тексте. * * Один источник секрет-паттернов на ДВА канала (анти-дрейф, как classify-destructive для * разрушительности): read-path-deny (7.1, скан выдачи Read) + mcp-classification (7.3, скан * исходящего egress). Секрет-ПОДМНОЖЕСТВО (не PII телефон/email — то в observer-pii-filter): * приватные ключи PEM, известные токены провайдеров, строки подключения со встроенными кредами. * * Чистая функция; паттерны без флага /g (для безопасного .test без lastIndex-состояния). * Токен-regex согласованы с observer-pii-filter (тот редактирует, этот — детектит/блокирует). */ const SECRET_PATTERNS = [ ['pem-private-key', /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----/], ['jwt', /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/], ['aws-key', /\bAKIA[A-Z0-9]{16}\b/], ['yc-static', /\bAQVN[A-Za-z0-9_-]{15,}\b/], ['yc-session', /\bt1\.[A-Za-z0-9_-]{40,}\b/], ['yc-oauth', /\by0_[A-Za-z0-9_-]{40,}\b/], ['sentry-token', /sntrys?_[A-Za-z0-9]{12,}/], ['openai-token', /\bsk-[A-Za-z0-9]{20,}/], ['github-token', /\bgh[pousr]_[A-Za-z0-9]{36,}\b/], ['slack-token', /\bxox[baprs]-[A-Za-z0-9-]{10,}/], ['bearer', /Bearer\s+[A-Za-z0-9._-]{20,}/], // Строка подключения с КРЕДАМИ: scheme://user:pass@host. Без user:pass@ (только host:port) — // не секрет (см. тест). Покрывает postgres/mysql/mongodb/redis/amqp. ['conn-string-creds', /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|rediss?|amqp):\/\/[^\s:@/]+:[^\s:@/]+@/i], ]; /** Скан текста на секрет-паттерны. @returns {{found:boolean, hits:string[]}} (пустой/невалидный → not found). */ export function scanSecrets(text) { const s = String(text == null ? '' : text); const hits = SECRET_PATTERNS.filter(([, re]) => re.test(s)).map(([name]) => name); return { found: hits.length > 0, hits }; } export const _internals = { SECRET_PATTERNS };