@bytehide/secrets-scanner
Version:
AI-powered secrets scanner for JavaScript/TypeScript. Detects and protects API keys, tokens, and credentials in source code and build artifacts. Features automatic fixing, built-in secrets manager, and zero-knowledge privacy. Superior alternative to gitle
1,719 lines (1,637 loc) • 72.2 kB
JavaScript
// node_modules/tsup/assets/esm_shims.js
import { fileURLToPath } from "url";
import path from "path";
var getFilename = () => fileURLToPath(import.meta.url);
var getDirname = () => path.dirname(getFilename());
var __dirname = /* @__PURE__ */ getDirname();
// src/core/analysisBuilder.ts
import dayjs from "dayjs";
import path2 from "path";
import os from "os";
function createAnalysis(secrets, appName, engine, startTime, endTime, actions) {
const totalTime = (endTime - startTime) / 1e3;
const detections = secrets.map((s) => {
return {
id: s.key,
// o un ID que generes
name: s.name,
confidence: s.confidence,
location: s.filePath + ` on line ${s.line}`,
// un ejemplo
path: shortifyPath(s.filePath) + `:${s.line}`,
file: s.filePath,
discover: s.discoveredBy,
// "pattern", "plugins", etc.
code: s.snippet,
// si tienes snippet
highlight: s.snippetLineNumber
};
});
const now = dayjs().format();
return {
application: appName,
date: now,
// string ISO
time: totalTime,
engine,
detections,
actions: actions || {}
};
}
function shortifyPath(absolutePath, maxSegments = 4) {
const homeDir = os.homedir();
let shortPath = absolutePath;
const normalizedAbsolute = path2.normalize(absolutePath);
const normalizedHome = path2.normalize(homeDir);
if (normalizedAbsolute.startsWith(normalizedHome)) {
shortPath = normalizedAbsolute.slice(normalizedHome.length);
if (!shortPath.startsWith(path2.sep)) {
shortPath = path2.sep + shortPath;
}
}
const parts = shortPath.split(path2.sep).filter(Boolean);
if (parts.length > maxSegments) {
const lastSegments = parts.slice(parts.length - maxSegments);
return ".../" + lastSegments.join(path2.sep);
} else {
return shortPath;
}
}
// src/core/mainScanner.ts
import path5 from "path";
// src/core/extractors/stringExtractorUniversal.ts
import fs2 from "fs";
import path3 from "path";
import Parser from "tree-sitter";
import JavaScript from "tree-sitter-javascript";
import TSParser from "tree-sitter-typescript";
import Python from "tree-sitter-python";
import Java from "tree-sitter-java";
import CSharp from "tree-sitter-c-sharp";
import CPP from "tree-sitter-cpp";
import TSParser2 from "tree-sitter-php";
import Swift from "tree-sitter-swift";
import Kotlin from "tree-sitter-kotlin";
import Go from "tree-sitter-go";
import Rust from "tree-sitter-rust";
import Ruby from "tree-sitter-ruby";
import Scala from "tree-sitter-scala";
// src/core/extractors/stringExtractor.ts
import fs from "fs";
import { parse } from "@babel/parser";
import traverse from "@babel/traverse";
import * as t from "@babel/types";
function getSnippet(content, line, column, options = { linesBefore: 3, linesAfter: 3 }) {
const lines = content.split("\n");
const startLine = Math.max(line - (options.linesBefore ?? 3), 1);
const endLine = Math.min(line + (options.linesAfter ?? 3), lines.length);
const snippetLines = lines.slice(startLine - 1, endLine);
const snippet = snippetLines.join("\n");
let highlight = 0;
let snippetLineNumber = line - startLine + 1;
if (line >= startLine && line <= endLine) {
const currentLineIndex = snippetLineNumber - 1;
highlight = snippetLines.slice(0, currentLineIndex).reduce((acc, ln) => acc + ln.length + 1, 0);
highlight += column;
}
return { snippet, highlight, snippetLineNumber };
}
// src/core/extractors/stringExtractorUniversal.ts
var { typescript: TypeScript, tsx: TSX } = TSParser;
var { php: PHP } = TSParser2;
var LANG_MAP = {
// JavaScript / Node
".js": JavaScript,
".jsx": JavaScript,
".mjs": JavaScript,
".cjs": JavaScript,
// TypeScript
".ts": TypeScript,
".tsx": TSX,
".cts": TypeScript,
".mts": TypeScript,
// Python
".py": Python,
".pyw": Python,
// Java
".java": Java,
// C#
".cs": CSharp,
".csx": CSharp,
".razor": CSharp,
".cshtml": CSharp,
// C++
".cpp": CPP,
".cxx": CPP,
".cc": CPP,
".hpp": CPP,
".hh": CPP,
".hxx": CPP,
".h": CPP,
// PHP / Laravel Blade
".php": PHP,
".phtml": PHP,
".php3": PHP,
".php4": PHP,
".php5": PHP,
".phar": PHP,
".inc": PHP,
".blade.php": void 0,
// Swift
".swift": Swift,
// Kotlin
".kt": Kotlin,
".kts": Kotlin,
// Go
".go": Go,
// Rust
".rs": Rust,
// Ruby
".rb": Ruby,
// Scala
".scala": Scala,
".sc": Scala
// Dart
//'.dart': Dart,
// Shell scripts
//'.sh': Shell,
//'.bash': Shell,
//'.zsh': Shell,
// Perl
//'.pl': Perl,
//'.pm': Perl,
//'.t': Perl,
// Lua
//'.lua': Lua,
// MATLAB
//'.m': Matlab,
// Fortran
//'.f': Fortran,
//'.for': Fortran,
//'.f90': Fortran,
};
var STRING_NODE_TYPES = /* @__PURE__ */ new Set([
// Generic string literals
"string_literal",
"string",
"template_string",
// Go
"interpreted_string_literal",
"raw_string_literal",
// PHP
"encapsed_string",
"string_content",
// JSX
"jsx_text",
// C#
"interpolated_string_expression",
"interpolated_regular_string_literal",
"interpolated_verbatim_string_literal",
// Swift
"string_literal",
// Swift grammar uses same node type
// Perl
"string",
// Perl grammar calls them “string”
//Swift
"line_string_literal",
"line_str_text",
// Others (Rust, Kotlin, Java, etc.)
"string_literal"
]);
function extractStringsFromFile(filePath, includeSnippet = false) {
const ext = path3.extname(filePath).toLowerCase();
let Grammar = LANG_MAP[ext];
if (filePath.endsWith(".blade.php"))
Grammar = void 0;
const content = fs2.readFileSync(filePath, "utf-8");
const results = [];
if (Grammar) {
let walk2 = function(node) {
if (STRING_NODE_TYPES.has(node.type) && !(node.parent && STRING_NODE_TYPES.has(node.parent.type))) {
const start = node.startPosition;
const raw = content.slice(node.startIndex, node.endIndex);
const value = raw.replace(/^(['"`])|(\1)$/g, "");
const metadata = {
value,
filePath,
line: start.row + 1,
column: start.column
};
const varName = getVariableName(node);
if (varName)
metadata.variableName = varName;
if (includeSnippet) {
const snippetData = getSnippet(content, metadata.line, metadata.column);
Object.assign(metadata, snippetData);
}
results.push(metadata);
}
node.children.forEach(walk2);
};
var walk = walk2;
const parser = new Parser();
parser.setLanguage(Grammar);
const tree = parser.parse(content);
walk2(tree.rootNode);
} else {
const regex = /(['"`])((?:\\.|(?!\1).)*?)\1/g;
for (const [idx, line] of content.split("\n").entries()) {
let match;
while (match = regex.exec(line)) {
const [, , val] = match;
const metadata = {
value: val,
filePath,
line: idx + 1,
column: match.index
};
if (includeSnippet) {
const snippetData = getSnippet(content, metadata.line, metadata.column);
Object.assign(metadata, snippetData);
}
results.push(metadata);
}
}
}
return results;
}
function getVariableName(node) {
let curr = node;
while (curr) {
const parent = curr.parent;
if (!parent) break;
if (parent.type === "variable_declarator" || parent.type === "assignment_expression" || parent.type === "assignment") {
const id = parent.child(0);
if (id?.type === "identifier") return id.text;
}
if (parent.type === "assignment") {
const id = parent.child(0);
if (id?.type === "identifier") return id.text;
}
if (parent.type === "pair") {
const key = parent.child(0);
if (key?.type === "identifier") return key.text;
if (key?.type === "string") return key.text.replace(/^['"`]|['"`]$/g, "");
}
if (parent.type === "parameter" || parent.type === "parameter_definition") {
const id = parent.child(0);
if (id?.type === "identifier") return id.text;
}
curr = parent;
}
return void 0;
}
function extractStringsFromFiles(files, includeSnippet = false) {
return files.flatMap((fp) => extractStringsFromFile(path3.resolve(fp), includeSnippet));
}
// src/core/patternLoader.ts
import fs3 from "fs";
import yaml from "js-yaml";
function loadPatterns(filePath) {
if (!fs3.existsSync(filePath)) {
throw new Error(`Can't read patterns data. File not found: ${filePath}`);
}
const content = fs3.readFileSync(filePath, "utf-8");
const data = yaml.load(content);
if (!data || !data.patterns) {
throw new Error(`Invalid YAML structure. Missing 'patterns' key in ${filePath}`);
}
const patterns = [];
for (const item of data.patterns) {
if (!item.pattern) continue;
patterns.push({
name: item.pattern.name,
regex: item.pattern.regex,
confidence: item.pattern.confidence
});
}
return patterns;
}
// src/core/helpers/secretKeyGenerator.ts
import crypto from "crypto";
import path4 from "path";
var patternToDescription = {
"api_?key": "api_key",
"auth_?key": "auth_key",
"service_?key": "service_key",
"account_?key": "account_key",
"db_?key": "database_key",
"database_?key": "database_key",
"priv_?key": "private_key",
"private_?key": "private_key",
"client_?key": "client_key",
"db_?pass": "database_password",
"database_?pass": "database_password",
"key_?pass": "key_password",
"password": "password",
"passwd": "password",
"pwd": "password",
"secret": "secret",
"contrase\xF1a": "password_spanish",
"contrasena": "password_spanish",
".*api[-_]?key.*": "api_key",
".*auth[-_]?key.*": "auth_key",
".*service[-_]?key.*": "service_key",
".*account[-_]?key.*": "account_key",
".*db[-_]?key.*": "database_key",
".*database[-_]?key.*": "database_key",
".*priv[-_]?key.*": "private_key",
".*private[-_]?key.*": "private_key",
".*client[-_]?key.*": "client_key",
".*db[-_]?pass.*": "database_password",
".*database[-_]?pass.*": "database_password",
".*key[-_]?pass.*": "key_password",
".*password.*": "password",
".*passwd.*": "password",
".*pwd.*": "password",
".*secret.*": "secret",
".*contrase\xF1a.*": "password",
".*contrasena.*": "password",
".*token.*": "token",
".*session[-_]?id.*": "session_id",
".*access[-_]?token.*": "access_token",
".*refresh[-_]?token.*": "refresh_token",
".*credential.*": "credential",
".*signature.*": "signature",
".*encrypt.*": "encryption_key",
".*decrypt.*": "decryption_key",
".*certificate.*": "certificate",
".*login.*": "login",
".*user[-_]?name.*": "username",
".*username.*": "username",
".*user[-_]?id.*": "user_id",
".*userid.*": "userid"
};
var SecretKeyGenerator = class {
static {
// Propiedades equivalentes a _prefix, _appName, _appVersion
this.prefix = "auto_";
}
static {
this.appName = "";
}
static {
this.appVersion = "";
}
/**
* Genera un "key name" descriptivo basándose en variableName,
* usando patternToDescription para encontrar un tipo.
*/
static generateKeyName(variableName) {
const descriptivePart2 = this.extractDescriptivePart(variableName);
for (const [regexStr, desc] of Object.entries(patternToDescription)) {
const regex = new RegExp(regexStr, "i");
if (regex.test(variableName)) {
const descriptivePart = this.extractDescriptivePartWithPattern(variableName, regexStr);
const finalDescPart = descriptivePart.length > 0 ? descriptivePart : descriptivePart2;
return finalDescPart.length > 0 ? `${finalDescPart}-${desc}` : desc;
}
}
return descriptivePart2.length > 0 ? descriptivePart2 : "sensitive-data";
}
/**
* Extrae la parte descriptiva anterior al patrón detectado.
*/
static extractDescriptivePartWithPattern(variableName, pattern) {
const regex = new RegExp(pattern, "i");
const parts = variableName.split(regex);
if (parts.length > 1) {
return parts[0].replace(/_/g, "");
}
return "";
}
/**
* Extrae la parte descriptiva de variableName separando por _ o espacios,
* omitiendo la primera parte que suele ser la keyword (ej: "db_pass" -> "pass").
*/
static extractDescriptivePart(variableName) {
const parts = variableName.split(/[_\s]/);
if (parts.length > 1) {
return parts.slice(1).join("_");
}
return "";
}
/**
* Extrae la "pista de localización" a partir del nombre de archivo
* sin extensión (equivalente a Path.GetFileNameWithoutExtension).
*/
static extractLocationHint(filePathStr) {
if (!filePathStr) return "";
const base = path4.basename(filePathStr, path4.extname(filePathStr));
return base.toLowerCase();
}
/**
* Genera un ID único usando SHA256 sobre hash, fullMethod, _appName, _appVersion.
*/
static generateID(hash, fullMethod) {
const inputData = `${hash}_${fullMethod}_${this.appName}_${this.appVersion}`;
const sha256Hash = crypto.createHash("sha256").update(inputData, "utf8").digest("hex");
return sha256Hash;
}
/**
* Genera la key final combinando:
* - prefix
* - detectionMethod (keyword/entropy/..)
* - detectionName
* - variableName => se usa generateKeyName
* - locationHint
* - un hash corto de secretValue
*/
static generateKey(detectionMethod, detectionName, filePath, variableName, secretValue) {
let keyBuilder = this.sanitizeKeyPart(this.prefix);
switch (detectionMethod.toLowerCase()) {
case "keyword":
if (variableName) {
keyBuilder += this.sanitizeKeyPart(this.generateKeyName(variableName));
} else if (detectionName) {
keyBuilder += this.sanitizeKeyPart(detectionName);
}
break;
case "entropy":
keyBuilder += "sensitive-data";
break;
default:
keyBuilder += this.sanitizeKeyPart(detectionName);
break;
}
const locationHint = this.sanitizeKeyPart(this.extractLocationHint(filePath));
if (locationHint) {
keyBuilder += `-${locationHint}`;
}
keyBuilder += `-${this.sanitizeKeyPart(this.generateHash(secretValue))}`;
let result = keyBuilder.replace(/-+/g, "-").replace(/^-|-$/g, "");
if (result.length > 200) {
result = result.substring(0, 200);
}
return result;
}
/**
* Limpia la cadena de caracteres no alfanuméricos,
* reemplazándolos por guiones y pasando a minúsculas.
*/
static sanitizeKeyPart(input) {
if (!input) return input;
let sanitized = input.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
sanitized = sanitized.replace(/-+/g, "-");
return sanitized;
}
/**
* Genera un hash SHA256 del input y se queda con los primeros 6 caracteres,
* similar al GenerateHash() en .NET
*/
static generateHash(input) {
const hash = crypto.createHash("sha256").update(input, "utf8").digest("hex");
return hash.substring(0, 6);
}
};
// src/core/detectors/patternScanner.ts
function scanWithPatterns(strings, patterns) {
const results = [];
const highConfidence = patterns.filter((p) => p.confidence === "high");
for (const pat of highConfidence) {
const regex = new RegExp(pat.regex, "i");
for (const str of strings) {
if (regex.test(str.value)) {
const key = SecretKeyGenerator.generateKey(
"pattern",
// detectionMethod
pat.name,
// detectionName
str.filePath,
// filePath
str.variableName ?? "",
// variableName (si existe)
str.value
// secretValue
);
if (!results.some((r) => r.value === str.value && r.filePath === str.filePath && r.line === str.line)) {
results.push({
value: str.value,
key,
name: pat.name,
confidence: pat.confidence,
discoveredBy: "pattern",
filePath: str.filePath,
line: str.line,
snippet: str.snippet,
highlight: str.highlight,
snippetLineNumber: str.snippetLineNumber,
variableName: str.variableName
});
}
}
}
}
return results;
}
// src/core/detectors/plugins/RegexBaseDetector.ts
var RegexBasedDetector = class {
/**
* Implementa la lógica de containsSecret usando la tokenRegex.
*/
containsSecret(input) {
return this.tokenRegex.test(input);
}
};
// src/core/detectors/plugins/database/MongoDbDetector.ts
var MongoDbDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "MongoDB Connection String";
this.tokenRegex = new RegExp(
[
// MongoDB SRV URI (Atlas/cloud)
"mongodb\\+srv:\\/\\/[a-zA-Z0-9._%+-]+:[^@\\s]+@[^\\/\\s]+\\.[^\\/\\s]+\\/[a-zA-Z0-9_-]+",
// MongoDB URI (self-hosted or local)
"mongodb:\\/\\/[a-zA-Z0-9._%+-]+:[^@\\s]+@[^\\/\\s]+(:\\d+)?\\/[a-zA-Z0-9_-]+",
// In env or config
`MONGODB_URI\\s*[:=]\\s*['"]?mongodb[^'"\\s]+['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/PostgreSQLDetector.ts
var PostgreSQLDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "PostgreSQL Connection String";
this.tokenRegex = new RegExp(
[
// PostgreSQL URI
"postgres:\\/\\/[a-zA-Z0-9._%+-]+:[^@\\s]+@[^\\/\\s]+(:\\d+)?\\/[a-zA-Z0-9_-]+",
// Environment variable style
`POSTGRES_(URL|URI|PASSWORD)\\s*[:=]\\s*['"]?.+['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/MySQLDetector.ts
var MySQLDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "MySQL Connection String";
this.tokenRegex = new RegExp(
[
// MySQL URI
"mysql:\\/\\/[a-zA-Z0-9._%+-]+:[^@\\s]+@[^\\/\\s]+(:\\d+)?\\/[a-zA-Z0-9_-]+",
// Env variable style
`MYSQL_(URL|URI|PASSWORD)\\s*[:=]\\s*['"]?.+['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/RedisDetector.ts
var RedisDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Redis Connection String";
this.tokenRegex = new RegExp(
[
// Redis URI with password
"redis:\\/\\:[^@\\s]+@[^\\/\\s]+(:\\d+)?",
// Environment variable style
`REDIS_URL\\s*[:=]\\s*['"]?redis:\\/\\/[^'"\\s]+['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/ElasticsearchDetector.ts
var ElasticsearchDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Elasticsearch Credentials";
this.tokenRegex = new RegExp(
[
// Elasticsearch URL with basic auth
"https?:\\/\\/[a-zA-Z0-9._%+-]+:[^@\\s]+@[^\\/\\s]+(:\\d+)?\\/?",
// Environment variable style
`ELASTICSEARCH_(URL|PASSWORD)\\s*[:=]\\s*['"]?.+['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/FirebaseDetector.ts
var FirebaseDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Firebase API Key";
this.tokenRegex = new RegExp(
[
// Firebase API Key (General format)
"AIza[0-9A-Za-z-_]{35}",
// Firebase Admin SDK Service Account
`FIREBASE_AUTH\\s*[:=]\\s*['"]?AIza[0-9A-Za-z-_]{35}['"]?`,
// Firebase Realtime Database URL (with API keys)
"[a-zA-Z0-9_-]+\\.firebaseio\\.com/.+/.+/.+/.+",
// Firebase credentials
`GOOGLE_APPLICATION_CREDENTIALS\\s*[:=]\\s*['"]?firebase-adminsdk-[a-z0-9]{16}\\@[a-z0-9]+\\.iam\\.gserviceaccount\\.com['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/SupabaseDetector.ts
var SupabaseDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Supabase Credentials";
this.tokenRegex = new RegExp(
[
// Supabase URL
`SUPABASE_URL\\s*[:=]\\s*['"]?https:\\/\\/[a-z0-9]{20,40}\\.supabase\\.co['"]?`,
// Supabase anon key
`SUPABASE_ANON_KEY\\s*[:=]\\s*['"]?[a-zA-Z0-9-_]{40,100}['"]?`,
// Supabase service role key
`SUPABASE_SERVICE_ROLE_KEY\\s*[:=]\\s*['"]?[a-zA-Z0-9-_]{40,100}['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/GoogleCloudStorageDetector.ts
var GoogleCloudStorageDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Google Cloud Storage Key";
this.tokenRegex = new RegExp(
[
// Service account JSON key fields
'"type"\\s*:\\s*"service_account"',
'"project_id"\\s*:\\s*"[a-z0-9-]+"',
'"private_key_id"\\s*:\\s*"[a-f0-9]+"',
'"private_key"\\s*:\\s*"-----BEGIN PRIVATE KEY-----[^"]+-----END PRIVATE KEY-----"',
// Environment variable style
`GOOGLE_APPLICATION_CREDENTIALS\\s*[:=]\\s*['"]?.+\\.json['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/database/CloudantDetector.ts
var CloudantDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Cloudant Credentials";
this.tokenRegex = new RegExp(
[
// Cloudant URL with API Key (basic format)
"https?:\\/\\/[a-zA-Z0-9]+:[a-zA-Z0-9_-]+@[^\\/]+\\.cloudant\\.com",
// Cloudant credentials with API Key (no base URL)
`cloudant\\.(key|password|token)\\s*[:=]\\s*['"]?[a-zA-Z0-9_-]{32}['"]?`,
// Cloudant credentials for service accounts
`CLOUDANT_API_KEY\\s*[:=]\\s*['"]?[a-zA-Z0-9_-]{32}['"]?`,
// Cloudant URL with basic auth and no user/password
"https?:\\/\\/[a-zA-Z0-9]+@[^\\/]+\\.cloudant\\.com"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/SendGridDetector.ts
var SendGridDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "SendGrid API Key";
this.tokenRegex = new RegExp(
[
"SG.[a-zA-Z0-9_-]{22}.[a-zA-Z0-9_-]{43}",
`SENDGRID_API_KEYs*[:=]s*["']?SG.[a-zA-Z0-9_-]{22}.[a-zA-Z0-9_-]{43}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/SlackDetector.ts
var SlackDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Slack Token or Webhook";
this.tokenRegex = new RegExp(
[
"xox(?:a|b|p|o|s|r)-(?:d+-)+[a-z0-9]+",
"https://hooks.slack.com/services/T[a-zA-Z0-9_]+/B[a-zA-Z0-9_]+/[a-zA-Z0-9_]+"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/WhatsAppCloudDetector.ts
var WhatsAppCloudDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "WhatsApp Cloud API Token";
this.tokenRegex = new RegExp(
[
"EAACEdEose0cBA[0-9A-Za-z]{32,}",
`WHATSAPP_TOKENs*[:=]s*["']?EAACEdEose0cBA[0-9A-Za-z]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/VonageDetector.ts
var VonageDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Vonage (Nexmo) API Credentials";
this.tokenRegex = new RegExp(
[
`VONAGE_API_KEYs*[:=]s*["']?[a-zA-Z0-9]{8}["']?`,
`VONAGE_API_SECRETs*[:=]s*["']?[a-zA-Z0-9]{16,}["']?`,
`NEXMO_(API_KEY|API_SECRET)s*[:=]s*["']?[a-zA-Z0-9]{8,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/PlivoDetector.ts
var PlivoDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Plivo API Credentials";
this.tokenRegex = new RegExp(
[
`PLIVO_AUTH_IDs*[:=]s*["']?[A-Z0-9]{20}["']?`,
`PLIVO_AUTH_TOKENs*[:=]s*["']?[A-Za-z0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/MailchimpDetector.ts
var MailchimpDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Mailchimp Access Key";
this.tokenRegex = new RegExp(
[
"[0-9a-z]{32}-us[0-9]{1,2}",
`MAILCHIMP_API_KEYs*[:=]s*["']?[0-9a-z]{32}-us[0-9]{1,2}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/PostmarkDetector.ts
var PostmarkDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Postmark Server Token";
this.tokenRegex = new RegExp(
[
`POSTMARK_API_TOKENs*[:=]s*["']?[a-zA-Z0-9]{36}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/ZoomApiDetector.ts
var ZoomApiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Zoom JWT or SDK Secret";
this.tokenRegex = new RegExp(
[
`zoom_jwt_tokens*[:=]s*["']?[a-zA-Z0-9_-]{20,}["']?`,
`ZOOM_(JWT|SDK)_SECRETs*[:=]s*["']?[a-zA-Z0-9_-]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/SmtpGenericDetector.ts
var SmtpGenericDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Generic SMTP Password";
this.tokenRegex = new RegExp(
[
`(SMTP|EMAIL|MAIL)(_|)?(PASS|PASSWORD|AUTH)s*[:=]s*["']?.{8,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/DiscordBotTokenDetector.ts
var DiscordBotTokenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Discord Bot Token";
this.tokenRegex = new RegExp(
[
"[MNOPQ][a-zA-Zd_-]{23,25}.[a-zA-Zd_-]{6}.[a-zA-Zd_-]{27}"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/messages/MailgunDetector.ts
var MailgunDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Mailgun API Key";
this.tokenRegex = new RegExp(
[
"key-[a-f0-9]{32}",
`MAILGUN_API_KEYs*[:=]s*["']?key-[a-f0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/identity/FirebaseAuthDetector.ts
var FirebaseAuthDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Firebase Auth Keys";
this.tokenRegex = new RegExp(
[
`FIREBASE_API_KEYs*[:=]s*["']?[A-Za-z0-9-_]{39,}["']?`,
`FIREBASE_AUTH_DOMAINs*[:=]s*["']?[a-z0-9-]+.firebaseapp.com["']?`,
`FIREBASE_PROJECT_IDs*[:=]s*["']?[a-z0-9-]{6,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/identity/OktaDetector.ts
var OktaDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Okta API Key";
this.tokenRegex = new RegExp(
[
`OKTA_CLIENT_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`,
`OKTA_API_KEYs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`,
"https://[a-zA-Z0-9_-]+.okta.com"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/identity/ClerkDetector.ts
var ClerkDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Clerk.dev API Keys";
this.tokenRegex = new RegExp(
[
`CLERK_API_KEYs*[:=]s*["']?[a-zA-Z0-9]{40,}["']?`,
`CLERK_SECRET_KEYs*[:=]s*["']?[a-zA-Z0-9]{40,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/identity/SuperTokensDetector.ts
var SuperTokensDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "SuperTokens API Key";
this.tokenRegex = new RegExp(
[
`SUPERTOKENS_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/identity/Auth0Detector.ts
var Auth0Detector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Auth0 Credentials";
this.tokenRegex = new RegExp(
[
`AUTH0_DOMAINs*[:=]s*["']?[a-zA-Z0-9_-]+.auth0.com["']?`,
`AUTH0_CLIENT_SECRETs*[:=]s*["']?[a-zA-Z0-9_-]{32,}["']?`,
`AUTH0_API_TOKENs*[:=]s*["']?[a-zA-Z0-9_-]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/NpmTokenDetector.ts
var NpmTokenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "NPM Token";
/**
* Detects NPM tokens in `.npmrc` or env-like strings.
* Example:
* //registry.npmjs.org/:_authToken=npm_abcd1234...
* //my-registry/:_authToken=31dd103e-017c-4f0a-bd9d-9fa970bd24a4
*/
this.tokenRegex = new RegExp(
String.raw`\/\/.+\/:_authToken=\s*((npm_[a-zA-Z0-9]+)|([A-Fa-f0-9-]{36}))`,
"gi"
);
}
// Opcional: podrías agregar isFormallyValid o verifySecret si decides extenderlo.
};
// src/core/detectors/plugins/security/JenkinsDetector.ts
var JenkinsDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Jenkins Credentials";
this.tokenRegex = new RegExp(
[
`JENKINS_(USER|API_TOKEN|AUTH)s*[:=]s*["']?[a-zA-Z0-9@:_-]{8,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/GitHubActionsDetector.ts
var GitHubActionsDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "GitHub Actions Secrets";
this.tokenRegex = new RegExp(
[
`GITHUB_TOKENs*[:=]s*["']?[a-zA-Z0-9_]{20,}["']?`,
`ACTIONS_RUNTIME_TOKENs*[:=]s*["']?[a-zA-Z0-9_-]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/TerraformCloudDetector.ts
var TerraformCloudDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Terraform Cloud Token";
this.tokenRegex = new RegExp(
[
"tfp_[a-zA-Z0-9]{30,}",
`TERRAFORM_TOKENs*[:=]s*["']?tfp_[a-zA-Z0-9]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/DroneCiDetector.ts
var DroneCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Drone CI Secrets";
this.tokenRegex = new RegExp(
[
`DRONE_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`,
`DRONE_SECRETs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/PulumiDetector.ts
var PulumiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Pulumi Access Token";
this.tokenRegex = new RegExp(
[
"pul-[a-f0-9]{32}",
`PULUMI_ACCESS_TOKENs*[:=]s*["']?pul-[a-f0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/BuddyCiDetector.ts
var BuddyCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Buddy API Token";
this.tokenRegex = new RegExp(
[
`BUDDY_API_TOKENs*[:=]s*["']?[a-zA-Z0-9-_]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/GitLabCiDetector.ts
var GitLabCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "GitLab CI/CD Tokens";
this.tokenRegex = new RegExp(
[
"glpat-[A-Za-z0-9_-]{20,50}",
`CI_JOB_TOKENs*[:=]s*["']?[a-zA-Z0-9_-]{20,}["']?`,
`GL_SECRETs*[:=]s*["']?.{16,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/CodefreshDetector.ts
var CodefreshDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Codefresh API Token";
this.tokenRegex = new RegExp(
[
`CODEFRESH_TOKENs*[:=]s*["']?[a-zA-Z0-9-_]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/TravisCiDetector.ts
var TravisCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Travis CI Token";
this.tokenRegex = new RegExp(
[
`TRAVIS_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/CircleCiDetector.ts
var CircleCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "CircleCI Tokens";
this.tokenRegex = new RegExp(
[
`CIRCLE_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`,
`CIRCLECI_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/security/BitbucketCiDetector.ts
var BitbucketCiDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Bitbucket Pipelines Tokens";
this.tokenRegex = new RegExp(
[
"bbp-[a-f0-9]{40,}",
`BITBUCKET_SECRETs*[:=]s*["']?[a-zA-Z0-9-]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/TwilioKeyDetector.ts
var TwilioKeyDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Twilio API Key";
/**
* Detects:
* - Account SID: ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* - Secret Key: SKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* - Optional: AK/RK keys used by SDKs
* - Contextual: TWILIO_AUTH_TOKEN=...
*/
this.tokenRegex = new RegExp(
[
// Account SID
"AC[a-z0-9]{32}",
// Secret Key
"SK[a-z0-9]{32}",
// Optional SDK keys
"AK[a-z0-9]{32}",
"RK[a-z0-9]{32}",
// In context (env var style)
`TWILIO_(AUTH|API)?_?TOKEN\\s*[:=]\\s*['"]?[a-z0-9]{32}['"]?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/JwtTokenDetector.ts
var JwtTokenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "JSON Web Token";
/**
* Regex para detectar tokens JWT (header.payload.signature), incluyendo firmados o incompletos.
*/
this.tokenRegex = new RegExp(
"eyJ[A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]+\\.?[A-Za-z0-9-_.+/=]*?",
"gi"
);
}
/**
* Verifica si el token tiene una estructura válida y decodificable (header y payload con JSON).
*/
async isFormallyValid(token) {
const parts = token.split(".");
if (parts.length < 2) return false;
for (let i = 0; i < 2; i++) {
const part = parts[i];
try {
const padded = this.addPadding(part);
const decoded = Buffer.from(padded, "base64").toString("utf-8");
JSON.parse(decoded);
} catch {
return false;
}
}
return true;
}
addPadding(input) {
const mod = input.length % 4;
if (mod === 2) return input + "==";
if (mod === 3) return input + "=";
if (mod === 1) throw new Error("Invalid JWT base64 padding");
return input;
}
};
// src/core/detectors/plugins/IbmDetector.ts
var IbmDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "IBM Cloud Credentials";
/**
* Detects:
* - IAM API keys (44-char alphanumeric)
* - COS HMAC secret keys (48-char hex)
*/
this.tokenRegex = new RegExp(
[
// 1. IBM IAM API key in context: ibm_cloud_api_key=...
`(?:ibm[_\\-]?cloud[_\\-]?iam|cloud[_\\-]?iam|ibm[_\\-]?cloud|ibm[_\\-]?iam|ibm|iam|cloud)?[_\\-]?(api)?[_\\-]?(key|pwd|password|pass|token)[_\\-]?["']?([a-zA-Z0-9_\\-]{44})(?![a-zA-Z0-9_\\-])`,
// 2. COS HMAC secret keys (contextual): ibm-cos-secret-key
`(?:ibm[-_]?cos[-_]?hmac|cos[-_]?hmac|ibm[-_]?cos|ibm[-_]?hmac|hmac|cos)?[-_]?secret[-_]?key["']?([a-f0-9]{48})(?![a-f0-9])`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/AWSDetector.ts
var AWSDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "AWS Secrets";
/**
* Conjunto de expresiones para múltiples tipos de secretos AWS.
*/
this.tokenRegex = new RegExp(
[
// 1. AWS Access Key ID (AKIA, ASIA, etc.)
"(?<![A-Z0-9])[A3T][A-Z0-9]{16}(?![A-Z0-9])",
// A3T-style
"(?<![A-Z0-9])(AKIA|ASIA|ABIA|ACCA)[0-9A-Z]{16}(?![A-Z0-9])",
// Classic patterns
// 2. AWS Secret Access Key (base64-like, 40 chars)
"(?<![A-Za-z0-9/+=])[A-Za-z0-9/+=]{40}(?![A-Za-z0-9/+=])",
// 3. AWS credentials with context (key|secret|token)
`(aws|amazon)?[^a-zA-Z0-9]?(key|pwd|pw|password|pass|token)[^a-zA-Z0-9]{0,3}["']([A-Za-z0-9/+=]{40,})["']`,
// 4. AWS CLI config format
"\\[default\\]\\s*aws_access_key_id\\s*=\\s*[A-Z0-9]{20}\\s*aws_secret_access_key\\s*=\\s*[A-Za-z0-9/+=]{40}",
// 5. AWS KMS Key IDs (UUIDs prefixed with alias/ or key/)
"arn:aws:kms:[a-z0-9-]+:\\d{12}:key/[a-f0-9-]{36}",
"alias/[A-Za-z0-9/_+=.@-]+",
// 6. AWS ARNs (S3, Lambda, SES, etc.)
`arn:aws:[a-z0-9-]+:[a-z0-9-]*:\\d{12}:[^\\s'"]+`,
// 7. AWS session token (variable name + base64)
`(aws_session_token|aws_security_token)[\\s:='"]+([A-Za-z0-9/+=]{16,})`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/NewRelicDetector.ts
var NewRelicDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "New Relic API Keys";
this.tokenRegex = new RegExp(
[
`NEW_RELIC_LICENSE_KEYs*[:=]s*["']?[a-zA-Z0-9]{40}["']?`,
`NEW_RELIC_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/SentryDetector.ts
var SentryDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Sentry Credentials";
this.tokenRegex = new RegExp(
[
`SENTRY_DSNs*[:=]s*["']?https://[a-zA-Z0-9]+@[a-zA-Z0-9.-]+/[0-9]+["']?`,
`SENTRY_AUTH_TOKENs*[:=]s*["']?[a-zA-Z0-9-_]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/MixpanelDetector.ts
var MixpanelDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Mixpanel Token";
this.tokenRegex = new RegExp(
[
`MIXPANEL_TOKENs*[:=]s*["']?[a-zA-Z0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/AmplitudeDetector.ts
var AmplitudeDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Amplitude API Key";
this.tokenRegex = new RegExp(
[
`AMPLITUDE_API_KEYs*[:=]s*["']?[a-zA-Z0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/LogtailDetector.ts
var LogtailDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Logtail / Betterstack Token";
this.tokenRegex = new RegExp(
[
`LOGTAIL_TOKENs*[:=]s*["']?[a-zA-Z0-9]{30,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/logs/DatadogDetector.ts
var DatadogDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Datadog API Keys";
this.tokenRegex = new RegExp(
[
`DATADOG_API_KEYs*[:=]s*["']?[a-z0-9]{32}["']?`,
`DD_API_KEYs*[:=]s*["']?[a-z0-9]{32}["']?`,
`DD_APP_KEYs*[:=]s*["']?[a-z0-9]{32}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/ReplicateDetector.ts
var ReplicateDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Replicate API Token";
this.tokenRegex = new RegExp(
[
`REPLICATE_API_TOKENs*[:=]s*["']?[a-z0-9_-]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/VespaDetector.ts
var VespaDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Vespa Cloud API Token";
this.tokenRegex = new RegExp(
[
`VESPA_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/VertexAIDetector.ts
var VertexAIDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Google Vertex AI Credentials";
this.tokenRegex = new RegExp(
[
"AIza[0-9A-Za-z-_]{35}",
`GOOGLE_VERTEX_API_KEYs*[:=]s*["']?AIza[0-9A-Za-z-_]{35}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/BasetenDetector.ts
var BasetenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Baseten API Key";
this.tokenRegex = new RegExp(
[
`BASETEN_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/AnthropicDetector.ts
var AnthropicDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Anthropic API Key";
this.tokenRegex = new RegExp(
[
"cla-[a-zA-Z0-9]{40,}",
`ANTHROPIC_API_KEYs*[:=]s*["']?cla-[a-zA-Z0-9]{40,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/StabilityAIDetector.ts
var StabilityAIDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Stability AI Token";
this.tokenRegex = new RegExp(
[
"stability-[a-zA-Z0-9]{40,}",
`STABILITY_API_KEYs*[:=]s*["']?stability-[a-zA-Z0-9]{40,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/WeaviateDetector.ts
var WeaviateDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Weaviate API Key";
this.tokenRegex = new RegExp(
[
`WEAVIATE_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{32,}["']?`,
"Authorization:s*Bearers*[a-zA-Z0-9-_]{20,}"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/LangSmithDetector.ts
var LangSmithDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "LangSmith API Key";
this.tokenRegex = new RegExp(
[
`LANGSMITH_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/OpenAIDetector.ts
var OpenAIDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "OpenAI API Key";
this.tokenRegex = new RegExp(
[
"sk-[a-zA-Z0-9]{48}",
`OPENAI_API_KEYs*[:=]s*["']?sk-[a-zA-Z0-9]{48}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/ChromaDetector.ts
var ChromaDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Chroma API Token";
this.tokenRegex = new RegExp(
[
`CHROMA_API_TOKENs*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/HuggingFaceDetector.ts
var HuggingFaceDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "HuggingFace Access Token";
this.tokenRegex = new RegExp(
[
"hf_[a-zA-Z0-9]{32,}",
`HUGGINGFACEHUB_API_TOKENs*[:=]s*["']?hf_[a-zA-Z0-9]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/LangChainDetector.ts
var LangChainDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "LangChain API Key";
this.tokenRegex = new RegExp(
[
`LANGCHAIN_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{20,}["']?`,
"langchain-js.vercel.app"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/MistralDetector.ts
var MistralDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Mistral API Key";
this.tokenRegex = new RegExp(
[
"mistral-[a-zA-Z0-9]{40,}",
`MISTRAL_API_KEYs*[:=]s*["']?mistral-[a-zA-Z0-9]{40,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/PineconeDetector.ts
var PineconeDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Pinecone API Key";
this.tokenRegex = new RegExp(
[
`PINECONE_API_KEYs*[:=]s*["']?[a-z0-9-]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/QdrantDetector.ts
var QdrantDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Qdrant API Key";
this.tokenRegex = new RegExp(
[
`QDRANT_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/CohereDetector.ts
var CohereDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Cohere API Key";
this.tokenRegex = new RegExp(
[
"cohere-[a-zA-Z0-9]{32,}",
`COHERE_API_KEYs*[:=]s*["']?cohere-[a-zA-Z0-9]{32,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/ai/PerplexityDetector.ts
var PerplexityDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Perplexity API Token";
this.tokenRegex = new RegExp(
[
`PERPLEXITY_API_KEYs*[:=]s*["']?[a-zA-Z0-9-_]{40,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/deployment/BitbucketTokenDetector.ts
var BitbucketTokenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Bitbucket Token";
this.tokenRegex = new RegExp(
[
`bitbucket_(client_id|secret)s*[:=]s*["']?[A-Za-z0-9-_]{20,}["']?`,
`BITBUCKET_(CLIENT|SECRET)_KEYs*[:=]s*["']?[A-Za-z0-9-_]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/deployment/CircleCITokenDetector.ts
var CircleCITokenDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "CircleCI Token";
this.tokenRegex = new RegExp(
[
`CIRCLECI_API_TOKENs*[:=]s*["']?[A-Za-z0-9]{20,}["']?`,
`circleci_tokens*[:=]s*["']?[A-Za-z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/deployment/AzureDevOpsDetector.ts
var AzureDevOpsDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Azure DevOps Token";
this.tokenRegex = new RegExp(
[
`AZURE_DEVOPS_(TOKEN|PAT)s*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`,
`ado_tokens*[:=]s*["']?[a-zA-Z0-9]{20,}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/NetlifyDetector.ts
var NetlifyDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Netlify Personal Access Token";
this.tokenRegex = new RegExp(
[
`NETLIFY_AUTH_TOKENs*[:=]s*["']?[a-zA-Z0-9]{40}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/VercelDetector.ts
var VercelDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Vercel Token";
this.tokenRegex = new RegExp(
[
`VERCEL_TOKENs*[:=]s*["']?[a-zA-Z0-9_-]{64,}["']?`,
"vercel.com.*token=[a-zA-Z0-9_-]{64,}"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/DigitalOceanDetector.ts
var DigitalOceanDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "DigitalOcean Personal Access Token";
this.tokenRegex = new RegExp(
[
`do_(prod|dev)?_?tokens*[:=]s*["']?[a-f0-9]{64}["']?`,
`DIGITALOCEAN_ACCESS_TOKENs*[:=]s*["']?[a-f0-9]{64}["']?`
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/GcpKeyDetector.ts
var GcpKeyDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "GCP Service Account Key";
this.tokenRegex = new RegExp(
[
'\\"type\\":\\s*\\"service_account\\"',
'\\"project_id\\":\\s*\\"[a-z0-9\\-]+\\"',
'\\"private_key_id\\":\\s*\\"[a-f0-9]{40}\\"',
'\\"private_key\\":\\s*\\"-----BEGIN PRIVATE KEY-----[\\s\\S]+?-----END PRIVATE KEY-----\\"'
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/HerokuDetector.ts
var HerokuDetector = class extends RegexBasedDetector {
constructor() {
super(...arguments);
this.secretType = "Heroku API Key";
this.tokenRegex = new RegExp(
[
`HEROKU_API_KEYs*[:=]s*["']?[a-f0-9]{32}["']?`,
"Authorization:s*Bearers*[a-f0-9]{32}"
].join("|"),
"gi"
);
}
};
// src/core/detectors/plugins/cloud/CloudflareDetector.ts
var CloudflareDetector = class extends RegexBasedDetector {
construct