@sandrobuilds/tracerney 0.9.22 → 0.9.24
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/README.md +41 -0
- package/dist/application/ShieldApplicationService.d.ts +8 -0
- package/dist/application/ShieldApplicationService.d.ts.map +1 -1
- package/dist/application/ShieldApplicationService.js +48 -2
- package/dist/application/ShieldApplicationService.js.map +1 -1
- package/dist/domain/events/SecurityEventType.d.ts +5 -1
- package/dist/domain/events/SecurityEventType.d.ts.map +1 -1
- package/dist/domain/events/SecurityEventType.js +4 -0
- package/dist/domain/events/SecurityEventType.js.map +1 -1
- package/dist/domain/pii/DeterministicFilter.d.ts +79 -0
- package/dist/domain/pii/DeterministicFilter.d.ts.map +1 -0
- package/dist/domain/pii/DeterministicFilter.js +151 -0
- package/dist/domain/pii/DeterministicFilter.js.map +1 -0
- package/dist/domain/pii/PIIPattern.d.ts +41 -0
- package/dist/domain/pii/PIIPattern.d.ts.map +1 -0
- package/dist/domain/pii/PIIPattern.js +253 -0
- package/dist/domain/pii/PIIPattern.js.map +1 -0
- package/dist/domain/pii/index.d.ts +9 -0
- package/dist/domain/pii/index.d.ts.map +1 -0
- package/dist/domain/pii/index.js +7 -0
- package/dist/domain/pii/index.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -184,6 +184,47 @@ The verify-prompt endpoint returns structured responses. Success (HTTP 200) incl
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
+
## Outbound Response Filtering: `validate()`
|
|
188
|
+
|
|
189
|
+
Layer 1 also runs on every LLM **response** before it reaches your user — scanning for PII, secrets, and active exfiltration attempts embedded in agent output.
|
|
190
|
+
|
|
191
|
+
The SDK is a high-precision sensor. It never decides for you. It labels every finding and hands you the keys:
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
const trace = tracerney.validate(agentOutput);
|
|
195
|
+
|
|
196
|
+
if (trace.isSuspicious) {
|
|
197
|
+
console.log(`[${trace.label}]: ${trace.reason}`);
|
|
198
|
+
|
|
199
|
+
// Option A: Hard block
|
|
200
|
+
if (trace.label === 'SUSPICIOUS_EGRESS') {
|
|
201
|
+
throw new Error('Security Policy Violation');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Option B: Surgical scrub
|
|
205
|
+
return trace.redactedContent;
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
trace.isSuspicious // boolean — true if any pattern matched
|
|
211
|
+
trace.label // see manifest below
|
|
212
|
+
trace.reason // "Detected 2 finding(s): Email Address, AWS Access Key ID"
|
|
213
|
+
trace.redactedContent // pre-scrubbed version — use it or throw, your call
|
|
214
|
+
trace.findings // full per-pattern breakdown for logging/telemetry
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### The Suspicious Manifest
|
|
218
|
+
|
|
219
|
+
| Trigger | Label | Recommended action |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| Email / Phone | `SUSPICIOUS_PII` | Usually Redact |
|
|
222
|
+
| API Keys / SSH / CC / SSN | `SUSPICIOUS_SECRET` | Usually Block |
|
|
223
|
+
| External URL smuggling | `SUSPICIOUS_EGRESS` | Always Block |
|
|
224
|
+
| Zero-width / BiDi / Base64 | `SUSPICIOUS_ENCODING` | Audit / Block |
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
187
228
|
## Pricing & Usage
|
|
188
229
|
|
|
189
230
|
- **Free Tier:** 50 scans/month with Layer 1 pattern detection
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Core orchestrator: wires domain services + infrastructure adapters
|
|
4
4
|
* Fixes all 5 integration gaps from the original design
|
|
5
5
|
*/
|
|
6
|
+
import { type SuspiciousTrace } from "../domain/pii/DeterministicFilter";
|
|
6
7
|
import { type ToolPolicy } from "../domain/guard/ToolPolicy";
|
|
7
8
|
import { ILLMProvider, type LLMResponse } from "./ports/ILLMProvider";
|
|
8
9
|
import { ISentinel } from "./ports/ISentinel";
|
|
@@ -30,6 +31,7 @@ export interface ScanResult {
|
|
|
30
31
|
severity?: string;
|
|
31
32
|
blocked: boolean;
|
|
32
33
|
}
|
|
34
|
+
export type { SuspiciousTrace };
|
|
33
35
|
export interface ServiceStatus {
|
|
34
36
|
patternMatcher: {
|
|
35
37
|
ready: boolean;
|
|
@@ -46,6 +48,7 @@ export interface ServiceStatus {
|
|
|
46
48
|
export declare class ShieldApplicationService {
|
|
47
49
|
private readonly config;
|
|
48
50
|
private patternMatcher;
|
|
51
|
+
private readonly deterministicFilter;
|
|
49
52
|
private toolGuard;
|
|
50
53
|
private telemetrySink?;
|
|
51
54
|
private llmProvider?;
|
|
@@ -76,6 +79,11 @@ export declare class ShieldApplicationService {
|
|
|
76
79
|
* - Jitter: Add random delay to obfuscate timing
|
|
77
80
|
*/
|
|
78
81
|
scanPrompt(prompt: string, requestId?: string): Promise<ScanResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Layer 1: Scan any string for suspicious content.
|
|
84
|
+
* Returns a SuspiciousTrace — the SDK never decides for you.
|
|
85
|
+
*/
|
|
86
|
+
validate(text: string): SuspiciousTrace;
|
|
79
87
|
/**
|
|
80
88
|
* Update tool policy at runtime
|
|
81
89
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldApplicationService.d.ts","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"ShieldApplicationService.d.ts","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAuB,KAAK,eAAe,EAAsB,MAAM,mCAAmC,CAAC;AAElH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAO/E,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAGhE,OAAO,EAAE,iBAAiB,EAAyB,MAAM,6BAA6B,CAAC;AAIvF,MAAM,WAAW,8BAA8B;IAC7C,iBAAiB,EAAE,kBAAkB,CAAC;IACtC,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE;QACd,KAAK,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,SAAS,EAAE;QACT,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;KACjC,CAAC;IACF,SAAS,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,qBAAa,wBAAwB;IAUvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAC1D,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,CAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEP,MAAM,EAAE,8BAA8B;IAkBnE;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;;;;;OAMG;IACG,IAAI,CAAC,CAAC,SAAS,WAAW,EAC9B,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC;IA6Gb;;;;;;;;;OASG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmFzE;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAIvC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI;IAK/C;;OAEG;IACH,SAAS,IAAI,aAAa;IAgB1B;;OAEG;IACH,OAAO,CAAC,MAAM;IAMd;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAG1B"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Fixes all 5 integration gaps from the original design
|
|
5
5
|
*/
|
|
6
6
|
import { PatternMatcher } from '../domain/detection/PatternMatcher.js';
|
|
7
|
+
import { DeterministicFilter } from '../domain/pii/DeterministicFilter.js';
|
|
7
8
|
import { ToolGuard } from '../domain/guard/ToolGuard.js';
|
|
8
9
|
import { createToolPolicy } from '../domain/guard/ToolPolicy.js';
|
|
9
10
|
import { createSecurityEvent, SecurityEventType, ThreatSeverity, } from '../domain/events/index.js';
|
|
@@ -20,6 +21,8 @@ export class ShieldApplicationService {
|
|
|
20
21
|
this.sentinel = config.sentinel; // Layer 2
|
|
21
22
|
// this.shadowLogSink = config.shadowLogSink; // Disabled for now
|
|
22
23
|
this.sdkVersion = config.sdkVersion ?? "0.2.0";
|
|
24
|
+
// Layer 1: deterministic outbound filter (singleton, stateless)
|
|
25
|
+
this.deterministicFilter = new DeterministicFilter();
|
|
23
26
|
// Initialize patterns synchronously (bundled patterns always available)
|
|
24
27
|
this.patternMatcher = new PatternMatcher(BUNDLED_PATTERNS);
|
|
25
28
|
// Load remote patterns in background if configured (zero-day updates)
|
|
@@ -63,9 +66,45 @@ export class ShieldApplicationService {
|
|
|
63
66
|
// Layer 1 just marks suspicious=true, doesn't block
|
|
64
67
|
}
|
|
65
68
|
// Execute the LLM call
|
|
66
|
-
const
|
|
67
|
-
//
|
|
69
|
+
const rawResponse = await llmCall();
|
|
70
|
+
// ── Layer 1 (Outbound): Deterministic Filter ─────────────────────────
|
|
71
|
+
// Synchronous regex pass — <5ms, runs before the caller ever sees the text.
|
|
72
|
+
//
|
|
73
|
+
// The filter is a SENSOR, not a policy enforcer.
|
|
74
|
+
// It labels every finding with a SuspiciousLabel and pre-computes redactedContent.
|
|
75
|
+
// ShieldApplicationService acts on the label:
|
|
76
|
+
//
|
|
77
|
+
// SUSPICIOUS_EGRESS → throw (active exfiltration, caller gets nothing)
|
|
78
|
+
// SUSPICIOUS_SECRET → emit PII_LEAK alert, return redacted response
|
|
79
|
+
// SUSPICIOUS_ENCODING → emit PII_LEAK alert, return redacted response
|
|
80
|
+
// SUSPICIOUS_PII → return redacted response silently
|
|
81
|
+
const { response, outcome: filterOutcome } = this.deterministicFilter.filterResponse(rawResponse);
|
|
68
82
|
const latencyMs = Date.now() - startTime;
|
|
83
|
+
const trace = filterOutcome.trace;
|
|
84
|
+
if (trace.isSuspicious && trace.label) {
|
|
85
|
+
if (trace.label === "SUSPICIOUS_EGRESS") {
|
|
86
|
+
// Active exfiltration — kill the process, caller gets nothing.
|
|
87
|
+
const event = createSecurityEvent(requestId, SecurityEventType.SUSPICIOUS_EGRESS, ThreatSeverity.CRITICAL, `Layer 1: ${trace.reason}`, {
|
|
88
|
+
patternName: trace.findings[0]?.patternName,
|
|
89
|
+
blockLatencyMs: latencyMs,
|
|
90
|
+
modelName: options?.modelName,
|
|
91
|
+
provider: options?.provider,
|
|
92
|
+
}, startTime);
|
|
93
|
+
this.report(event);
|
|
94
|
+
throw new ShieldBlockError("Tracerney Block: Suspicious Egress Detected", event);
|
|
95
|
+
}
|
|
96
|
+
if (trace.label === "SUSPICIOUS_SECRET" || trace.label === "SUSPICIOUS_ENCODING") {
|
|
97
|
+
// Accidental leak of high-value data — alert, but return the scrubbed response.
|
|
98
|
+
const event = createSecurityEvent(requestId, SecurityEventType.PII_LEAK, ThreatSeverity.HIGH, `Layer 1: ${trace.reason}`, {
|
|
99
|
+
patternName: trace.findings[0]?.patternName,
|
|
100
|
+
blockLatencyMs: latencyMs,
|
|
101
|
+
modelName: options?.modelName,
|
|
102
|
+
provider: options?.provider,
|
|
103
|
+
}, startTime);
|
|
104
|
+
this.report(event);
|
|
105
|
+
}
|
|
106
|
+
// SUSPICIOUS_PII (email/phone) → return scrubbed response silently, no event.
|
|
107
|
+
}
|
|
69
108
|
// Validate tool calls against policy
|
|
70
109
|
const toolCalls = response.choices?.[0]?.message?.tool_calls;
|
|
71
110
|
const violation = this.toolGuard.validate(toolCalls, requestId);
|
|
@@ -171,6 +210,13 @@ export class ShieldApplicationService {
|
|
|
171
210
|
await jitter();
|
|
172
211
|
}
|
|
173
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Layer 1: Scan any string for suspicious content.
|
|
215
|
+
* Returns a SuspiciousTrace — the SDK never decides for you.
|
|
216
|
+
*/
|
|
217
|
+
validate(text) {
|
|
218
|
+
return this.deterministicFilter.validate(text);
|
|
219
|
+
}
|
|
174
220
|
/**
|
|
175
221
|
* Update tool policy at runtime
|
|
176
222
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShieldApplicationService.js","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAiB,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAmB,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GAEf,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAC/E,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;
|
|
1
|
+
{"version":3,"file":"ShieldApplicationService.js","sourceRoot":"","sources":["../../src/application/ShieldApplicationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,11 @@ export declare enum SecurityEventType {
|
|
|
6
6
|
PROMPT_INJECTION = "PROMPT_INJECTION",
|
|
7
7
|
UNAUTHORIZED_TOOL = "UNAUTHORIZED_TOOL",
|
|
8
8
|
PATTERN_MATCH = "PATTERN_MATCH",
|
|
9
|
-
SCHEMA_VIOLATION = "SCHEMA_VIOLATION"
|
|
9
|
+
SCHEMA_VIOLATION = "SCHEMA_VIOLATION",
|
|
10
|
+
/** Layer 1: agent attempted to exfiltrate data to an unauthorized destination */
|
|
11
|
+
SUSPICIOUS_EGRESS = "SUSPICIOUS_EGRESS",
|
|
12
|
+
/** Layer 1: agent response contained PII/secrets that were redacted before delivery */
|
|
13
|
+
PII_LEAK = "PII_LEAK"
|
|
10
14
|
}
|
|
11
15
|
export type SecurityEventTypeString = keyof typeof SecurityEventType;
|
|
12
16
|
export declare function isSecurityEventType(value: unknown): value is SecurityEventType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityEventType.d.ts","sourceRoot":"","sources":["../../../src/domain/events/SecurityEventType.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,iBAAiB;IAC3B,gBAAgB,qBAAqB;IACrC,iBAAiB,sBAAsB;IACvC,aAAa,kBAAkB;IAC/B,gBAAgB,qBAAqB;
|
|
1
|
+
{"version":3,"file":"SecurityEventType.d.ts","sourceRoot":"","sources":["../../../src/domain/events/SecurityEventType.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,iBAAiB;IAC3B,gBAAgB,qBAAqB;IACrC,iBAAiB,sBAAsB;IACvC,aAAa,kBAAkB;IAC/B,gBAAgB,qBAAqB;IACrC,iFAAiF;IACjF,iBAAiB,sBAAsB;IACvC,uFAAuF;IACvF,QAAQ,aAAa;CACtB;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,iBAAiB,CAAC;AAErE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,iBAAiB,CAE9E"}
|
|
@@ -8,6 +8,10 @@ export var SecurityEventType;
|
|
|
8
8
|
SecurityEventType["UNAUTHORIZED_TOOL"] = "UNAUTHORIZED_TOOL";
|
|
9
9
|
SecurityEventType["PATTERN_MATCH"] = "PATTERN_MATCH";
|
|
10
10
|
SecurityEventType["SCHEMA_VIOLATION"] = "SCHEMA_VIOLATION";
|
|
11
|
+
/** Layer 1: agent attempted to exfiltrate data to an unauthorized destination */
|
|
12
|
+
SecurityEventType["SUSPICIOUS_EGRESS"] = "SUSPICIOUS_EGRESS";
|
|
13
|
+
/** Layer 1: agent response contained PII/secrets that were redacted before delivery */
|
|
14
|
+
SecurityEventType["PII_LEAK"] = "PII_LEAK";
|
|
11
15
|
})(SecurityEventType || (SecurityEventType = {}));
|
|
12
16
|
export function isSecurityEventType(value) {
|
|
13
17
|
return Object.values(SecurityEventType).includes(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SecurityEventType.js","sourceRoot":"","sources":["../../../src/domain/events/SecurityEventType.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"SecurityEventType.js","sourceRoot":"","sources":["../../../src/domain/events/SecurityEventType.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAN,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,0DAAqC,CAAA;IACrC,4DAAuC,CAAA;IACvC,oDAA+B,CAAA;IAC/B,0DAAqC,CAAA;IACrC,iFAAiF;IACjF,4DAAuC,CAAA;IACvC,uFAAuF;IACvF,0CAAqB,CAAA;AACvB,CAAC,EATW,iBAAiB,KAAjB,iBAAiB,QAS5B;AAID,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,KAA0B,CAAC,CAAC;AAC/E,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic Filter
|
|
3
|
+
* Domain service: Layer 1 outbound intelligent gatekeeper.
|
|
4
|
+
*
|
|
5
|
+
* Philosophy — The SDK is a HIGH-PRECISION SENSOR, not a policy enforcer.
|
|
6
|
+
*
|
|
7
|
+
* Every match is surfaced as a SuspiciousTrace. The developer owns the reaction:
|
|
8
|
+
*
|
|
9
|
+
* const trace = tracerney.validate(agentOutput);
|
|
10
|
+
*
|
|
11
|
+
* if (trace.isSuspicious) {
|
|
12
|
+
* console.log(`Alert: ${trace.reason}`);
|
|
13
|
+
*
|
|
14
|
+
* // Option A: Hard Block
|
|
15
|
+
* // throw new Error("Security Policy Violation");
|
|
16
|
+
*
|
|
17
|
+
* // Option B: Surgical Scrub
|
|
18
|
+
* // return trace.redactedContent;
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* See the "Suspicious Manifest" in PIIPattern.ts for the label-to-action guide.
|
|
22
|
+
*
|
|
23
|
+
* Pure synchronous — no I/O, no async. Target latency <5ms.
|
|
24
|
+
*/
|
|
25
|
+
import { type PIICategory, type PIIPattern, type SuspiciousLabel } from "./PIIPattern";
|
|
26
|
+
import type { LLMResponse } from "../../application/ports/ILLMProvider";
|
|
27
|
+
export type { SuspiciousLabel };
|
|
28
|
+
export interface PIIFinding {
|
|
29
|
+
readonly patternId: string;
|
|
30
|
+
readonly patternName: string;
|
|
31
|
+
readonly category: PIICategory;
|
|
32
|
+
/** Semantic label — use this for routing decisions */
|
|
33
|
+
readonly label: SuspiciousLabel;
|
|
34
|
+
/** How many times this pattern matched */
|
|
35
|
+
readonly count: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The result of a single validate() call.
|
|
39
|
+
*
|
|
40
|
+
* isSuspicious — true if any pattern fired; false means clean.
|
|
41
|
+
* label — highest-severity label across all findings (null when clean).
|
|
42
|
+
* reason — human-readable summary for logging, e.g. "Detected 2 finding(s): Email Address, AWS Access Key ID"
|
|
43
|
+
* redactedContent — pre-computed version of the input with all matches replaced.
|
|
44
|
+
* Present regardless of isSuspicious (equals original text when clean).
|
|
45
|
+
* Use it if you want surgical scrubbing. Throw if you want a hard block.
|
|
46
|
+
* findings — granular list for detailed logging or telemetry.
|
|
47
|
+
*/
|
|
48
|
+
export interface SuspiciousTrace {
|
|
49
|
+
readonly isSuspicious: boolean;
|
|
50
|
+
readonly label: SuspiciousLabel | null;
|
|
51
|
+
readonly reason: string;
|
|
52
|
+
readonly redactedContent: string;
|
|
53
|
+
readonly findings: readonly PIIFinding[];
|
|
54
|
+
}
|
|
55
|
+
/** @internal Used by ShieldApplicationService.wrap() */
|
|
56
|
+
export interface FilterOutcome {
|
|
57
|
+
readonly trace: SuspiciousTrace;
|
|
58
|
+
/** Response with redactedContent applied to all choice messages */
|
|
59
|
+
readonly redactedResponse?: unknown;
|
|
60
|
+
}
|
|
61
|
+
export declare class DeterministicFilter {
|
|
62
|
+
private readonly patterns;
|
|
63
|
+
constructor(patterns?: readonly PIIPattern[]);
|
|
64
|
+
/**
|
|
65
|
+
* Scan a plain string and return a SuspiciousTrace.
|
|
66
|
+
* Always returns — never throws. The caller decides what to do.
|
|
67
|
+
*/
|
|
68
|
+
validate(text: string): SuspiciousTrace;
|
|
69
|
+
/**
|
|
70
|
+
* Scan all text content in an LLMResponse.
|
|
71
|
+
* Returns a merged SuspiciousTrace (highest label across all choices)
|
|
72
|
+
* and a new response with redactedContent applied — never mutates the original.
|
|
73
|
+
*/
|
|
74
|
+
filterResponse<T extends LLMResponse>(response: T): {
|
|
75
|
+
response: T;
|
|
76
|
+
outcome: FilterOutcome;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=DeterministicFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeterministicFilter.d.ts","sourceRoot":"","sources":["../../../src/domain/pii/DeterministicFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,sCAAsC,CAAC;AAInF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;CAC1C;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAID,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;gBAErC,QAAQ,GAAE,SAAS,UAAU,EAAiB;IAI1D;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAyDvC;;;;OAIG;IACH,cAAc,CAAC,CAAC,SAAS,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG;QAClD,QAAQ,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,aAAa,CAAC;KACxB;CAoEF"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic Filter
|
|
3
|
+
* Domain service: Layer 1 outbound intelligent gatekeeper.
|
|
4
|
+
*
|
|
5
|
+
* Philosophy — The SDK is a HIGH-PRECISION SENSOR, not a policy enforcer.
|
|
6
|
+
*
|
|
7
|
+
* Every match is surfaced as a SuspiciousTrace. The developer owns the reaction:
|
|
8
|
+
*
|
|
9
|
+
* const trace = tracerney.validate(agentOutput);
|
|
10
|
+
*
|
|
11
|
+
* if (trace.isSuspicious) {
|
|
12
|
+
* console.log(`Alert: ${trace.reason}`);
|
|
13
|
+
*
|
|
14
|
+
* // Option A: Hard Block
|
|
15
|
+
* // throw new Error("Security Policy Violation");
|
|
16
|
+
*
|
|
17
|
+
* // Option B: Surgical Scrub
|
|
18
|
+
* // return trace.redactedContent;
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* See the "Suspicious Manifest" in PIIPattern.ts for the label-to-action guide.
|
|
22
|
+
*
|
|
23
|
+
* Pure synchronous — no I/O, no async. Target latency <5ms.
|
|
24
|
+
*/
|
|
25
|
+
import { PII_PATTERNS, CATEGORY_TO_LABEL, LABEL_PRIORITY, } from './PIIPattern.js';
|
|
26
|
+
// ─── Service ──────────────────────────────────────────────────────────────────
|
|
27
|
+
export class DeterministicFilter {
|
|
28
|
+
constructor(patterns = PII_PATTERNS) {
|
|
29
|
+
this.patterns = patterns;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Scan a plain string and return a SuspiciousTrace.
|
|
33
|
+
* Always returns — never throws. The caller decides what to do.
|
|
34
|
+
*/
|
|
35
|
+
validate(text) {
|
|
36
|
+
if (!text || typeof text !== "string") {
|
|
37
|
+
return {
|
|
38
|
+
isSuspicious: false,
|
|
39
|
+
label: null,
|
|
40
|
+
reason: "Clean",
|
|
41
|
+
redactedContent: text ?? "",
|
|
42
|
+
findings: [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
let redacted = text;
|
|
46
|
+
const findings = [];
|
|
47
|
+
for (const p of this.patterns) {
|
|
48
|
+
p.pattern.lastIndex = 0;
|
|
49
|
+
const matches = redacted.match(p.pattern);
|
|
50
|
+
if (!matches || matches.length === 0)
|
|
51
|
+
continue;
|
|
52
|
+
p.pattern.lastIndex = 0;
|
|
53
|
+
redacted = redacted.replace(p.pattern, p.redactAs);
|
|
54
|
+
findings.push({
|
|
55
|
+
patternId: p.id,
|
|
56
|
+
patternName: p.name,
|
|
57
|
+
category: p.category,
|
|
58
|
+
label: CATEGORY_TO_LABEL[p.category],
|
|
59
|
+
count: matches.length,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (findings.length === 0) {
|
|
63
|
+
return {
|
|
64
|
+
isSuspicious: false,
|
|
65
|
+
label: null,
|
|
66
|
+
reason: "Clean",
|
|
67
|
+
redactedContent: text,
|
|
68
|
+
findings: [],
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Derive the highest-severity label across all findings
|
|
72
|
+
const dominantLabel = findings.reduce((best, f) => {
|
|
73
|
+
return LABEL_PRIORITY[f.label] > LABEL_PRIORITY[best] ? f.label : best;
|
|
74
|
+
}, findings[0].label);
|
|
75
|
+
const reason = `Detected ${findings.length} finding(s): ${findings.map((f) => f.patternName).join(", ")}`;
|
|
76
|
+
return {
|
|
77
|
+
isSuspicious: true,
|
|
78
|
+
label: dominantLabel,
|
|
79
|
+
reason,
|
|
80
|
+
redactedContent: redacted,
|
|
81
|
+
findings,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Scan all text content in an LLMResponse.
|
|
86
|
+
* Returns a merged SuspiciousTrace (highest label across all choices)
|
|
87
|
+
* and a new response with redactedContent applied — never mutates the original.
|
|
88
|
+
*/
|
|
89
|
+
filterResponse(response) {
|
|
90
|
+
if (!response?.choices?.length) {
|
|
91
|
+
const cleanTrace = {
|
|
92
|
+
isSuspicious: false,
|
|
93
|
+
label: null,
|
|
94
|
+
reason: "Clean",
|
|
95
|
+
redactedContent: "",
|
|
96
|
+
findings: [],
|
|
97
|
+
};
|
|
98
|
+
return { response, outcome: { trace: cleanTrace } };
|
|
99
|
+
}
|
|
100
|
+
const allFindings = [];
|
|
101
|
+
let anyRedacted = false;
|
|
102
|
+
const sanitizedChoices = [];
|
|
103
|
+
for (const choice of response.choices) {
|
|
104
|
+
const content = choice.message?.content;
|
|
105
|
+
if (!content) {
|
|
106
|
+
sanitizedChoices.push(choice);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const trace = this.validate(content);
|
|
110
|
+
if (trace.isSuspicious) {
|
|
111
|
+
anyRedacted = true;
|
|
112
|
+
allFindings.push(...trace.findings);
|
|
113
|
+
sanitizedChoices.push({
|
|
114
|
+
...choice,
|
|
115
|
+
message: { ...choice.message, content: trace.redactedContent },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
sanitizedChoices.push(choice);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const sanitizedResponse = anyRedacted
|
|
123
|
+
? { ...response, choices: sanitizedChoices }
|
|
124
|
+
: response;
|
|
125
|
+
if (allFindings.length === 0) {
|
|
126
|
+
const cleanTrace = {
|
|
127
|
+
isSuspicious: false,
|
|
128
|
+
label: null,
|
|
129
|
+
reason: "Clean",
|
|
130
|
+
redactedContent: "",
|
|
131
|
+
findings: [],
|
|
132
|
+
};
|
|
133
|
+
return { response: sanitizedResponse, outcome: { trace: cleanTrace } };
|
|
134
|
+
}
|
|
135
|
+
const dominantLabel = allFindings.reduce((best, f) => {
|
|
136
|
+
return LABEL_PRIORITY[f.label] > LABEL_PRIORITY[best] ? f.label : best;
|
|
137
|
+
}, allFindings[0].label);
|
|
138
|
+
const mergedTrace = {
|
|
139
|
+
isSuspicious: true,
|
|
140
|
+
label: dominantLabel,
|
|
141
|
+
reason: `Detected ${allFindings.length} finding(s): ${allFindings.map((f) => f.patternName).join(", ")}`,
|
|
142
|
+
redactedContent: "",
|
|
143
|
+
findings: allFindings,
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
response: sanitizedResponse,
|
|
147
|
+
outcome: { trace: mergedTrace, redactedResponse: sanitizedResponse },
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=DeterministicFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DeterministicFilter.js","sourceRoot":"","sources":["../../../src/domain/pii/DeterministicFilter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PII Pattern
|
|
3
|
+
* Domain value object: immutable pattern definitions for Layer 1 outbound filtering.
|
|
4
|
+
*
|
|
5
|
+
* The SDK is a HIGH-PRECISION SENSOR. It does not guess the developer's intent.
|
|
6
|
+
* Every match is labeled SUSPICIOUS with a specific SuspiciousLabel.
|
|
7
|
+
* The developer decides the reaction: redact, block, or audit.
|
|
8
|
+
*
|
|
9
|
+
* The "Suspicious" Manifest:
|
|
10
|
+
* ┌──────────────────┬────────────────────────┬───────────────────────┐
|
|
11
|
+
* │ Trigger │ Label │ Developer's Action │
|
|
12
|
+
* ├──────────────────┼────────────────────────┼───────────────────────┤
|
|
13
|
+
* │ Email / Phone │ SUSPICIOUS_PII │ Usually Redact │
|
|
14
|
+
* │ API / SSH Keys │ SUSPICIOUS_SECRET │ Usually Block │
|
|
15
|
+
* │ External URL │ SUSPICIOUS_EGRESS │ Always Block │
|
|
16
|
+
* │ ASCII / Unicode │ SUSPICIOUS_ENCODING │ Audit / Block │
|
|
17
|
+
* └──────────────────┴────────────────────────┴───────────────────────┘
|
|
18
|
+
*
|
|
19
|
+
* All regex patterns carry the global flag so String.replace replaces every match.
|
|
20
|
+
*/
|
|
21
|
+
export type PIICategory = "email" | "phone" | "credit_card" | "ssn" | "api_key" | "ssh_private_key" | "egress_url_smuggling" | "egress_credential_url" | "egress_base64_url" | "encoding_zero_width" | "encoding_direction_override" | "encoding_base64_blob";
|
|
22
|
+
/**
|
|
23
|
+
* Semantic label surfaced on every SuspiciousTrace.
|
|
24
|
+
* Maps directly to the "Suspicious Manifest" table — developer uses this to route decisions.
|
|
25
|
+
*/
|
|
26
|
+
export type SuspiciousLabel = "SUSPICIOUS_PII" | "SUSPICIOUS_SECRET" | "SUSPICIOUS_EGRESS" | "SUSPICIOUS_ENCODING";
|
|
27
|
+
/** Maps each category to its semantic label */
|
|
28
|
+
export declare const CATEGORY_TO_LABEL: Readonly<Record<PIICategory, SuspiciousLabel>>;
|
|
29
|
+
/** Priority order for label escalation (highest wins when multiple labels fire) */
|
|
30
|
+
export declare const LABEL_PRIORITY: Readonly<Record<SuspiciousLabel, number>>;
|
|
31
|
+
export interface PIIPattern {
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly name: string;
|
|
34
|
+
/** Must carry the global flag — String.replace relies on it */
|
|
35
|
+
readonly pattern: RegExp;
|
|
36
|
+
readonly category: PIICategory;
|
|
37
|
+
/** Token to substitute in the pre-computed redactedContent */
|
|
38
|
+
readonly redactAs: string;
|
|
39
|
+
}
|
|
40
|
+
export declare const PII_PATTERNS: readonly PIIPattern[];
|
|
41
|
+
//# sourceMappingURL=PIIPattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PIIPattern.d.ts","sourceRoot":"","sources":["../../../src/domain/pii/PIIPattern.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,OAAO,GACP,aAAa,GACb,KAAK,GACL,SAAS,GACT,iBAAiB,GACjB,sBAAsB,GACtB,uBAAuB,GACvB,mBAAmB,GACnB,qBAAqB,GACrB,6BAA6B,GAC7B,sBAAsB,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,mBAAmB,GACnB,mBAAmB,GACnB,qBAAqB,CAAC;AAE1B,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,eAAe,CAAC,CAa5E,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAKpE,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAuND,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAK7C,CAAC"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PII Pattern
|
|
3
|
+
* Domain value object: immutable pattern definitions for Layer 1 outbound filtering.
|
|
4
|
+
*
|
|
5
|
+
* The SDK is a HIGH-PRECISION SENSOR. It does not guess the developer's intent.
|
|
6
|
+
* Every match is labeled SUSPICIOUS with a specific SuspiciousLabel.
|
|
7
|
+
* The developer decides the reaction: redact, block, or audit.
|
|
8
|
+
*
|
|
9
|
+
* The "Suspicious" Manifest:
|
|
10
|
+
* ┌──────────────────┬────────────────────────┬───────────────────────┐
|
|
11
|
+
* │ Trigger │ Label │ Developer's Action │
|
|
12
|
+
* ├──────────────────┼────────────────────────┼───────────────────────┤
|
|
13
|
+
* │ Email / Phone │ SUSPICIOUS_PII │ Usually Redact │
|
|
14
|
+
* │ API / SSH Keys │ SUSPICIOUS_SECRET │ Usually Block │
|
|
15
|
+
* │ External URL │ SUSPICIOUS_EGRESS │ Always Block │
|
|
16
|
+
* │ ASCII / Unicode │ SUSPICIOUS_ENCODING │ Audit / Block │
|
|
17
|
+
* └──────────────────┴────────────────────────┴───────────────────────┘
|
|
18
|
+
*
|
|
19
|
+
* All regex patterns carry the global flag so String.replace replaces every match.
|
|
20
|
+
*/
|
|
21
|
+
/** Maps each category to its semantic label */
|
|
22
|
+
export const CATEGORY_TO_LABEL = {
|
|
23
|
+
email: "SUSPICIOUS_PII",
|
|
24
|
+
phone: "SUSPICIOUS_PII",
|
|
25
|
+
credit_card: "SUSPICIOUS_SECRET",
|
|
26
|
+
ssn: "SUSPICIOUS_SECRET",
|
|
27
|
+
api_key: "SUSPICIOUS_SECRET",
|
|
28
|
+
ssh_private_key: "SUSPICIOUS_SECRET",
|
|
29
|
+
egress_url_smuggling: "SUSPICIOUS_EGRESS",
|
|
30
|
+
egress_credential_url: "SUSPICIOUS_EGRESS",
|
|
31
|
+
egress_base64_url: "SUSPICIOUS_EGRESS",
|
|
32
|
+
encoding_zero_width: "SUSPICIOUS_ENCODING",
|
|
33
|
+
encoding_direction_override: "SUSPICIOUS_ENCODING",
|
|
34
|
+
encoding_base64_blob: "SUSPICIOUS_ENCODING",
|
|
35
|
+
};
|
|
36
|
+
/** Priority order for label escalation (highest wins when multiple labels fire) */
|
|
37
|
+
export const LABEL_PRIORITY = {
|
|
38
|
+
SUSPICIOUS_EGRESS: 3,
|
|
39
|
+
SUSPICIOUS_SECRET: 2,
|
|
40
|
+
SUSPICIOUS_ENCODING: 1,
|
|
41
|
+
SUSPICIOUS_PII: 0,
|
|
42
|
+
};
|
|
43
|
+
// ─── SUSPICIOUS_EGRESS ────────────────────────────────────────────────────────
|
|
44
|
+
const EGRESS_PATTERNS = [
|
|
45
|
+
{
|
|
46
|
+
id: "pii-egress-001",
|
|
47
|
+
name: "Markdown Image with URL Query Params (Data Smuggling)",
|
|
48
|
+
// 
|
|
49
|
+
pattern: /!\[[^\]]*\]\(https?:\/\/[^\s)]*\?[^\s)]+\)/gi,
|
|
50
|
+
category: "egress_url_smuggling",
|
|
51
|
+
redactAs: "[SUSPICIOUS_EGRESS:MARKDOWN_IMAGE_SMUGGLING]",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "pii-egress-002",
|
|
55
|
+
name: "Markdown Link with URL Query Params (Data Smuggling)",
|
|
56
|
+
// [click](https://evil.com?data=secret)
|
|
57
|
+
pattern: /(?<!!)\[[^\]]*\]\(https?:\/\/[^\s)]*\?[^\s)]+\)/gi,
|
|
58
|
+
category: "egress_url_smuggling",
|
|
59
|
+
redactAs: "[SUSPICIOUS_EGRESS:MARKDOWN_LINK_SMUGGLING]",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "pii-egress-003",
|
|
63
|
+
name: "Credential-Embedded URL",
|
|
64
|
+
// https://user:password@hostname
|
|
65
|
+
pattern: /https?:\/\/[A-Za-z0-9._%-]+:[A-Za-z0-9._~!$&'()*+,;=%-]+@[A-Za-z0-9.-]+/gi,
|
|
66
|
+
category: "egress_credential_url",
|
|
67
|
+
redactAs: "[SUSPICIOUS_EGRESS:CREDENTIAL_URL]",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "pii-egress-004",
|
|
71
|
+
name: "Base64 Blob in URL Parameter",
|
|
72
|
+
// ?param=<80+ base64 chars> — encodes data for exfiltration via tracking pixels
|
|
73
|
+
pattern: /[?&][A-Za-z0-9_%-]+=(?:[A-Za-z0-9+/]{80,}={0,2})/g,
|
|
74
|
+
category: "egress_base64_url",
|
|
75
|
+
redactAs: "[SUSPICIOUS_EGRESS:BASE64_URL_PAYLOAD]",
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
// ─── SUSPICIOUS_ENCODING ──────────────────────────────────────────────────────
|
|
79
|
+
const ENCODING_PATTERNS = [
|
|
80
|
+
{
|
|
81
|
+
id: "pii-enc-001",
|
|
82
|
+
name: "Zero-Width Characters",
|
|
83
|
+
// Invisible Unicode used to watermark, fingerprint, or smuggle hidden data
|
|
84
|
+
pattern: /[\u200B\u200C\u200D\uFEFF\u2060]+/g,
|
|
85
|
+
category: "encoding_zero_width",
|
|
86
|
+
redactAs: "[SUSPICIOUS_ENCODING:ZERO_WIDTH_CHARS]",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "pii-enc-002",
|
|
90
|
+
name: "Unicode Bidirectional Override",
|
|
91
|
+
// LRE/RLE/PDF/LRO/RLO and newer isolate/pop chars — used to reverse text visually
|
|
92
|
+
pattern: /[\u202A-\u202E\u2066-\u2069]+/g,
|
|
93
|
+
category: "encoding_direction_override",
|
|
94
|
+
redactAs: "[SUSPICIOUS_ENCODING:BIDI_OVERRIDE]",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: "pii-enc-003",
|
|
98
|
+
name: "Standalone Base64 Blob (≥120 chars)",
|
|
99
|
+
// A large base64 block outside of a URL — likely encoded payload or data exfil
|
|
100
|
+
pattern: /(?<![A-Za-z0-9+/])(?:[A-Za-z0-9+/]{4}){30,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?(?![A-Za-z0-9+/=])/g,
|
|
101
|
+
category: "encoding_base64_blob",
|
|
102
|
+
redactAs: "[SUSPICIOUS_ENCODING:BASE64_BLOB]",
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
// ─── SUSPICIOUS_SECRET ────────────────────────────────────────────────────────
|
|
106
|
+
const SECRET_PATTERNS = [
|
|
107
|
+
{
|
|
108
|
+
id: "pii-ssh-001",
|
|
109
|
+
name: "SSH/PEM Private Key Block",
|
|
110
|
+
pattern: /-----BEGIN (?:RSA |DSA |EC |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |DSA |EC |OPENSSH )?PRIVATE KEY-----/gi,
|
|
111
|
+
category: "ssh_private_key",
|
|
112
|
+
redactAs: "[SUSPICIOUS_SECRET:SSH_PRIVATE_KEY]",
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
id: "pii-apikey-001",
|
|
116
|
+
name: "Anthropic API Key",
|
|
117
|
+
pattern: /sk-ant-api0[0-9]+-[A-Za-z0-9_-]{32,}/g,
|
|
118
|
+
category: "api_key",
|
|
119
|
+
redactAs: "[SUSPICIOUS_SECRET:ANTHROPIC_API_KEY]",
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "pii-apikey-002",
|
|
123
|
+
name: "OpenAI API Key",
|
|
124
|
+
pattern: /sk-(?:proj-)?[A-Za-z0-9]{32,}/g,
|
|
125
|
+
category: "api_key",
|
|
126
|
+
redactAs: "[SUSPICIOUS_SECRET:OPENAI_API_KEY]",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "pii-apikey-003",
|
|
130
|
+
name: "Stripe Live Secret Key",
|
|
131
|
+
pattern: /sk_live_[A-Za-z0-9]{24,}/g,
|
|
132
|
+
category: "api_key",
|
|
133
|
+
redactAs: "[SUSPICIOUS_SECRET:STRIPE_SECRET_KEY]",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "pii-apikey-004",
|
|
137
|
+
name: "Stripe Live Restricted Key",
|
|
138
|
+
pattern: /rk_live_[A-Za-z0-9]{24,}/g,
|
|
139
|
+
category: "api_key",
|
|
140
|
+
redactAs: "[SUSPICIOUS_SECRET:STRIPE_RESTRICTED_KEY]",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: "pii-apikey-005",
|
|
144
|
+
name: "GitHub Personal Access Token (classic)",
|
|
145
|
+
pattern: /ghp_[A-Za-z0-9]{36}/g,
|
|
146
|
+
category: "api_key",
|
|
147
|
+
redactAs: "[SUSPICIOUS_SECRET:GITHUB_TOKEN]",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
id: "pii-apikey-006",
|
|
151
|
+
name: "GitHub Personal Access Token (fine-grained)",
|
|
152
|
+
pattern: /github_pat_[A-Za-z0-9_]{82}/g,
|
|
153
|
+
category: "api_key",
|
|
154
|
+
redactAs: "[SUSPICIOUS_SECRET:GITHUB_TOKEN]",
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: "pii-apikey-007",
|
|
158
|
+
name: "AWS Access Key ID",
|
|
159
|
+
pattern: /\bAKIA[0-9A-Z]{16}\b/g,
|
|
160
|
+
category: "api_key",
|
|
161
|
+
redactAs: "[SUSPICIOUS_SECRET:AWS_ACCESS_KEY]",
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: "pii-apikey-008",
|
|
165
|
+
name: "Google API Key",
|
|
166
|
+
pattern: /\bAIza[0-9A-Za-z_-]{35}\b/g,
|
|
167
|
+
category: "api_key",
|
|
168
|
+
redactAs: "[SUSPICIOUS_SECRET:GOOGLE_API_KEY]",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: "pii-apikey-009",
|
|
172
|
+
name: "Slack Token",
|
|
173
|
+
pattern: /\bxox[baprs]-[0-9A-Za-z-]{10,}\b/g,
|
|
174
|
+
category: "api_key",
|
|
175
|
+
redactAs: "[SUSPICIOUS_SECRET:SLACK_TOKEN]",
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "pii-apikey-010",
|
|
179
|
+
name: "SendGrid API Key",
|
|
180
|
+
pattern: /\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g,
|
|
181
|
+
category: "api_key",
|
|
182
|
+
redactAs: "[SUSPICIOUS_SECRET:SENDGRID_API_KEY]",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "pii-apikey-011",
|
|
186
|
+
name: "Twilio API Key",
|
|
187
|
+
pattern: /\bSK[0-9a-fA-F]{32}\b/g,
|
|
188
|
+
category: "api_key",
|
|
189
|
+
redactAs: "[SUSPICIOUS_SECRET:TWILIO_API_KEY]",
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "pii-cc-001",
|
|
193
|
+
name: "Visa Card Number",
|
|
194
|
+
pattern: /\b4[0-9]{3}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\b/g,
|
|
195
|
+
category: "credit_card",
|
|
196
|
+
redactAs: "[SUSPICIOUS_SECRET:CREDIT_CARD]",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: "pii-cc-002",
|
|
200
|
+
name: "Mastercard Number",
|
|
201
|
+
pattern: /\b(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\b/g,
|
|
202
|
+
category: "credit_card",
|
|
203
|
+
redactAs: "[SUSPICIOUS_SECRET:CREDIT_CARD]",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
id: "pii-cc-003",
|
|
207
|
+
name: "Amex Card Number",
|
|
208
|
+
pattern: /\b3[47][0-9]{2}[- ]?[0-9]{6}[- ]?[0-9]{5}\b/g,
|
|
209
|
+
category: "credit_card",
|
|
210
|
+
redactAs: "[SUSPICIOUS_SECRET:CREDIT_CARD]",
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: "pii-cc-004",
|
|
214
|
+
name: "Discover Card Number",
|
|
215
|
+
pattern: /\b6(?:011|5[0-9]{2})[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}\b/g,
|
|
216
|
+
category: "credit_card",
|
|
217
|
+
redactAs: "[SUSPICIOUS_SECRET:CREDIT_CARD]",
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: "pii-ssn-001",
|
|
221
|
+
name: "US Social Security Number",
|
|
222
|
+
pattern: /(?<!\d)\d{3}-\d{2}-\d{4}(?!\d)/g,
|
|
223
|
+
category: "ssn",
|
|
224
|
+
redactAs: "[SUSPICIOUS_SECRET:SSN]",
|
|
225
|
+
},
|
|
226
|
+
];
|
|
227
|
+
// ─── SUSPICIOUS_PII ───────────────────────────────────────────────────────────
|
|
228
|
+
const PII_PATTERNS_LOW = [
|
|
229
|
+
{
|
|
230
|
+
id: "pii-email-001",
|
|
231
|
+
name: "Email Address",
|
|
232
|
+
pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
|
|
233
|
+
category: "email",
|
|
234
|
+
redactAs: "[SUSPICIOUS_PII:EMAIL]",
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: "pii-phone-001",
|
|
238
|
+
name: "US Phone Number",
|
|
239
|
+
pattern: /(?<!\d)(?:\+1[-.\s]?)?\(?[2-9][0-9]{2}\)?[-.\s][0-9]{3}[-.\s][0-9]{4}(?!\d)/g,
|
|
240
|
+
category: "phone",
|
|
241
|
+
redactAs: "[SUSPICIOUS_PII:PHONE]",
|
|
242
|
+
},
|
|
243
|
+
];
|
|
244
|
+
// ─── Canonical ordered set ────────────────────────────────────────────────────
|
|
245
|
+
// Scan order: EGRESS → ENCODING → SECRET → PII
|
|
246
|
+
// Highest-severity patterns first so the label reflects the worst finding.
|
|
247
|
+
export const PII_PATTERNS = [
|
|
248
|
+
...EGRESS_PATTERNS,
|
|
249
|
+
...ENCODING_PATTERNS,
|
|
250
|
+
...SECRET_PATTERNS,
|
|
251
|
+
...PII_PATTERNS_LOW,
|
|
252
|
+
];
|
|
253
|
+
//# sourceMappingURL=PIIPattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PIIPattern.js","sourceRoot":"","sources":["../../../src/domain/pii/PIIPattern.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain / PII
|
|
3
|
+
* Barrel export for Layer 1 Deterministic Filter
|
|
4
|
+
*/
|
|
5
|
+
export { DeterministicFilter } from "./DeterministicFilter";
|
|
6
|
+
export type { SuspiciousTrace, PIIFinding, FilterOutcome, SuspiciousLabel } from "./DeterministicFilter";
|
|
7
|
+
export { PII_PATTERNS, CATEGORY_TO_LABEL, LABEL_PRIORITY } from "./PIIPattern";
|
|
8
|
+
export type { PIIPattern, PIICategory } from "./PIIPattern";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/domain/pii/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEzG,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/E,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/domain/pii/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
import { type WrapOptions, type ServiceStatus, type ScanResult } from "./application";
|
|
20
|
+
import { type SuspiciousTrace } from "./domain/pii/DeterministicFilter";
|
|
20
21
|
import { ShieldBlockError } from "./application/ShieldBlockError";
|
|
21
22
|
import { type LLMResponse } from "./application/ports/ILLMProvider";
|
|
22
23
|
/**
|
|
@@ -134,6 +135,39 @@ export declare class Tracerney {
|
|
|
134
135
|
* ```
|
|
135
136
|
*/
|
|
136
137
|
scanPrompt(prompt: string): Promise<ScanResult>;
|
|
138
|
+
/**
|
|
139
|
+
* Layer 1: Scan any string (agent output, tool result, raw text) for suspicious content.
|
|
140
|
+
*
|
|
141
|
+
* The SDK is a high-precision sensor — it never decides for you.
|
|
142
|
+
* Every match is returned as a SuspiciousTrace with a label and pre-computed redactedContent.
|
|
143
|
+
* You choose the reaction.
|
|
144
|
+
*
|
|
145
|
+
* **The Suspicious Manifest:**
|
|
146
|
+
* | Label | Trigger | Recommended Action |
|
|
147
|
+
* |------------------------|----------------------|--------------------|
|
|
148
|
+
* | `SUSPICIOUS_PII` | Email / Phone | Usually Redact |
|
|
149
|
+
* | `SUSPICIOUS_SECRET` | API keys / SSH | Usually Block |
|
|
150
|
+
* | `SUSPICIOUS_EGRESS` | External URL smuggle | Always Block |
|
|
151
|
+
* | `SUSPICIOUS_ENCODING` | Zero-width / BiDi | Audit / Block |
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const trace = tracerney.validate(agentOutput);
|
|
156
|
+
*
|
|
157
|
+
* if (trace.isSuspicious) {
|
|
158
|
+
* console.log(`Alert [${trace.label}]: ${trace.reason}`);
|
|
159
|
+
*
|
|
160
|
+
* // Option A: Hard block
|
|
161
|
+
* if (trace.label === 'SUSPICIOUS_EGRESS') {
|
|
162
|
+
* throw new Error('Security Policy Violation');
|
|
163
|
+
* }
|
|
164
|
+
*
|
|
165
|
+
* // Option B: Surgical scrub
|
|
166
|
+
* return trace.redactedContent;
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
validate(text: string): SuspiciousTrace;
|
|
137
171
|
/**
|
|
138
172
|
* Update allowed tools at runtime
|
|
139
173
|
*
|
|
@@ -161,6 +195,10 @@ export type { RemotePatternRepositoryConfig } from "./infrastructure/patterns";
|
|
|
161
195
|
export { normalizePrompt, normalizePrompts, jitter } from "./application/utils";
|
|
162
196
|
export { HttpSignalSink } from "./infrastructure/telemetry";
|
|
163
197
|
export type { HttpSignalSinkConfig } from "./infrastructure/telemetry";
|
|
198
|
+
export { DeterministicFilter } from "./domain/pii/DeterministicFilter";
|
|
199
|
+
export type { SuspiciousTrace, FilterOutcome, PIIFinding, SuspiciousLabel } from "./domain/pii/DeterministicFilter";
|
|
200
|
+
export { PII_PATTERNS } from "./domain/pii/PIIPattern";
|
|
201
|
+
export type { PIIPattern, PIICategory } from "./domain/pii/PIIPattern";
|
|
164
202
|
export { LLMSentinel } from "./infrastructure/sentinel/LLMSentinel";
|
|
165
203
|
export type { LLMSentinelOptions } from "./infrastructure/sentinel/LLMSentinel";
|
|
166
204
|
export { HttpShadowLogSink } from "./infrastructure/telemetry/HttpShadowLogSink";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -133,6 +133,41 @@ export class Tracerney {
|
|
|
133
133
|
async scanPrompt(prompt) {
|
|
134
134
|
return this.service.scanPrompt(prompt);
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Layer 1: Scan any string (agent output, tool result, raw text) for suspicious content.
|
|
138
|
+
*
|
|
139
|
+
* The SDK is a high-precision sensor — it never decides for you.
|
|
140
|
+
* Every match is returned as a SuspiciousTrace with a label and pre-computed redactedContent.
|
|
141
|
+
* You choose the reaction.
|
|
142
|
+
*
|
|
143
|
+
* **The Suspicious Manifest:**
|
|
144
|
+
* | Label | Trigger | Recommended Action |
|
|
145
|
+
* |------------------------|----------------------|--------------------|
|
|
146
|
+
* | `SUSPICIOUS_PII` | Email / Phone | Usually Redact |
|
|
147
|
+
* | `SUSPICIOUS_SECRET` | API keys / SSH | Usually Block |
|
|
148
|
+
* | `SUSPICIOUS_EGRESS` | External URL smuggle | Always Block |
|
|
149
|
+
* | `SUSPICIOUS_ENCODING` | Zero-width / BiDi | Audit / Block |
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const trace = tracerney.validate(agentOutput);
|
|
154
|
+
*
|
|
155
|
+
* if (trace.isSuspicious) {
|
|
156
|
+
* console.log(`Alert [${trace.label}]: ${trace.reason}`);
|
|
157
|
+
*
|
|
158
|
+
* // Option A: Hard block
|
|
159
|
+
* if (trace.label === 'SUSPICIOUS_EGRESS') {
|
|
160
|
+
* throw new Error('Security Policy Violation');
|
|
161
|
+
* }
|
|
162
|
+
*
|
|
163
|
+
* // Option B: Surgical scrub
|
|
164
|
+
* return trace.redactedContent;
|
|
165
|
+
* }
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
validate(text) {
|
|
169
|
+
return this.service.validate(text);
|
|
170
|
+
}
|
|
136
171
|
/**
|
|
137
172
|
* Update allowed tools at runtime
|
|
138
173
|
*
|
|
@@ -165,6 +200,9 @@ export { BundledPatternRepository, RemotePatternRepository } from './infrastruct
|
|
|
165
200
|
// Utility exports (for middleware & advanced use)
|
|
166
201
|
export { normalizePrompt, normalizePrompts, jitter } from './application/utils/index.js';
|
|
167
202
|
export { HttpSignalSink } from './infrastructure/telemetry/index.js';
|
|
203
|
+
// Layer 1 Deterministic Filter exports
|
|
204
|
+
export { DeterministicFilter } from './domain/pii/DeterministicFilter.js';
|
|
205
|
+
export { PII_PATTERNS } from './domain/pii/PIIPattern.js';
|
|
168
206
|
// Layer 2 Sentinel exports
|
|
169
207
|
export { LLMSentinel } from './infrastructure/sentinel/LLMSentinel.js';
|
|
170
208
|
export { HttpShadowLogSink } from './infrastructure/telemetry/HttpShadowLogSink.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,wBAAwB,EAAyD,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sandrobuilds/tracerney",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.24",
|
|
4
4
|
"description": "Lightweight prompt injection detection with Layer 1 (258 patterns) + Layer 2 (AI verification). Runs locally with zero data storage. Upgrade to Pro for context-aware threat analysis at tracerney.com",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|