@aion0/bastion 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +183 -0
- package/README.zh.md +468 -0
- package/config/default.yaml +73 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +31 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/env.d.ts +3 -0
- package/dist/cli/commands/env.d.ts.map +1 -0
- package/dist/cli/commands/env.js +83 -0
- package/dist/cli/commands/env.js.map +1 -0
- package/dist/cli/commands/health.d.ts +3 -0
- package/dist/cli/commands/health.d.ts.map +1 -0
- package/dist/cli/commands/health.js +45 -0
- package/dist/cli/commands/health.js.map +1 -0
- package/dist/cli/commands/openclaw.d.ts +3 -0
- package/dist/cli/commands/openclaw.d.ts.map +1 -0
- package/dist/cli/commands/openclaw.js +1062 -0
- package/dist/cli/commands/openclaw.js.map +1 -0
- package/dist/cli/commands/proxy.d.ts +8 -0
- package/dist/cli/commands/proxy.d.ts.map +1 -0
- package/dist/cli/commands/proxy.js +433 -0
- package/dist/cli/commands/proxy.js.map +1 -0
- package/dist/cli/commands/start.d.ts +3 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +62 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +3 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +32 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +3 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +28 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/token.d.ts +3 -0
- package/dist/cli/commands/token.d.ts.map +1 -0
- package/dist/cli/commands/token.js +32 -0
- package/dist/cli/commands/token.js.map +1 -0
- package/dist/cli/commands/trust-ca.d.ts +3 -0
- package/dist/cli/commands/trust-ca.d.ts.map +1 -0
- package/dist/cli/commands/trust-ca.js +44 -0
- package/dist/cli/commands/trust-ca.js.map +1 -0
- package/dist/cli/commands/wrap.d.ts +3 -0
- package/dist/cli/commands/wrap.d.ts.map +1 -0
- package/dist/cli/commands/wrap.js +70 -0
- package/dist/cli/commands/wrap.js.map +1 -0
- package/dist/cli/daemon.d.ts +11 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +82 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +35 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +60 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/manager.d.ts +12 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +73 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/paths.d.ts +10 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +16 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.d.ts +85 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +3 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/dashboard/api-routes.d.ts +6 -0
- package/dist/dashboard/api-routes.d.ts.map +1 -0
- package/dist/dashboard/api-routes.js +671 -0
- package/dist/dashboard/api-routes.js.map +1 -0
- package/dist/dashboard/api.d.ts +4 -0
- package/dist/dashboard/api.d.ts.map +1 -0
- package/dist/dashboard/api.js +25 -0
- package/dist/dashboard/api.js.map +1 -0
- package/dist/dashboard/page.d.ts +3 -0
- package/dist/dashboard/page.d.ts.map +1 -0
- package/dist/dashboard/page.js +1622 -0
- package/dist/dashboard/page.js.map +1 -0
- package/dist/dlp/actions.d.ts +13 -0
- package/dist/dlp/actions.d.ts.map +1 -0
- package/dist/dlp/actions.js +3 -0
- package/dist/dlp/actions.js.map +1 -0
- package/dist/dlp/ai-validator.d.ts +28 -0
- package/dist/dlp/ai-validator.d.ts.map +1 -0
- package/dist/dlp/ai-validator.js +214 -0
- package/dist/dlp/ai-validator.js.map +1 -0
- package/dist/dlp/engine.d.ts +34 -0
- package/dist/dlp/engine.d.ts.map +1 -0
- package/dist/dlp/engine.js +342 -0
- package/dist/dlp/engine.js.map +1 -0
- package/dist/dlp/entropy.d.ts +22 -0
- package/dist/dlp/entropy.d.ts.map +1 -0
- package/dist/dlp/entropy.js +43 -0
- package/dist/dlp/entropy.js.map +1 -0
- package/dist/dlp/message-cache.d.ts +45 -0
- package/dist/dlp/message-cache.d.ts.map +1 -0
- package/dist/dlp/message-cache.js +251 -0
- package/dist/dlp/message-cache.js.map +1 -0
- package/dist/dlp/patterns/context-aware.d.ts +4 -0
- package/dist/dlp/patterns/context-aware.d.ts.map +1 -0
- package/dist/dlp/patterns/context-aware.js +45 -0
- package/dist/dlp/patterns/context-aware.js.map +1 -0
- package/dist/dlp/patterns/high-confidence.d.ts +4 -0
- package/dist/dlp/patterns/high-confidence.d.ts.map +1 -0
- package/dist/dlp/patterns/high-confidence.js +140 -0
- package/dist/dlp/patterns/high-confidence.js.map +1 -0
- package/dist/dlp/patterns/prompt-injection.d.ts +4 -0
- package/dist/dlp/patterns/prompt-injection.d.ts.map +1 -0
- package/dist/dlp/patterns/prompt-injection.js +244 -0
- package/dist/dlp/patterns/prompt-injection.js.map +1 -0
- package/dist/dlp/patterns/validated.d.ts +4 -0
- package/dist/dlp/patterns/validated.d.ts.map +1 -0
- package/dist/dlp/patterns/validated.js +21 -0
- package/dist/dlp/patterns/validated.js.map +1 -0
- package/dist/dlp/remote-sync.d.ts +47 -0
- package/dist/dlp/remote-sync.d.ts.map +1 -0
- package/dist/dlp/remote-sync.js +252 -0
- package/dist/dlp/remote-sync.js.map +1 -0
- package/dist/dlp/semantics.d.ts +27 -0
- package/dist/dlp/semantics.d.ts.map +1 -0
- package/dist/dlp/semantics.js +93 -0
- package/dist/dlp/semantics.js.map +1 -0
- package/dist/dlp/structure.d.ts +25 -0
- package/dist/dlp/structure.d.ts.map +1 -0
- package/dist/dlp/structure.js +86 -0
- package/dist/dlp/structure.js.map +1 -0
- package/dist/dlp/validators.d.ts +6 -0
- package/dist/dlp/validators.d.ts.map +1 -0
- package/dist/dlp/validators.js +46 -0
- package/dist/dlp/validators.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +200 -0
- package/dist/index.js.map +1 -0
- package/dist/license/verify.d.ts +18 -0
- package/dist/license/verify.d.ts.map +1 -0
- package/dist/license/verify.js +71 -0
- package/dist/license/verify.js.map +1 -0
- package/dist/metrics/collector.d.ts +11 -0
- package/dist/metrics/collector.d.ts.map +1 -0
- package/dist/metrics/collector.js +17 -0
- package/dist/metrics/collector.js.map +1 -0
- package/dist/metrics/dashboard.d.ts +6 -0
- package/dist/metrics/dashboard.d.ts.map +1 -0
- package/dist/metrics/dashboard.js +66 -0
- package/dist/metrics/dashboard.js.map +1 -0
- package/dist/metrics/pricing.d.ts +10 -0
- package/dist/metrics/pricing.d.ts.map +1 -0
- package/dist/metrics/pricing.js +62 -0
- package/dist/metrics/pricing.js.map +1 -0
- package/dist/optimizer/cache.d.ts +14 -0
- package/dist/optimizer/cache.d.ts.map +1 -0
- package/dist/optimizer/cache.js +58 -0
- package/dist/optimizer/cache.js.map +1 -0
- package/dist/optimizer/estimator.d.ts +6 -0
- package/dist/optimizer/estimator.d.ts.map +1 -0
- package/dist/optimizer/estimator.js +12 -0
- package/dist/optimizer/estimator.js.map +1 -0
- package/dist/optimizer/reorder.d.ts +9 -0
- package/dist/optimizer/reorder.d.ts.map +1 -0
- package/dist/optimizer/reorder.js +27 -0
- package/dist/optimizer/reorder.js.map +1 -0
- package/dist/optimizer/trimmer.d.ts +9 -0
- package/dist/optimizer/trimmer.d.ts.map +1 -0
- package/dist/optimizer/trimmer.js +47 -0
- package/dist/optimizer/trimmer.js.map +1 -0
- package/dist/plugin-api/index.d.ts +3 -0
- package/dist/plugin-api/index.d.ts.map +1 -0
- package/dist/plugin-api/index.js +6 -0
- package/dist/plugin-api/index.js.map +1 -0
- package/dist/plugin-api/types.d.ts +77 -0
- package/dist/plugin-api/types.d.ts.map +1 -0
- package/dist/plugin-api/types.js +6 -0
- package/dist/plugin-api/types.js.map +1 -0
- package/dist/plugins/adapter.d.ts +12 -0
- package/dist/plugins/adapter.d.ts.map +1 -0
- package/dist/plugins/adapter.js +116 -0
- package/dist/plugins/adapter.js.map +1 -0
- package/dist/plugins/builtin/audit-logger.d.ts +9 -0
- package/dist/plugins/builtin/audit-logger.d.ts.map +1 -0
- package/dist/plugins/builtin/audit-logger.js +53 -0
- package/dist/plugins/builtin/audit-logger.js.map +1 -0
- package/dist/plugins/builtin/dlp-scanner.d.ts +19 -0
- package/dist/plugins/builtin/dlp-scanner.d.ts.map +1 -0
- package/dist/plugins/builtin/dlp-scanner.js +284 -0
- package/dist/plugins/builtin/dlp-scanner.js.map +1 -0
- package/dist/plugins/builtin/metrics-collector.d.ts +4 -0
- package/dist/plugins/builtin/metrics-collector.d.ts.map +1 -0
- package/dist/plugins/builtin/metrics-collector.js +111 -0
- package/dist/plugins/builtin/metrics-collector.js.map +1 -0
- package/dist/plugins/builtin/token-optimizer.d.ts +10 -0
- package/dist/plugins/builtin/token-optimizer.d.ts.map +1 -0
- package/dist/plugins/builtin/token-optimizer.js +120 -0
- package/dist/plugins/builtin/token-optimizer.js.map +1 -0
- package/dist/plugins/builtin/tool-guard.d.ts +20 -0
- package/dist/plugins/builtin/tool-guard.d.ts.map +1 -0
- package/dist/plugins/builtin/tool-guard.js +259 -0
- package/dist/plugins/builtin/tool-guard.js.map +1 -0
- package/dist/plugins/context.d.ts +8 -0
- package/dist/plugins/context.d.ts.map +1 -0
- package/dist/plugins/context.js +33 -0
- package/dist/plugins/context.js.map +1 -0
- package/dist/plugins/event-bus.d.ts +9 -0
- package/dist/plugins/event-bus.d.ts.map +1 -0
- package/dist/plugins/event-bus.js +25 -0
- package/dist/plugins/event-bus.js.map +1 -0
- package/dist/plugins/index.d.ts +18 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +148 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +14 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +98 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/types.d.ts +91 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +3 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/proxy/certs.d.ts +10 -0
- package/dist/proxy/certs.d.ts.map +1 -0
- package/dist/proxy/certs.js +110 -0
- package/dist/proxy/certs.js.map +1 -0
- package/dist/proxy/connect.d.ts +11 -0
- package/dist/proxy/connect.d.ts.map +1 -0
- package/dist/proxy/connect.js +298 -0
- package/dist/proxy/connect.js.map +1 -0
- package/dist/proxy/forwarder.d.ts +14 -0
- package/dist/proxy/forwarder.d.ts.map +1 -0
- package/dist/proxy/forwarder.js +342 -0
- package/dist/proxy/forwarder.js.map +1 -0
- package/dist/proxy/passthrough.d.ts +4 -0
- package/dist/proxy/passthrough.d.ts.map +1 -0
- package/dist/proxy/passthrough.js +68 -0
- package/dist/proxy/passthrough.js.map +1 -0
- package/dist/proxy/providers/anthropic.d.ts +4 -0
- package/dist/proxy/providers/anthropic.d.ts.map +1 -0
- package/dist/proxy/providers/anthropic.js +46 -0
- package/dist/proxy/providers/anthropic.js.map +1 -0
- package/dist/proxy/providers/classify.d.ts +14 -0
- package/dist/proxy/providers/classify.d.ts.map +1 -0
- package/dist/proxy/providers/classify.js +37 -0
- package/dist/proxy/providers/classify.js.map +1 -0
- package/dist/proxy/providers/claude-web.d.ts +8 -0
- package/dist/proxy/providers/claude-web.d.ts.map +1 -0
- package/dist/proxy/providers/claude-web.js +50 -0
- package/dist/proxy/providers/claude-web.js.map +1 -0
- package/dist/proxy/providers/gemini.d.ts +4 -0
- package/dist/proxy/providers/gemini.d.ts.map +1 -0
- package/dist/proxy/providers/gemini.js +38 -0
- package/dist/proxy/providers/gemini.js.map +1 -0
- package/dist/proxy/providers/index.d.ts +27 -0
- package/dist/proxy/providers/index.d.ts.map +1 -0
- package/dist/proxy/providers/index.js +32 -0
- package/dist/proxy/providers/index.js.map +1 -0
- package/dist/proxy/providers/messaging.d.ts +2 -0
- package/dist/proxy/providers/messaging.d.ts.map +1 -0
- package/dist/proxy/providers/messaging.js +53 -0
- package/dist/proxy/providers/messaging.js.map +1 -0
- package/dist/proxy/providers/openai.d.ts +4 -0
- package/dist/proxy/providers/openai.d.ts.map +1 -0
- package/dist/proxy/providers/openai.js +38 -0
- package/dist/proxy/providers/openai.js.map +1 -0
- package/dist/proxy/providers/telegram.d.ts +8 -0
- package/dist/proxy/providers/telegram.d.ts.map +1 -0
- package/dist/proxy/providers/telegram.js +35 -0
- package/dist/proxy/providers/telegram.js.map +1 -0
- package/dist/proxy/router.d.ts +12 -0
- package/dist/proxy/router.d.ts.map +1 -0
- package/dist/proxy/router.js +26 -0
- package/dist/proxy/router.js.map +1 -0
- package/dist/proxy/safety.d.ts +13 -0
- package/dist/proxy/safety.d.ts.map +1 -0
- package/dist/proxy/safety.js +58 -0
- package/dist/proxy/safety.js.map +1 -0
- package/dist/proxy/server.d.ts +8 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +126 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/proxy/streaming.d.ts +21 -0
- package/dist/proxy/streaming.d.ts.map +1 -0
- package/dist/proxy/streaming.js +70 -0
- package/dist/proxy/streaming.js.map +1 -0
- package/dist/storage/database.d.ts +6 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +44 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/encryption.d.ts +11 -0
- package/dist/storage/encryption.d.ts.map +1 -0
- package/dist/storage/encryption.js +47 -0
- package/dist/storage/encryption.js.map +1 -0
- package/dist/storage/migrations.d.ts +3 -0
- package/dist/storage/migrations.d.ts.map +1 -0
- package/dist/storage/migrations.js +265 -0
- package/dist/storage/migrations.js.map +1 -0
- package/dist/storage/repositories/audit-log.d.ts +115 -0
- package/dist/storage/repositories/audit-log.d.ts.map +1 -0
- package/dist/storage/repositories/audit-log.js +586 -0
- package/dist/storage/repositories/audit-log.js.map +1 -0
- package/dist/storage/repositories/cache.d.ts +26 -0
- package/dist/storage/repositories/cache.d.ts.map +1 -0
- package/dist/storage/repositories/cache.js +44 -0
- package/dist/storage/repositories/cache.js.map +1 -0
- package/dist/storage/repositories/dlp-config-history.d.ts +17 -0
- package/dist/storage/repositories/dlp-config-history.d.ts.map +1 -0
- package/dist/storage/repositories/dlp-config-history.js +30 -0
- package/dist/storage/repositories/dlp-config-history.js.map +1 -0
- package/dist/storage/repositories/dlp-events.d.ts +35 -0
- package/dist/storage/repositories/dlp-events.d.ts.map +1 -0
- package/dist/storage/repositories/dlp-events.js +57 -0
- package/dist/storage/repositories/dlp-events.js.map +1 -0
- package/dist/storage/repositories/dlp-patterns.d.ts +70 -0
- package/dist/storage/repositories/dlp-patterns.d.ts.map +1 -0
- package/dist/storage/repositories/dlp-patterns.js +187 -0
- package/dist/storage/repositories/dlp-patterns.js.map +1 -0
- package/dist/storage/repositories/optimizer-events.d.ts +28 -0
- package/dist/storage/repositories/optimizer-events.d.ts.map +1 -0
- package/dist/storage/repositories/optimizer-events.js +49 -0
- package/dist/storage/repositories/optimizer-events.js.map +1 -0
- package/dist/storage/repositories/plugin-events.d.ts +34 -0
- package/dist/storage/repositories/plugin-events.d.ts.map +1 -0
- package/dist/storage/repositories/plugin-events.js +64 -0
- package/dist/storage/repositories/plugin-events.js.map +1 -0
- package/dist/storage/repositories/requests.d.ts +68 -0
- package/dist/storage/repositories/requests.d.ts.map +1 -0
- package/dist/storage/repositories/requests.js +113 -0
- package/dist/storage/repositories/requests.js.map +1 -0
- package/dist/storage/repositories/sessions.d.ts +23 -0
- package/dist/storage/repositories/sessions.d.ts.map +1 -0
- package/dist/storage/repositories/sessions.js +42 -0
- package/dist/storage/repositories/sessions.js.map +1 -0
- package/dist/storage/repositories/tool-calls.d.ts +49 -0
- package/dist/storage/repositories/tool-calls.d.ts.map +1 -0
- package/dist/storage/repositories/tool-calls.js +61 -0
- package/dist/storage/repositories/tool-calls.js.map +1 -0
- package/dist/storage/repositories/tool-guard-rules.d.ts +50 -0
- package/dist/storage/repositories/tool-guard-rules.d.ts.map +1 -0
- package/dist/storage/repositories/tool-guard-rules.js +120 -0
- package/dist/storage/repositories/tool-guard-rules.js.map +1 -0
- package/dist/tool-guard/alert.d.ts +30 -0
- package/dist/tool-guard/alert.d.ts.map +1 -0
- package/dist/tool-guard/alert.js +113 -0
- package/dist/tool-guard/alert.js.map +1 -0
- package/dist/tool-guard/extractor.d.ts +10 -0
- package/dist/tool-guard/extractor.d.ts.map +1 -0
- package/dist/tool-guard/extractor.js +309 -0
- package/dist/tool-guard/extractor.js.map +1 -0
- package/dist/tool-guard/rules.d.ts +18 -0
- package/dist/tool-guard/rules.d.ts.map +1 -0
- package/dist/tool-guard/rules.js +255 -0
- package/dist/tool-guard/rules.js.map +1 -0
- package/dist/tool-guard/streaming-guard.d.ts +57 -0
- package/dist/tool-guard/streaming-guard.d.ts.map +1 -0
- package/dist/tool-guard/streaming-guard.js +389 -0
- package/dist/tool-guard/streaming-guard.js.map +1 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +8 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +54 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/timeout.d.ts +5 -0
- package/dist/utils/timeout.d.ts.map +1 -0
- package/dist/utils/timeout.js +26 -0
- package/dist/utils/timeout.js.map +1 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPatterns = getPatterns;
|
|
4
|
+
exports.scanText = scanText;
|
|
5
|
+
const validators_js_1 = require("./validators.js");
|
|
6
|
+
const high_confidence_js_1 = require("./patterns/high-confidence.js");
|
|
7
|
+
const validated_js_1 = require("./patterns/validated.js");
|
|
8
|
+
const context_aware_js_1 = require("./patterns/context-aware.js");
|
|
9
|
+
const prompt_injection_js_1 = require("./patterns/prompt-injection.js");
|
|
10
|
+
const structure_js_1 = require("./structure.js");
|
|
11
|
+
const entropy_js_1 = require("./entropy.js");
|
|
12
|
+
const semantics_js_1 = require("./semantics.js");
|
|
13
|
+
const PATTERN_TIMEOUT_MS = 50;
|
|
14
|
+
function runRegexWithPositions(regex, text, timeoutMs) {
|
|
15
|
+
const results = [];
|
|
16
|
+
const start = Date.now();
|
|
17
|
+
const cloned = new RegExp(regex.source, regex.flags);
|
|
18
|
+
let match;
|
|
19
|
+
while ((match = cloned.exec(text)) !== null) {
|
|
20
|
+
results.push({ match: match[0], index: match.index });
|
|
21
|
+
if (Date.now() - start > timeoutMs)
|
|
22
|
+
break;
|
|
23
|
+
if (match.index === cloned.lastIndex)
|
|
24
|
+
cloned.lastIndex++;
|
|
25
|
+
}
|
|
26
|
+
return results;
|
|
27
|
+
}
|
|
28
|
+
function runRegexWithTimeout(regex, text, timeoutMs) {
|
|
29
|
+
const matches = [];
|
|
30
|
+
const start = Date.now();
|
|
31
|
+
// Clone regex to reset lastIndex
|
|
32
|
+
const cloned = new RegExp(regex.source, regex.flags);
|
|
33
|
+
let match;
|
|
34
|
+
while ((match = cloned.exec(text)) !== null) {
|
|
35
|
+
matches.push(match[0]);
|
|
36
|
+
if (Date.now() - start > timeoutMs)
|
|
37
|
+
break;
|
|
38
|
+
// Prevent infinite loops on zero-length matches
|
|
39
|
+
if (match.index === cloned.lastIndex)
|
|
40
|
+
cloned.lastIndex++;
|
|
41
|
+
}
|
|
42
|
+
return matches;
|
|
43
|
+
}
|
|
44
|
+
const CONTEXT_RADIUS = 200; // chars around match to look for context words
|
|
45
|
+
/** Match a context word in text. Short words (<=3 chars) use word-boundary matching
|
|
46
|
+
* to avoid substring false positives (e.g., 'ip' matching inside 'script'). */
|
|
47
|
+
function contextWordMatches(haystack, word) {
|
|
48
|
+
const lowerWord = word.toLowerCase();
|
|
49
|
+
// Words with underscores, dots, or length > 3 are specific enough for substring match
|
|
50
|
+
if (lowerWord.length > 3 || /[_.]/.test(lowerWord)) {
|
|
51
|
+
return haystack.includes(lowerWord);
|
|
52
|
+
}
|
|
53
|
+
// Short words need word-boundary matching
|
|
54
|
+
const escaped = lowerWord.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
55
|
+
return new RegExp(`\\b${escaped}\\b`, 'i').test(haystack);
|
|
56
|
+
}
|
|
57
|
+
function hasContext(text, contextWords) {
|
|
58
|
+
const lower = text.toLowerCase();
|
|
59
|
+
return contextWords.some((word) => contextWordMatches(lower, word));
|
|
60
|
+
}
|
|
61
|
+
/** Check if any context word appears within CONTEXT_RADIUS chars of the match position */
|
|
62
|
+
function hasNearbyContext(text, matchIndex, matchLength, contextWords) {
|
|
63
|
+
const start = Math.max(0, matchIndex - CONTEXT_RADIUS);
|
|
64
|
+
const end = Math.min(text.length, matchIndex + matchLength + CONTEXT_RADIUS);
|
|
65
|
+
const nearby = text.slice(start, end);
|
|
66
|
+
return contextWords.some((word) => contextWordMatches(nearby, word));
|
|
67
|
+
}
|
|
68
|
+
const VERIFY_CONTEXT_RADIUS = 300;
|
|
69
|
+
/** Check if a position in text falls inside a markdown code block (``` ... ```) */
|
|
70
|
+
function isInsideCodeBlock(text, matchIndex) {
|
|
71
|
+
let inside = false;
|
|
72
|
+
let i = 0;
|
|
73
|
+
while (i < matchIndex) {
|
|
74
|
+
if (text[i] === '`' && i + 2 < text.length && text[i + 1] === '`' && text[i + 2] === '`') {
|
|
75
|
+
inside = !inside;
|
|
76
|
+
i += 3;
|
|
77
|
+
// skip to end of line for opening fence (language tag)
|
|
78
|
+
if (inside)
|
|
79
|
+
while (i < matchIndex && text[i] !== '\n')
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
i++;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return inside;
|
|
87
|
+
}
|
|
88
|
+
/** Post-match context verification (free tier — always runs) */
|
|
89
|
+
function contextVerifyMatch(text, match, matchIndex, verify) {
|
|
90
|
+
// 1. rejectInCodeBlock
|
|
91
|
+
if (verify.rejectInCodeBlock && isInsideCodeBlock(text, matchIndex)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
// 2. minEntropy
|
|
95
|
+
if (verify.minEntropy !== undefined) {
|
|
96
|
+
const entropy = (0, entropy_js_1.shannonEntropy)(match);
|
|
97
|
+
if (entropy < verify.minEntropy)
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
// 3. antiPatterns — extract context window, reject if any matches
|
|
101
|
+
const start = Math.max(0, matchIndex - VERIFY_CONTEXT_RADIUS);
|
|
102
|
+
const end = Math.min(text.length, matchIndex + match.length + VERIFY_CONTEXT_RADIUS);
|
|
103
|
+
const context = text.slice(start, end);
|
|
104
|
+
if (verify.antiPatterns) {
|
|
105
|
+
for (const ap of verify.antiPatterns) {
|
|
106
|
+
ap.lastIndex = 0; // reset in case regex has 'g' flag
|
|
107
|
+
if (ap.test(context))
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// 4. confirmPatterns — require at least one match
|
|
112
|
+
if (verify.confirmPatterns && verify.confirmPatterns.length > 0) {
|
|
113
|
+
const confirmed = verify.confirmPatterns.some(cp => {
|
|
114
|
+
cp.lastIndex = 0;
|
|
115
|
+
return cp.test(context);
|
|
116
|
+
});
|
|
117
|
+
if (!confirmed)
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
function getPatterns(categories) {
|
|
123
|
+
const all = [];
|
|
124
|
+
const catSet = new Set(categories);
|
|
125
|
+
if (catSet.has('high-confidence'))
|
|
126
|
+
all.push(...high_confidence_js_1.highConfidencePatterns);
|
|
127
|
+
if (catSet.has('validated'))
|
|
128
|
+
all.push(...validated_js_1.validatedPatterns);
|
|
129
|
+
if (catSet.has('context-aware'))
|
|
130
|
+
all.push(...context_aware_js_1.contextAwarePatterns);
|
|
131
|
+
if (catSet.has('prompt-injection'))
|
|
132
|
+
all.push(...prompt_injection_js_1.promptInjectionPatterns);
|
|
133
|
+
return all;
|
|
134
|
+
}
|
|
135
|
+
function scanText(text, patterns, action, trace) {
|
|
136
|
+
const findings = [];
|
|
137
|
+
let redactedBody = text;
|
|
138
|
+
const t0 = trace ? performance.now() : 0;
|
|
139
|
+
if (trace) {
|
|
140
|
+
trace.entries.push({ layer: -1, layerName: 'init', step: 'start', detail: `Input: ${text.length} chars, ${patterns.length} patterns, action=${action}` });
|
|
141
|
+
}
|
|
142
|
+
// ── Layer 2: Regex pattern matching ──
|
|
143
|
+
const regexStart = trace ? performance.now() : 0;
|
|
144
|
+
for (const pattern of patterns) {
|
|
145
|
+
const patStart = trace ? performance.now() : 0;
|
|
146
|
+
// Quick pre-check: if context words don't appear anywhere, skip entirely
|
|
147
|
+
if (pattern.requireContext && !hasContext(text, pattern.requireContext)) {
|
|
148
|
+
if (trace) {
|
|
149
|
+
trace.entries.push({
|
|
150
|
+
layer: 2, layerName: 'regex', step: 'context-skip',
|
|
151
|
+
detail: `[${pattern.name}] context words [${pattern.requireContext.join(', ')}] not found in text — skipped`,
|
|
152
|
+
durationMs: performance.now() - patStart,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Use position-aware matching when requireContext or contextVerify needs it
|
|
158
|
+
const needPositions = !!(pattern.requireContext || pattern.contextVerify);
|
|
159
|
+
let matches;
|
|
160
|
+
let posMatches;
|
|
161
|
+
if (needPositions) {
|
|
162
|
+
posMatches = runRegexWithPositions(pattern.regex, text, PATTERN_TIMEOUT_MS);
|
|
163
|
+
if (pattern.requireContext) {
|
|
164
|
+
const filtered = posMatches.filter((m) => hasNearbyContext(text, m.index, m.match.length, pattern.requireContext));
|
|
165
|
+
if (trace) {
|
|
166
|
+
trace.entries.push({
|
|
167
|
+
layer: 2, layerName: 'regex', step: 'context-match',
|
|
168
|
+
detail: `[${pattern.name}] regex matched ${posMatches.length}, ${filtered.length} with nearby context [${pattern.requireContext.join(', ')}]`,
|
|
169
|
+
durationMs: performance.now() - patStart,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
posMatches = filtered;
|
|
173
|
+
}
|
|
174
|
+
else if (trace) {
|
|
175
|
+
trace.entries.push({
|
|
176
|
+
layer: 2, layerName: 'regex', step: 'match',
|
|
177
|
+
detail: `[${pattern.name}] (${pattern.category}) regex /${pattern.regex.source}/ → ${posMatches.length} match(es)${posMatches.length > 0 ? ': ' + posMatches.map(m => m.match.length > 40 ? m.match.slice(0, 40) + '...' : m.match).join(', ') : ''}`,
|
|
178
|
+
durationMs: performance.now() - patStart,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
matches = posMatches.map((m) => m.match);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
matches = runRegexWithTimeout(pattern.regex, text, PATTERN_TIMEOUT_MS);
|
|
185
|
+
if (trace) {
|
|
186
|
+
trace.entries.push({
|
|
187
|
+
layer: 2, layerName: 'regex', step: 'match',
|
|
188
|
+
detail: `[${pattern.name}] (${pattern.category}) regex /${pattern.regex.source}/ → ${matches.length} match(es)${matches.length > 0 ? ': ' + matches.map(m => m.length > 40 ? m.slice(0, 40) + '...' : m).join(', ') : ''}`,
|
|
189
|
+
durationMs: performance.now() - patStart,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (matches.length === 0)
|
|
194
|
+
continue;
|
|
195
|
+
// Run validator if one is specified
|
|
196
|
+
const validatedMatches = pattern.validator
|
|
197
|
+
? matches.filter((m) => validators_js_1.validators[pattern.validator]?.(m) ?? true)
|
|
198
|
+
: matches;
|
|
199
|
+
if (trace && pattern.validator) {
|
|
200
|
+
const rejected = matches.length - validatedMatches.length;
|
|
201
|
+
trace.entries.push({
|
|
202
|
+
layer: 2, layerName: 'regex', step: 'validate',
|
|
203
|
+
detail: `[${pattern.name}] validator "${pattern.validator}": ${validatedMatches.length} passed, ${rejected} rejected`,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (validatedMatches.length === 0)
|
|
207
|
+
continue;
|
|
208
|
+
// Context verification (free tier — always runs when contextVerify is defined)
|
|
209
|
+
let verifiedMatches = validatedMatches;
|
|
210
|
+
if (pattern.contextVerify && posMatches) {
|
|
211
|
+
// Build verified list from posMatches to preserve per-occurrence position info
|
|
212
|
+
// (avoids find-first-match bug when same string appears at multiple positions)
|
|
213
|
+
const validatedSet = new Set(validatedMatches);
|
|
214
|
+
verifiedMatches = [];
|
|
215
|
+
for (const pos of posMatches) {
|
|
216
|
+
if (!validatedSet.has(pos.match))
|
|
217
|
+
continue; // filtered by validator
|
|
218
|
+
if (contextVerifyMatch(text, pos.match, pos.index, pattern.contextVerify)) {
|
|
219
|
+
verifiedMatches.push(pos.match);
|
|
220
|
+
}
|
|
221
|
+
else if (trace) {
|
|
222
|
+
trace.entries.push({
|
|
223
|
+
layer: 2, layerName: 'regex', step: 'context-verify-reject',
|
|
224
|
+
detail: `[${pattern.name}] match "${pos.match.length > 30 ? pos.match.slice(0, 30) + '...' : pos.match}" rejected by context verification`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (verifiedMatches.length === 0)
|
|
230
|
+
continue;
|
|
231
|
+
findings.push({
|
|
232
|
+
patternName: pattern.name,
|
|
233
|
+
patternCategory: pattern.category,
|
|
234
|
+
matchCount: verifiedMatches.length,
|
|
235
|
+
matches: verifiedMatches,
|
|
236
|
+
});
|
|
237
|
+
// Apply redaction if needed
|
|
238
|
+
if (action === 'redact') {
|
|
239
|
+
for (const m of verifiedMatches) {
|
|
240
|
+
redactedBody = redactedBody.replaceAll(m, `[${pattern.name.toUpperCase()}_REDACTED]`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (trace) {
|
|
245
|
+
trace.entries.push({
|
|
246
|
+
layer: 2, layerName: 'regex', step: 'summary',
|
|
247
|
+
detail: `Layer 2 complete: ${findings.length} finding(s) from regex patterns`,
|
|
248
|
+
durationMs: performance.now() - regexStart,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// ── Layer 0 + 1 + 3: Structure → Entropy → Semantic detection ──
|
|
252
|
+
// Detect generic secrets: high-entropy values in sensitive field names
|
|
253
|
+
// that were NOT already caught by a specific regex pattern above.
|
|
254
|
+
const structStart = trace ? performance.now() : 0;
|
|
255
|
+
const fields = (0, structure_js_1.extractStructuredFields)(text);
|
|
256
|
+
if (trace) {
|
|
257
|
+
trace.entries.push({
|
|
258
|
+
layer: 0, layerName: 'structure', step: 'extract',
|
|
259
|
+
detail: `Layer 0: extracted ${fields.length} field(s) from text${fields.length > 0 ? ' — ' + fields.map(f => `${f.path}=${f.value.length > 20 ? f.value.slice(0, 20) + '...' : f.value}`).join('; ') : ''}`,
|
|
260
|
+
durationMs: performance.now() - structStart,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
for (const field of fields) {
|
|
264
|
+
if (field.value.length < entropy_js_1.MIN_ENTROPY_LENGTH || field.value.length > entropy_js_1.MAX_SECRET_LENGTH) {
|
|
265
|
+
if (trace) {
|
|
266
|
+
trace.entries.push({
|
|
267
|
+
layer: 1, layerName: 'entropy', step: 'length-skip',
|
|
268
|
+
detail: `[${field.path}] value length ${field.value.length} outside range [${entropy_js_1.MIN_ENTROPY_LENGTH}, ${entropy_js_1.MAX_SECRET_LENGTH}] — skipped`,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
const sensitive = (0, semantics_js_1.isSensitiveFieldName)(field.key);
|
|
274
|
+
if (!sensitive) {
|
|
275
|
+
if (trace) {
|
|
276
|
+
trace.entries.push({
|
|
277
|
+
layer: 3, layerName: 'semantics', step: 'not-sensitive',
|
|
278
|
+
detail: `[${field.path}] field name "${field.key}" not sensitive — skipped`,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const entropy = (0, entropy_js_1.shannonEntropy)(field.value);
|
|
284
|
+
const highEnt = entropy >= entropy_js_1.DEFAULT_ENTROPY_THRESHOLD;
|
|
285
|
+
if (trace) {
|
|
286
|
+
trace.entries.push({
|
|
287
|
+
layer: 1, layerName: 'entropy', step: highEnt ? 'high' : 'low',
|
|
288
|
+
detail: `[${field.path}] entropy=${entropy.toFixed(3)} bits/char (threshold=${entropy_js_1.DEFAULT_ENTROPY_THRESHOLD})${highEnt ? ' → HIGH' : ' → low, skipped'}`,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (!highEnt)
|
|
292
|
+
continue;
|
|
293
|
+
// Check if this value is already covered by a regex finding
|
|
294
|
+
const alreadyCovered = findings.some((f) => f.matches.some((m) => field.value.includes(m) || m.includes(field.value)));
|
|
295
|
+
if (alreadyCovered) {
|
|
296
|
+
if (trace) {
|
|
297
|
+
trace.entries.push({
|
|
298
|
+
layer: 1, layerName: 'entropy', step: 'dedup',
|
|
299
|
+
detail: `[${field.path}] already covered by regex finding — skipped`,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (trace) {
|
|
305
|
+
trace.entries.push({
|
|
306
|
+
layer: 1, layerName: 'entropy', step: 'finding',
|
|
307
|
+
detail: `[${field.path}] ✓ generic-secret detected: sensitive field "${field.key}" + high entropy (${entropy.toFixed(3)})`,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
findings.push({
|
|
311
|
+
patternName: 'generic-secret',
|
|
312
|
+
patternCategory: 'entropy',
|
|
313
|
+
matchCount: 1,
|
|
314
|
+
matches: [field.value],
|
|
315
|
+
});
|
|
316
|
+
if (action === 'redact') {
|
|
317
|
+
redactedBody = redactedBody.replaceAll(field.value, '[GENERIC-SECRET_REDACTED]');
|
|
318
|
+
// Also handle JSON-encoded version (escapes like \" or \\n)
|
|
319
|
+
const encoded = JSON.stringify(field.value).slice(1, -1);
|
|
320
|
+
if (encoded !== field.value) {
|
|
321
|
+
redactedBody = redactedBody.replaceAll(encoded, '[GENERIC-SECRET_REDACTED]');
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
if (trace) {
|
|
326
|
+
trace.totalDurationMs = performance.now() - t0;
|
|
327
|
+
trace.entries.push({
|
|
328
|
+
layer: -1, layerName: 'summary', step: 'done',
|
|
329
|
+
detail: `Scan complete: ${findings.length} total finding(s), action=${findings.length === 0 ? 'pass' : action}, ${trace.totalDurationMs.toFixed(2)}ms`,
|
|
330
|
+
durationMs: trace.totalDurationMs,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
if (findings.length === 0) {
|
|
334
|
+
return { action: 'pass', findings: [] };
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
action,
|
|
338
|
+
findings,
|
|
339
|
+
redactedBody: action === 'redact' ? redactedBody : undefined,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/dlp/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 1: Entropy Pre-filter
|
|
3
|
+
*
|
|
4
|
+
* Shannon entropy measures information density (randomness) of a string.
|
|
5
|
+
* Secrets and API keys typically have high entropy (4.5–6.0 bits/char),
|
|
6
|
+
* while natural language text averages 3.0–4.0 bits/char.
|
|
7
|
+
*
|
|
8
|
+
* Used as a pre-filter: only high-entropy values proceed to deeper analysis.
|
|
9
|
+
*/
|
|
10
|
+
/** Calculate Shannon entropy in bits per character */
|
|
11
|
+
export declare function shannonEntropy(s: string): number;
|
|
12
|
+
/** Default threshold: values at or above this are likely secrets.
|
|
13
|
+
* Real API keys / secrets: 4.5–6.0 bits/char. Natural language: 3.0–4.0.
|
|
14
|
+
* 4.0 avoids overlap zone and reduces false positives on URLs, paths, code. */
|
|
15
|
+
export declare const DEFAULT_ENTROPY_THRESHOLD = 4;
|
|
16
|
+
/** Minimum length for entropy analysis to be meaningful */
|
|
17
|
+
export declare const MIN_ENTROPY_LENGTH = 8;
|
|
18
|
+
/** Maximum length for a single secret value (longer strings are content, not secrets) */
|
|
19
|
+
export declare const MAX_SECRET_LENGTH = 200;
|
|
20
|
+
/** Check if a string likely contains a secret based on entropy */
|
|
21
|
+
export declare function isHighEntropy(s: string, threshold?: number): boolean;
|
|
22
|
+
//# sourceMappingURL=entropy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entropy.d.ts","sourceRoot":"","sources":["../../src/dlp/entropy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBhD;AAED;;+EAE+E;AAC/E,eAAO,MAAM,yBAAyB,IAAM,CAAC;AAE7C,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,kEAAkE;AAClE,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,SAA4B,GAAG,OAAO,CAEvF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Layer 1: Entropy Pre-filter
|
|
4
|
+
*
|
|
5
|
+
* Shannon entropy measures information density (randomness) of a string.
|
|
6
|
+
* Secrets and API keys typically have high entropy (4.5–6.0 bits/char),
|
|
7
|
+
* while natural language text averages 3.0–4.0 bits/char.
|
|
8
|
+
*
|
|
9
|
+
* Used as a pre-filter: only high-entropy values proceed to deeper analysis.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.MAX_SECRET_LENGTH = exports.MIN_ENTROPY_LENGTH = exports.DEFAULT_ENTROPY_THRESHOLD = void 0;
|
|
13
|
+
exports.shannonEntropy = shannonEntropy;
|
|
14
|
+
exports.isHighEntropy = isHighEntropy;
|
|
15
|
+
/** Calculate Shannon entropy in bits per character */
|
|
16
|
+
function shannonEntropy(s) {
|
|
17
|
+
if (s.length === 0)
|
|
18
|
+
return 0;
|
|
19
|
+
const freq = new Map();
|
|
20
|
+
for (const ch of s) {
|
|
21
|
+
freq.set(ch, (freq.get(ch) ?? 0) + 1);
|
|
22
|
+
}
|
|
23
|
+
let h = 0;
|
|
24
|
+
const len = s.length;
|
|
25
|
+
for (const count of freq.values()) {
|
|
26
|
+
const p = count / len;
|
|
27
|
+
h -= p * Math.log2(p);
|
|
28
|
+
}
|
|
29
|
+
return h;
|
|
30
|
+
}
|
|
31
|
+
/** Default threshold: values at or above this are likely secrets.
|
|
32
|
+
* Real API keys / secrets: 4.5–6.0 bits/char. Natural language: 3.0–4.0.
|
|
33
|
+
* 4.0 avoids overlap zone and reduces false positives on URLs, paths, code. */
|
|
34
|
+
exports.DEFAULT_ENTROPY_THRESHOLD = 4.0;
|
|
35
|
+
/** Minimum length for entropy analysis to be meaningful */
|
|
36
|
+
exports.MIN_ENTROPY_LENGTH = 8;
|
|
37
|
+
/** Maximum length for a single secret value (longer strings are content, not secrets) */
|
|
38
|
+
exports.MAX_SECRET_LENGTH = 200;
|
|
39
|
+
/** Check if a string likely contains a secret based on entropy */
|
|
40
|
+
function isHighEntropy(s, threshold = exports.DEFAULT_ENTROPY_THRESHOLD) {
|
|
41
|
+
return s.length >= exports.MIN_ENTROPY_LENGTH && shannonEntropy(s) >= threshold;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=entropy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entropy.js","sourceRoot":"","sources":["../../src/dlp/entropy.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAGH,wCAgBC;AAcD,sCAEC;AAjCD,sDAAsD;AACtD,SAAgB,cAAc,CAAC,CAAS;IACtC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAE7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC;QACtB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;+EAE+E;AAClE,QAAA,yBAAyB,GAAG,GAAG,CAAC;AAE7C,2DAA2D;AAC9C,QAAA,kBAAkB,GAAG,CAAC,CAAC;AAEpC,yFAAyF;AAC5E,QAAA,iBAAiB,GAAG,GAAG,CAAC;AAErC,kEAAkE;AAClE,SAAgB,aAAa,CAAC,CAAS,EAAE,SAAS,GAAG,iCAAyB;IAC5E,OAAO,CAAC,CAAC,MAAM,IAAI,0BAAkB,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message-level DLP cache.
|
|
3
|
+
*
|
|
4
|
+
* LLM API requests carry the full conversation history in a `messages[]` array.
|
|
5
|
+
* Without caching, every turn re-scans ALL previous messages — O(N²) cumulative.
|
|
6
|
+
*
|
|
7
|
+
* This module hashes individual messages and caches their DLP findings so that
|
|
8
|
+
* only new/unseen messages are scanned. Complexity drops to O(N).
|
|
9
|
+
*
|
|
10
|
+
* Cache also distinguishes between "new findings" (first detection) and
|
|
11
|
+
* "cached findings" (repeated from history) so the caller can decide
|
|
12
|
+
* whether to record duplicate DLP events.
|
|
13
|
+
*/
|
|
14
|
+
import { type DlpPattern } from './engine.js';
|
|
15
|
+
import type { DlpFinding, DlpResult, DlpAction } from './actions.js';
|
|
16
|
+
export interface MessageCacheStats {
|
|
17
|
+
hits: number;
|
|
18
|
+
misses: number;
|
|
19
|
+
size: number;
|
|
20
|
+
}
|
|
21
|
+
export interface CachedDlpResult extends DlpResult {
|
|
22
|
+
/** Findings from newly scanned messages (first-time detection) */
|
|
23
|
+
newFindings: DlpFinding[];
|
|
24
|
+
/** Findings from cache (already detected in a previous request) */
|
|
25
|
+
cachedFindings: DlpFinding[];
|
|
26
|
+
}
|
|
27
|
+
export declare class DlpMessageCache {
|
|
28
|
+
private cache;
|
|
29
|
+
private hits;
|
|
30
|
+
private misses;
|
|
31
|
+
constructor(maxSize?: number);
|
|
32
|
+
get stats(): MessageCacheStats;
|
|
33
|
+
/**
|
|
34
|
+
* Scan a request body with message-level caching.
|
|
35
|
+
*
|
|
36
|
+
* If parsedBody has a `messages[]` array, each message is individually
|
|
37
|
+
* hashed and checked against the cache. Only new messages are scanned.
|
|
38
|
+
*
|
|
39
|
+
* Falls back to full-body scan for non-messages payloads.
|
|
40
|
+
*/
|
|
41
|
+
scanWithCache(body: string, parsedBody: Record<string, unknown>, patterns: DlpPattern[], action: DlpAction): CachedDlpResult;
|
|
42
|
+
/** Clear the cache (for testing or config changes) */
|
|
43
|
+
clear(): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=message-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-cache.d.ts","sourceRoot":"","sources":["../../src/dlp/message-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAqErE,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAaD,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,kEAAkE;IAClE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,mEAAmE;IACnE,cAAc,EAAE,UAAU,EAAE,CAAC;CAC9B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAEP,OAAO,SAAO;IAI1B,IAAI,KAAK,IAAI,iBAAiB,CAE7B;IAED;;;;;;;OAOG;IACH,aAAa,CACX,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,EAAE,UAAU,EAAE,EACtB,MAAM,EAAE,SAAS,GAChB,eAAe;IAoKlB,sDAAsD;IACtD,KAAK,IAAI,IAAI;CAKd"}
|