shieldcortex 2.6.4 → 2.7.1

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.
Files changed (80) hide show
  1. package/README.md +36 -5
  2. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  3. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  4. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +2 -2
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +3 -3
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +3 -3
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_25b1b286._.js +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  32. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/static/chunks/00fd16d311d2adfc.css +3 -0
  35. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{3255204bf9fadccd.js → 8d38247f89b93596.js} +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{d0e13004c4367a98.js → a4856321b5a33f59.js} +1 -1
  37. package/dist/api/visualization-server.d.ts.map +1 -1
  38. package/dist/api/visualization-server.js +29 -1
  39. package/dist/api/visualization-server.js.map +1 -1
  40. package/dist/cloud/cli.d.ts.map +1 -1
  41. package/dist/cloud/cli.js +18 -3
  42. package/dist/cloud/cli.js.map +1 -1
  43. package/dist/cloud/config.d.ts +9 -0
  44. package/dist/cloud/config.d.ts.map +1 -1
  45. package/dist/cloud/config.js +23 -0
  46. package/dist/cloud/config.js.map +1 -1
  47. package/dist/defence/__tests__/credential-leak.test.d.ts +8 -0
  48. package/dist/defence/__tests__/credential-leak.test.d.ts.map +1 -0
  49. package/dist/defence/__tests__/credential-leak.test.js +403 -0
  50. package/dist/defence/__tests__/credential-leak.test.js.map +1 -0
  51. package/dist/defence/credential-leak/entropy.d.ts +42 -0
  52. package/dist/defence/credential-leak/entropy.d.ts.map +1 -0
  53. package/dist/defence/credential-leak/entropy.js +105 -0
  54. package/dist/defence/credential-leak/entropy.js.map +1 -0
  55. package/dist/defence/credential-leak/index.d.ts +54 -0
  56. package/dist/defence/credential-leak/index.d.ts.map +1 -0
  57. package/dist/defence/credential-leak/index.js +168 -0
  58. package/dist/defence/credential-leak/index.js.map +1 -0
  59. package/dist/defence/credential-leak/patterns.d.ts +26 -0
  60. package/dist/defence/credential-leak/patterns.d.ts.map +1 -0
  61. package/dist/defence/credential-leak/patterns.js +304 -0
  62. package/dist/defence/credential-leak/patterns.js.map +1 -0
  63. package/dist/defence/index.d.ts +4 -2
  64. package/dist/defence/index.d.ts.map +1 -1
  65. package/dist/defence/index.js +3 -1
  66. package/dist/defence/index.js.map +1 -1
  67. package/dist/defence/pipeline.d.ts +1 -1
  68. package/dist/defence/pipeline.d.ts.map +1 -1
  69. package/dist/defence/pipeline.js +26 -3
  70. package/dist/defence/pipeline.js.map +1 -1
  71. package/dist/defence/types.d.ts +1 -0
  72. package/dist/defence/types.d.ts.map +1 -1
  73. package/dist/defence/types.js.map +1 -1
  74. package/dist/index.js +7 -0
  75. package/dist/index.js.map +1 -1
  76. package/package.json +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/static/chunks/ddb21377f32257df.css +0 -3
  78. /package/dashboard/.next/standalone/dashboard/.next/static/{ku0ZhFF_US0fWJ3A7pvJa → d3yvcqXn0tuMKtjxk5bhH}/_buildManifest.js +0 -0
  79. /package/dashboard/.next/standalone/dashboard/.next/static/{ku0ZhFF_US0fWJ3A7pvJa → d3yvcqXn0tuMKtjxk5bhH}/_clientMiddlewareManifest.json +0 -0
  80. /package/dashboard/.next/standalone/dashboard/.next/static/{ku0ZhFF_US0fWJ3A7pvJa → d3yvcqXn0tuMKtjxk5bhH}/_ssgManifest.js +0 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Credential Leak Detection — Entropy Analysis
3
+ *
4
+ * Shannon entropy calculation for detecting high-entropy strings
5
+ * that look like secrets (random tokens, keys, passwords).
6
+ */
7
+ /**
8
+ * Calculate Shannon entropy of a string (bits per character).
9
+ * Higher entropy = more random/unpredictable.
10
+ *
11
+ * Reference values:
12
+ * - English text: ~3.5-4.0
13
+ * - Base64 encoded: ~5.0-5.5
14
+ * - Random hex: ~3.5-4.0
15
+ * - Random alphanumeric: ~5.5-5.9
16
+ * - Crypto keys: ~5.5-6.0+
17
+ */
18
+ export function shannonEntropy(str) {
19
+ if (str.length === 0)
20
+ return 0;
21
+ const freq = new Map();
22
+ for (const ch of str) {
23
+ freq.set(ch, (freq.get(ch) ?? 0) + 1);
24
+ }
25
+ let entropy = 0;
26
+ const len = str.length;
27
+ for (const count of freq.values()) {
28
+ const p = count / len;
29
+ entropy -= p * Math.log2(p);
30
+ }
31
+ return entropy;
32
+ }
33
+ /** Minimum string length for entropy-based detection */
34
+ export const MIN_ENTROPY_LENGTH = 20;
35
+ /** Entropy threshold — strings above this are flagged */
36
+ export const ENTROPY_THRESHOLD = 4.5;
37
+ /**
38
+ * Check if a string looks like a high-entropy secret.
39
+ * Returns confidence score (0-1) or null if not suspicious.
40
+ */
41
+ export function checkHighEntropy(str) {
42
+ if (str.length < MIN_ENTROPY_LENGTH)
43
+ return null;
44
+ const entropy = shannonEntropy(str);
45
+ if (entropy < ENTROPY_THRESHOLD)
46
+ return null;
47
+ // Confidence scales with entropy above threshold
48
+ // 4.5 → 0.50, 5.0 → 0.65, 5.5 → 0.80, 6.0 → 0.95
49
+ const confidence = Math.min(0.95, 0.50 + (entropy - ENTROPY_THRESHOLD) * 0.30);
50
+ return { entropy, confidence };
51
+ }
52
+ /**
53
+ * Extract candidate high-entropy tokens from content.
54
+ * Looks for long contiguous alphanumeric+special strings
55
+ * that could be secrets.
56
+ */
57
+ export function extractHighEntropyTokens(content) {
58
+ // Match long strings of alphanumeric + common secret chars
59
+ const tokenRegex = /[A-Za-z0-9\-_./+=]{20,}/g;
60
+ const results = [];
61
+ const seen = new Set();
62
+ let match;
63
+ while ((match = tokenRegex.exec(content)) !== null) {
64
+ const token = match[0];
65
+ if (seen.has(token))
66
+ continue;
67
+ seen.add(token);
68
+ // Skip common false positives
69
+ if (isLikelyFalsePositive(token))
70
+ continue;
71
+ const result = checkHighEntropy(token);
72
+ if (result) {
73
+ results.push({
74
+ token,
75
+ position: match.index,
76
+ entropy: result.entropy,
77
+ confidence: result.confidence,
78
+ });
79
+ }
80
+ }
81
+ return results;
82
+ }
83
+ /**
84
+ * Heuristic filter to reduce false positives from entropy detection.
85
+ */
86
+ function isLikelyFalsePositive(token) {
87
+ // Pure lowercase with dashes — likely a slug or CSS class
88
+ if (/^[a-z\-]+$/.test(token))
89
+ return true;
90
+ // Looks like a file path
91
+ if (token.includes('/') && !token.includes('//') && /\.[a-z]{2,4}$/i.test(token))
92
+ return true;
93
+ // Repeated character sequences (aaaaaaa...)
94
+ if (/^(.)\1{10,}$/.test(token))
95
+ return true;
96
+ // Common base64 padding pattern (just padding)
97
+ if (/^=+$/.test(token) || /^[A-Za-z0-9+/]*={3,}$/.test(token))
98
+ return true;
99
+ // Long runs of a single character class with low variety
100
+ const uniqueChars = new Set(token).size;
101
+ if (uniqueChars < 6 && token.length > 20)
102
+ return true;
103
+ return false;
104
+ }
105
+ //# sourceMappingURL=entropy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entropy.js","sourceRoot":"","sources":["../../../src/defence/credential-leak/entropy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC;QACtB,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,CAAC,MAAM,GAAG,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,OAAO,GAAG,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAE7C,iDAAiD;IACjD,iDAAiD;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,GAAG,iBAAiB,CAAC,GAAG,IAAI,CAAC,CAAC;IAE/E,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAe;IAEf,2DAA2D;IAC3D,MAAM,UAAU,GAAG,0BAA0B,CAAC;IAC9C,MAAM,OAAO,GAAoF,EAAE,CAAC;IACpG,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEhB,8BAA8B;QAC9B,IAAI,qBAAqB,CAAC,KAAK,CAAC;YAAE,SAAS;QAE3C,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK;gBACL,QAAQ,EAAE,KAAK,CAAC,KAAK;gBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,KAAa;IAC1C,0DAA0D;IAC1D,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,yBAAyB;IACzB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9F,4CAA4C;IAC5C,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE5C,+CAA+C;IAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3E,yDAAyD;IACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;IACxC,IAAI,WAAW,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IAEtD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Credential Leak Detection — Layer 6
3
+ *
4
+ * Detects credentials, secrets, and sensitive tokens accidentally
5
+ * persisted in AI agent memory writes. Supports known API key formats,
6
+ * generic secrets, private keys, connection strings, environment
7
+ * variable patterns, and high-entropy string heuristics.
8
+ */
9
+ import { type CredentialPattern, type CredentialType, type CredentialSeverity } from './patterns.js';
10
+ export interface CredentialFinding {
11
+ type: CredentialType;
12
+ provider?: string;
13
+ confidence: number;
14
+ severity: CredentialSeverity;
15
+ /** Redacted version showing first/last 4 chars */
16
+ match: string;
17
+ /** Char offset in content */
18
+ position: number;
19
+ action: 'blocked' | 'warned' | 'logged';
20
+ }
21
+ export interface CredentialScanResult {
22
+ leaked: boolean;
23
+ findings: CredentialFinding[];
24
+ redactedContent?: string;
25
+ }
26
+ export interface CredentialDetectionConfig {
27
+ enabled: boolean;
28
+ blockOnCritical: boolean;
29
+ blockOnHigh: boolean;
30
+ warnOnMedium: boolean;
31
+ customPatterns: CredentialPattern[];
32
+ allowlist: string[];
33
+ }
34
+ export declare const DEFAULT_CREDENTIAL_CONFIG: CredentialDetectionConfig;
35
+ /**
36
+ * Scan content for credential leaks.
37
+ *
38
+ * Checks known API key formats, generic secrets, private keys,
39
+ * connection strings, env variable patterns, and high-entropy strings.
40
+ *
41
+ * @param content - The text content to scan
42
+ * @param config - Optional credential detection configuration
43
+ * @returns Scan result with findings and optional redacted content
44
+ */
45
+ export declare function scanForCredentials(content: string, config?: Partial<CredentialDetectionConfig>): CredentialScanResult;
46
+ /**
47
+ * Replace all detected secrets in content with [REDACTED-{type}] placeholders.
48
+ * Useful for agents that want to store memory but strip the secrets.
49
+ */
50
+ export declare function redactCredentials(content: string, config?: Partial<CredentialDetectionConfig>): string;
51
+ export type { CredentialPattern, CredentialType, CredentialSeverity } from './patterns.js';
52
+ export { shannonEntropy, checkHighEntropy } from './entropy.js';
53
+ export { ALL_CREDENTIAL_PATTERNS } from './patterns.js';
54
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/defence/credential-leak/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAKvB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,eAAO,MAAM,yBAAyB,EAAE,yBAOvC,CAAC;AAuCF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAC1C,oBAAoB,CAmGtB;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAC1C,MAAM,CAGR;AAmBD,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Credential Leak Detection — Layer 6
3
+ *
4
+ * Detects credentials, secrets, and sensitive tokens accidentally
5
+ * persisted in AI agent memory writes. Supports known API key formats,
6
+ * generic secrets, private keys, connection strings, environment
7
+ * variable patterns, and high-entropy string heuristics.
8
+ */
9
+ import { ALL_CREDENTIAL_PATTERNS, } from './patterns.js';
10
+ import { extractHighEntropyTokens } from './entropy.js';
11
+ export const DEFAULT_CREDENTIAL_CONFIG = {
12
+ enabled: true,
13
+ blockOnCritical: true,
14
+ blockOnHigh: true,
15
+ warnOnMedium: true,
16
+ customPatterns: [],
17
+ allowlist: [],
18
+ };
19
+ // ── Redaction ──
20
+ /**
21
+ * Redact a matched secret, showing first and last 4 chars.
22
+ * Very short matches get fully redacted.
23
+ */
24
+ function redactMatch(value, type) {
25
+ if (value.length <= 12)
26
+ return `[REDACTED-${type}]`;
27
+ return `${value.slice(0, 4)}...${value.slice(-4)}`;
28
+ }
29
+ /**
30
+ * Determine action based on severity and config.
31
+ */
32
+ function actionForSeverity(severity, config) {
33
+ if (severity === 'critical' && config.blockOnCritical)
34
+ return 'blocked';
35
+ if (severity === 'high' && config.blockOnHigh)
36
+ return 'blocked';
37
+ if (severity === 'medium' && config.warnOnMedium)
38
+ return 'warned';
39
+ return 'logged';
40
+ }
41
+ /**
42
+ * Check if a match is in the allowlist.
43
+ * Allowlist entries can be literal prefixes or glob-like patterns.
44
+ */
45
+ function isAllowlisted(value, allowlist) {
46
+ for (const entry of allowlist) {
47
+ if (value.startsWith(entry) || value === entry)
48
+ return true;
49
+ }
50
+ return false;
51
+ }
52
+ // ── Scanner ──
53
+ /**
54
+ * Scan content for credential leaks.
55
+ *
56
+ * Checks known API key formats, generic secrets, private keys,
57
+ * connection strings, env variable patterns, and high-entropy strings.
58
+ *
59
+ * @param content - The text content to scan
60
+ * @param config - Optional credential detection configuration
61
+ * @returns Scan result with findings and optional redacted content
62
+ */
63
+ export function scanForCredentials(content, config) {
64
+ const cfg = { ...DEFAULT_CREDENTIAL_CONFIG, ...config };
65
+ if (!cfg.enabled || !content || content.length === 0) {
66
+ return { leaked: false, findings: [] };
67
+ }
68
+ const findings = [];
69
+ const matchedRanges = [];
70
+ const patterns = [...ALL_CREDENTIAL_PATTERNS, ...cfg.customPatterns];
71
+ // Run all pattern matchers
72
+ for (const pattern of patterns) {
73
+ // Reset regex lastIndex for each scan
74
+ const regex = new RegExp(pattern.regex.source, pattern.regex.flags);
75
+ let match;
76
+ while ((match = regex.exec(content)) !== null) {
77
+ const fullMatch = match[0];
78
+ // For patterns with capture groups, use the group; otherwise the full match
79
+ const secretValue = match[1] ?? fullMatch;
80
+ // Skip if below minimum length
81
+ if (pattern.minLength && secretValue.length < pattern.minLength)
82
+ continue;
83
+ // Skip allowlisted values
84
+ if (isAllowlisted(secretValue, cfg.allowlist))
85
+ continue;
86
+ // Skip if this range is already covered by a higher-priority pattern
87
+ const start = match.index;
88
+ const end = start + fullMatch.length;
89
+ if (matchedRanges.some(r => start >= r.start && end <= r.end))
90
+ continue;
91
+ const action = actionForSeverity(pattern.severity, cfg);
92
+ const redacted = redactMatch(secretValue, pattern.type);
93
+ findings.push({
94
+ type: pattern.type,
95
+ provider: pattern.provider,
96
+ confidence: pattern.confidence,
97
+ severity: pattern.severity,
98
+ match: redacted,
99
+ position: start,
100
+ action,
101
+ });
102
+ const replacement = `[REDACTED-${pattern.type}${pattern.provider ? `-${pattern.provider}` : ''}]`;
103
+ matchedRanges.push({ start, end, replacement });
104
+ }
105
+ }
106
+ // Run entropy-based detection for anything not already caught
107
+ const entropyTokens = extractHighEntropyTokens(content);
108
+ for (const token of entropyTokens) {
109
+ const start = token.position;
110
+ const end = start + token.token.length;
111
+ // Skip if already caught by pattern matching
112
+ if (matchedRanges.some(r => (start >= r.start && start < r.end) ||
113
+ (end > r.start && end <= r.end)))
114
+ continue;
115
+ // Skip allowlisted
116
+ if (isAllowlisted(token.token, cfg.allowlist))
117
+ continue;
118
+ const severity = token.confidence >= 0.8 ? 'medium' : 'low';
119
+ const action = actionForSeverity(severity, cfg);
120
+ findings.push({
121
+ type: 'high_entropy',
122
+ confidence: token.confidence,
123
+ severity,
124
+ match: redactMatch(token.token, 'high_entropy'),
125
+ position: start,
126
+ action,
127
+ });
128
+ matchedRanges.push({ start, end, replacement: '[REDACTED-high_entropy]' });
129
+ }
130
+ // Sort findings by position
131
+ findings.sort((a, b) => a.position - b.position);
132
+ const leaked = findings.length > 0;
133
+ const hasBlocked = findings.some(f => f.action === 'blocked');
134
+ // Build redacted content if any findings
135
+ let redactedContent;
136
+ if (leaked) {
137
+ redactedContent = buildRedactedContent(content, matchedRanges);
138
+ }
139
+ return {
140
+ leaked,
141
+ findings,
142
+ redactedContent: hasBlocked ? redactedContent : redactedContent,
143
+ };
144
+ }
145
+ // ── Redaction Helper ──
146
+ /**
147
+ * Replace all detected secrets in content with [REDACTED-{type}] placeholders.
148
+ * Useful for agents that want to store memory but strip the secrets.
149
+ */
150
+ export function redactCredentials(content, config) {
151
+ const result = scanForCredentials(content, config);
152
+ return result.redactedContent ?? content;
153
+ }
154
+ /**
155
+ * Build redacted content by replacing matched ranges.
156
+ */
157
+ function buildRedactedContent(content, ranges) {
158
+ // Sort by start position descending to replace from end to start
159
+ const sorted = [...ranges].sort((a, b) => b.start - a.start);
160
+ let result = content;
161
+ for (const range of sorted) {
162
+ result = result.slice(0, range.start) + range.replacement + result.slice(range.end);
163
+ }
164
+ return result;
165
+ }
166
+ export { shannonEntropy, checkHighEntropy } from './entropy.js';
167
+ export { ALL_CREDENTIAL_PATTERNS } from './patterns.js';
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/defence/credential-leak/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Credential Leak Detection — Pattern Definitions
3
+ *
4
+ * Known API key formats, secret patterns, and heuristic matchers
5
+ * for detecting accidentally persisted credentials in AI agent memory.
6
+ */
7
+ export interface CredentialPattern {
8
+ name: string;
9
+ type: CredentialType;
10
+ provider?: string;
11
+ regex: RegExp;
12
+ severity: CredentialSeverity;
13
+ /** Base confidence when pattern matches (can be boosted by entropy) */
14
+ confidence: number;
15
+ /** Minimum match length to avoid false positives */
16
+ minLength?: number;
17
+ }
18
+ export type CredentialType = 'api_key' | 'jwt' | 'private_key' | 'connection_string' | 'env_secret' | 'high_entropy';
19
+ export type CredentialSeverity = 'critical' | 'high' | 'medium' | 'low';
20
+ export declare const API_KEY_PATTERNS: CredentialPattern[];
21
+ export declare const GENERIC_SECRET_PATTERNS: CredentialPattern[];
22
+ export declare const PRIVATE_KEY_PATTERNS: CredentialPattern[];
23
+ export declare const CONNECTION_STRING_PATTERNS: CredentialPattern[];
24
+ export declare const ENV_SECRET_PATTERNS: CredentialPattern[];
25
+ export declare const ALL_CREDENTIAL_PATTERNS: CredentialPattern[];
26
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../../src/defence/credential-leak/patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,KAAK,GACL,aAAa,GACb,mBAAmB,GACnB,YAAY,GACZ,cAAc,CAAC;AAEnB,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAIxE,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,EAgK/C,CAAC;AAIF,eAAO,MAAM,uBAAuB,EAAE,iBAAiB,EAyBtD,CAAC;AAIF,eAAO,MAAM,oBAAoB,EAAE,iBAAiB,EAgCnD,CAAC;AAIF,eAAO,MAAM,0BAA0B,EAAE,iBAAiB,EAiCzD,CAAC;AAIF,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,EA6BlD,CAAC;AAIF,eAAO,MAAM,uBAAuB,EAAE,iBAAiB,EAMtD,CAAC"}
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Credential Leak Detection — Pattern Definitions
3
+ *
4
+ * Known API key formats, secret patterns, and heuristic matchers
5
+ * for detecting accidentally persisted credentials in AI agent memory.
6
+ */
7
+ // ── Known API Key Patterns ──
8
+ export const API_KEY_PATTERNS = [
9
+ // OpenAI
10
+ {
11
+ name: 'OpenAI API Key',
12
+ type: 'api_key',
13
+ provider: 'openai',
14
+ regex: /sk-[A-Za-z0-9]{20,}/g,
15
+ severity: 'critical',
16
+ confidence: 0.95,
17
+ minLength: 24,
18
+ },
19
+ // Anthropic
20
+ {
21
+ name: 'Anthropic API Key',
22
+ type: 'api_key',
23
+ provider: 'anthropic',
24
+ regex: /sk-ant-[A-Za-z0-9\-_]{20,}/g,
25
+ severity: 'critical',
26
+ confidence: 0.98,
27
+ },
28
+ // AWS Access Key
29
+ {
30
+ name: 'AWS Access Key ID',
31
+ type: 'api_key',
32
+ provider: 'aws',
33
+ regex: /AKIA[0-9A-Z]{16}/g,
34
+ severity: 'critical',
35
+ confidence: 0.97,
36
+ },
37
+ // AWS Secret Key (typically base64-like, 40 chars)
38
+ {
39
+ name: 'AWS Secret Access Key',
40
+ type: 'api_key',
41
+ provider: 'aws',
42
+ regex: /(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY|SecretAccessKey)\s*[=:]\s*["']?([A-Za-z0-9/+=]{40})["']?/g,
43
+ severity: 'critical',
44
+ confidence: 0.95,
45
+ },
46
+ // GitHub tokens
47
+ {
48
+ name: 'GitHub Personal Access Token',
49
+ type: 'api_key',
50
+ provider: 'github',
51
+ regex: /ghp_[A-Za-z0-9]{36,}/g,
52
+ severity: 'critical',
53
+ confidence: 0.98,
54
+ },
55
+ {
56
+ name: 'GitHub OAuth Token',
57
+ type: 'api_key',
58
+ provider: 'github',
59
+ regex: /gho_[A-Za-z0-9]{36,}/g,
60
+ severity: 'critical',
61
+ confidence: 0.98,
62
+ },
63
+ {
64
+ name: 'GitHub Fine-grained PAT',
65
+ type: 'api_key',
66
+ provider: 'github',
67
+ regex: /github_pat_[A-Za-z0-9_]{22,}/g,
68
+ severity: 'critical',
69
+ confidence: 0.98,
70
+ },
71
+ // Stripe
72
+ {
73
+ name: 'Stripe Live Key',
74
+ type: 'api_key',
75
+ provider: 'stripe',
76
+ regex: /sk_live_[A-Za-z0-9]{24,}/g,
77
+ severity: 'critical',
78
+ confidence: 0.98,
79
+ },
80
+ {
81
+ name: 'Stripe Test Key',
82
+ type: 'api_key',
83
+ provider: 'stripe',
84
+ regex: /sk_test_[A-Za-z0-9]{24,}/g,
85
+ severity: 'medium',
86
+ confidence: 0.95,
87
+ },
88
+ {
89
+ name: 'Stripe Publishable Key',
90
+ type: 'api_key',
91
+ provider: 'stripe',
92
+ regex: /pk_(?:live|test)_[A-Za-z0-9]{24,}/g,
93
+ severity: 'medium',
94
+ confidence: 0.90,
95
+ },
96
+ // Twilio
97
+ {
98
+ name: 'Twilio API Key',
99
+ type: 'api_key',
100
+ provider: 'twilio',
101
+ regex: /SK[a-f0-9]{32}/g,
102
+ severity: 'critical',
103
+ confidence: 0.90,
104
+ },
105
+ // SendGrid
106
+ {
107
+ name: 'SendGrid API Key',
108
+ type: 'api_key',
109
+ provider: 'sendgrid',
110
+ regex: /SG\.[A-Za-z0-9\-_]{22,}\.[A-Za-z0-9\-_]{22,}/g,
111
+ severity: 'critical',
112
+ confidence: 0.97,
113
+ },
114
+ // Slack
115
+ {
116
+ name: 'Slack Bot Token',
117
+ type: 'api_key',
118
+ provider: 'slack',
119
+ regex: /xoxb-[0-9]{10,}-[0-9A-Za-z\-]{20,}/g,
120
+ severity: 'critical',
121
+ confidence: 0.96,
122
+ },
123
+ {
124
+ name: 'Slack Webhook URL',
125
+ type: 'api_key',
126
+ provider: 'slack',
127
+ regex: /https:\/\/hooks\.slack\.com\/services\/T[A-Z0-9]{8,}\/B[A-Z0-9]{8,}\/[A-Za-z0-9]{20,}/g,
128
+ severity: 'high',
129
+ confidence: 0.95,
130
+ },
131
+ // Google
132
+ {
133
+ name: 'Google API Key',
134
+ type: 'api_key',
135
+ provider: 'google',
136
+ regex: /AIza[A-Za-z0-9\-_]{35}/g,
137
+ severity: 'critical',
138
+ confidence: 0.95,
139
+ },
140
+ // Mailgun
141
+ {
142
+ name: 'Mailgun API Key',
143
+ type: 'api_key',
144
+ provider: 'mailgun',
145
+ regex: /key-[A-Za-z0-9]{32}/g,
146
+ severity: 'critical',
147
+ confidence: 0.85,
148
+ },
149
+ // npm
150
+ {
151
+ name: 'npm Access Token',
152
+ type: 'api_key',
153
+ provider: 'npm',
154
+ regex: /npm_[A-Za-z0-9]{36,}/g,
155
+ severity: 'critical',
156
+ confidence: 0.97,
157
+ },
158
+ // Heroku
159
+ {
160
+ name: 'Heroku API Key',
161
+ type: 'api_key',
162
+ provider: 'heroku',
163
+ regex: /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/g,
164
+ severity: 'low',
165
+ confidence: 0.30,
166
+ // UUIDs are very common — only flagged as low confidence
167
+ },
168
+ ];
169
+ // ── Generic Secret Patterns ──
170
+ export const GENERIC_SECRET_PATTERNS = [
171
+ // JWT tokens
172
+ {
173
+ name: 'JWT Token',
174
+ type: 'jwt',
175
+ regex: /eyJ[A-Za-z0-9\-_]+\.eyJ[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+/g,
176
+ severity: 'high',
177
+ confidence: 0.92,
178
+ },
179
+ // Bearer tokens in headers
180
+ {
181
+ name: 'Bearer Token',
182
+ type: 'api_key',
183
+ regex: /(?:Authorization|authorization)\s*:\s*Bearer\s+([A-Za-z0-9\-_./+=]{20,})/g,
184
+ severity: 'high',
185
+ confidence: 0.90,
186
+ },
187
+ // Basic auth headers
188
+ {
189
+ name: 'Basic Auth Header',
190
+ type: 'api_key',
191
+ regex: /(?:Authorization|authorization)\s*:\s*Basic\s+([A-Za-z0-9+/=]{8,})/g,
192
+ severity: 'high',
193
+ confidence: 0.88,
194
+ },
195
+ ];
196
+ // ── Private Key Patterns ──
197
+ export const PRIVATE_KEY_PATTERNS = [
198
+ {
199
+ name: 'RSA Private Key',
200
+ type: 'private_key',
201
+ provider: 'rsa',
202
+ regex: /-----BEGIN\s+RSA\s+PRIVATE\s+KEY-----[\s\S]*?-----END\s+RSA\s+PRIVATE\s+KEY-----/g,
203
+ severity: 'critical',
204
+ confidence: 0.99,
205
+ },
206
+ {
207
+ name: 'EC Private Key',
208
+ type: 'private_key',
209
+ provider: 'ec',
210
+ regex: /-----BEGIN\s+EC\s+PRIVATE\s+KEY-----[\s\S]*?-----END\s+EC\s+PRIVATE\s+KEY-----/g,
211
+ severity: 'critical',
212
+ confidence: 0.99,
213
+ },
214
+ {
215
+ name: 'Generic Private Key',
216
+ type: 'private_key',
217
+ regex: /-----BEGIN\s+(?:ENCRYPTED\s+)?PRIVATE\s+KEY-----[\s\S]*?-----END\s+(?:ENCRYPTED\s+)?PRIVATE\s+KEY-----/g,
218
+ severity: 'critical',
219
+ confidence: 0.99,
220
+ },
221
+ {
222
+ name: 'SSH Private Key',
223
+ type: 'private_key',
224
+ provider: 'ssh',
225
+ regex: /-----BEGIN\s+OPENSSH\s+PRIVATE\s+KEY-----[\s\S]*?-----END\s+OPENSSH\s+PRIVATE\s+KEY-----/g,
226
+ severity: 'critical',
227
+ confidence: 0.99,
228
+ },
229
+ ];
230
+ // ── Connection String Patterns ──
231
+ export const CONNECTION_STRING_PATTERNS = [
232
+ {
233
+ name: 'PostgreSQL Connection String',
234
+ type: 'connection_string',
235
+ provider: 'postgres',
236
+ regex: /postgres(?:ql)?:\/\/[^\s"'`]+:[^\s"'`@]+@[^\s"'`]+/g,
237
+ severity: 'critical',
238
+ confidence: 0.95,
239
+ },
240
+ {
241
+ name: 'MySQL Connection String',
242
+ type: 'connection_string',
243
+ provider: 'mysql',
244
+ regex: /mysql:\/\/[^\s"'`]+:[^\s"'`@]+@[^\s"'`]+/g,
245
+ severity: 'critical',
246
+ confidence: 0.95,
247
+ },
248
+ {
249
+ name: 'MongoDB Connection String',
250
+ type: 'connection_string',
251
+ provider: 'mongodb',
252
+ regex: /mongodb(?:\+srv)?:\/\/[^\s"'`]+:[^\s"'`@]+@[^\s"'`]+/g,
253
+ severity: 'critical',
254
+ confidence: 0.95,
255
+ },
256
+ {
257
+ name: 'Redis Connection String',
258
+ type: 'connection_string',
259
+ provider: 'redis',
260
+ regex: /redis(?:s)?:\/\/[^\s"'`]*:[^\s"'`@]+@[^\s"'`]+/g,
261
+ severity: 'critical',
262
+ confidence: 0.93,
263
+ },
264
+ ];
265
+ // ── Environment Variable Patterns ──
266
+ export const ENV_SECRET_PATTERNS = [
267
+ {
268
+ name: 'Password Assignment',
269
+ type: 'env_secret',
270
+ regex: /(?:PASSWORD|PASSWD|DB_PASS|DB_PASSWORD|ADMIN_PASSWORD|ROOT_PASSWORD)\s*[=:]\s*["']?([^\s"']{8,})["']?/gi,
271
+ severity: 'high',
272
+ confidence: 0.85,
273
+ },
274
+ {
275
+ name: 'Secret Assignment',
276
+ type: 'env_secret',
277
+ regex: /(?:SECRET|SECRET_KEY|APP_SECRET|JWT_SECRET|SESSION_SECRET|ENCRYPTION_KEY)\s*[=:]\s*["']?([^\s"']{8,})["']?/gi,
278
+ severity: 'high',
279
+ confidence: 0.85,
280
+ },
281
+ {
282
+ name: 'Token Assignment',
283
+ type: 'env_secret',
284
+ regex: /(?:TOKEN|ACCESS_TOKEN|REFRESH_TOKEN|AUTH_TOKEN|API_TOKEN|BEARER_TOKEN)\s*[=:]\s*["']?([^\s"']{8,})["']?/gi,
285
+ severity: 'high',
286
+ confidence: 0.82,
287
+ },
288
+ {
289
+ name: 'API Key Assignment',
290
+ type: 'env_secret',
291
+ regex: /(?:API_KEY|APIKEY|API_SECRET)\s*[=:]\s*["']?([^\s"']{8,})["']?/gi,
292
+ severity: 'high',
293
+ confidence: 0.82,
294
+ },
295
+ ];
296
+ // ── All Patterns Combined (in priority order) ──
297
+ export const ALL_CREDENTIAL_PATTERNS = [
298
+ ...PRIVATE_KEY_PATTERNS,
299
+ ...API_KEY_PATTERNS,
300
+ ...CONNECTION_STRING_PATTERNS,
301
+ ...GENERIC_SECRET_PATTERNS,
302
+ ...ENV_SECRET_PATTERNS,
303
+ ];
304
+ //# sourceMappingURL=patterns.js.map