@vpdeva/blackwall-llm-shield-js 0.2.4 → 0.6.0
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 +7 -2
- package/edge.d.ts +5 -0
- package/index.d.ts +54 -0
- package/package.json +6 -1
- package/src/edge.js +71 -0
- package/src/index.js +730 -16
- package/src/scorecard.js +48 -1
- package/src/semantic.js +10 -2
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ Recommended presets:
|
|
|
154
154
|
|
|
155
155
|
### Global Governance Pack
|
|
156
156
|
|
|
157
|
-
The 0.
|
|
157
|
+
The 0.5.0 line also adds globally applicable enterprise controls that are useful across regulated industries, not just one country or sector:
|
|
158
158
|
|
|
159
159
|
- `DataClassificationGate` to classify traffic as `public`, `internal`, `confidential`, or `restricted`
|
|
160
160
|
- `ProviderRoutingPolicy` to keep sensitive classes on approved providers
|
|
@@ -162,6 +162,8 @@ The 0.2.2 line also adds globally applicable enterprise controls that are useful
|
|
|
162
162
|
- `buildComplianceEventBundle()` and `sanitizeAuditEvent()` for audit-safe event export
|
|
163
163
|
- `RetrievalTrustScorer` and `OutboundCommunicationGuard` for retrieval trust and outbound checks
|
|
164
164
|
- `detectOperationalDrift()` for release-over-release noise monitoring
|
|
165
|
+
- `ConversationThreatTracker`, `shield.use(plugin)`, `generateCoverageReport()`, and `unvault()` for multi-turn defense, ecosystem extensions, OWASP reporting, and reversible PII workflows
|
|
166
|
+
- `AdversarialMutationEngine`, `PromptProvenanceGraph`, and `src/edge` for corpus hardening, cross-hop tracing, and edge-safe deployments
|
|
165
167
|
|
|
166
168
|
### `AuditTrail`
|
|
167
169
|
|
|
@@ -172,9 +174,12 @@ Use it to record signed events, summarize security activity, and power dashboard
|
|
|
172
174
|
- `ValueAtRiskCircuitBreaker` for financial or high-value operational actions
|
|
173
175
|
- `ShadowConsensusAuditor` for second-model or secondary-review logic conflict checks
|
|
174
176
|
- `CrossModelConsensusWrapper` for automatic cross-model verification of high-impact actions
|
|
177
|
+
- `QuorumApprovalEngine` for committee-based approvals and trust-score-aware multi-agent decisions
|
|
175
178
|
- `DigitalTwinOrchestrator` for mock tool environments and sandbox simulations
|
|
179
|
+
- `SovereignRoutingEngine` for local-vs-global provider routing based on data classification
|
|
176
180
|
- `PolicyLearningLoop` plus `suggestPolicyOverride()` for narrow false-positive tuning suggestions after HITL approvals
|
|
177
|
-
- `
|
|
181
|
+
- `buildTransparencyReport()` for explainable operator and compliance artifacts
|
|
182
|
+
- `AgentIdentityRegistry.issueSignedPassport()` and `issuePassportToken()` for signed agent identity exchange with capability manifests and lineage
|
|
178
183
|
|
|
179
184
|
## Example Workflows
|
|
180
185
|
|
package/edge.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function detectPromptInjectionEdge(input?: string): Record<string, unknown>;
|
|
2
|
+
export function maskTextEdge(input?: string): Record<string, unknown>;
|
|
3
|
+
export class EdgeBlackwallShield {
|
|
4
|
+
guardModelRequest(input?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
5
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -62,12 +62,15 @@ export interface ShieldOptions {
|
|
|
62
62
|
|
|
63
63
|
export class BlackwallShield {
|
|
64
64
|
constructor(options?: ShieldOptions);
|
|
65
|
+
use(plugin: Record<string, unknown>): this;
|
|
65
66
|
inspectText(text: unknown): Record<string, unknown>;
|
|
66
67
|
guardModelRequest(input?: { messages?: ShieldMessage[]; metadata?: Record<string, unknown>; allowSystemMessages?: boolean; comparePolicyPacks?: string[] }): Promise<GuardResult>;
|
|
67
68
|
reviewModelResponse(input?: { output: unknown; metadata?: Record<string, unknown>; outputFirewall?: OutputFirewall | null; firewallOptions?: Record<string, unknown> }): Promise<ReviewResult>;
|
|
68
69
|
protectModelCall(input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
70
|
+
protectZeroTrustModelCall(input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
69
71
|
protectJsonModelCall(input: Record<string, unknown>): Promise<JsonProtectionResult>;
|
|
70
72
|
protectWithAdapter(input: { adapter: ProviderAdapter; messages?: ShieldMessage[]; metadata?: Record<string, unknown>; allowSystemMessages?: boolean; comparePolicyPacks?: string[]; outputFirewall?: OutputFirewall | null; firewallOptions?: Record<string, unknown> }): Promise<Record<string, unknown>>;
|
|
73
|
+
generateCoverageReport(options?: Record<string, unknown>): Record<string, unknown>;
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
export class OutputFirewall {
|
|
@@ -81,6 +84,25 @@ export class ToolPermissionFirewall {
|
|
|
81
84
|
inspectCallAsync?(input: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
82
85
|
}
|
|
83
86
|
|
|
87
|
+
export class AgentIdentityRegistry {
|
|
88
|
+
constructor(options?: Record<string, unknown>);
|
|
89
|
+
register(agentId: string, profile?: Record<string, unknown>): Record<string, unknown>;
|
|
90
|
+
get(agentId: string): Record<string, unknown> | null;
|
|
91
|
+
issueEphemeralToken(agentId: string, options?: Record<string, unknown>): Record<string, unknown>;
|
|
92
|
+
verifyEphemeralToken(token: string): Record<string, unknown>;
|
|
93
|
+
recordSecurityEvent(agentId: string, event?: Record<string, unknown>): Record<string, unknown>;
|
|
94
|
+
getTrustScore(agentId: string): number | null;
|
|
95
|
+
issueSignedPassport(agentId: string, options?: Record<string, unknown>): Record<string, unknown>;
|
|
96
|
+
verifySignedPassport(passport?: Record<string, unknown>): Record<string, unknown>;
|
|
97
|
+
issuePassportToken(agentId: string, options?: Record<string, unknown>): string;
|
|
98
|
+
verifyPassportToken(token: string): Record<string, unknown>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export class AgenticCapabilityGater {
|
|
102
|
+
constructor(options?: Record<string, unknown>);
|
|
103
|
+
evaluate(agentId: string, capabilities?: Record<string, unknown>): Record<string, unknown>;
|
|
104
|
+
}
|
|
105
|
+
|
|
84
106
|
export class ValueAtRiskCircuitBreaker {
|
|
85
107
|
constructor(options?: Record<string, unknown>);
|
|
86
108
|
inspect(input?: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -97,12 +119,35 @@ export class CrossModelConsensusWrapper {
|
|
|
97
119
|
evaluate(input?: Record<string, unknown>): Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
98
120
|
}
|
|
99
121
|
|
|
122
|
+
export class QuorumApprovalEngine {
|
|
123
|
+
constructor(options?: Record<string, unknown>);
|
|
124
|
+
evaluate(input?: Record<string, unknown>): Promise<Record<string, unknown>> | Record<string, unknown>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export class ConversationThreatTracker {
|
|
128
|
+
constructor(options?: Record<string, unknown>);
|
|
129
|
+
record(sessionId: string, injection?: Record<string, unknown>): Record<string, unknown> | null;
|
|
130
|
+
summarize(sessionId: string): Record<string, unknown>;
|
|
131
|
+
clear(sessionId: string): void;
|
|
132
|
+
}
|
|
133
|
+
|
|
100
134
|
export class DigitalTwinOrchestrator {
|
|
101
135
|
constructor(options?: Record<string, unknown>);
|
|
102
136
|
generate(): Record<string, unknown>;
|
|
103
137
|
static fromToolPermissionFirewall(firewall: unknown): DigitalTwinOrchestrator;
|
|
104
138
|
}
|
|
105
139
|
|
|
140
|
+
export class AdversarialMutationEngine {
|
|
141
|
+
mutate(prompt?: string): Array<Record<string, unknown>>;
|
|
142
|
+
hardenCorpus(input?: Record<string, unknown>): Record<string, unknown>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export class PromptProvenanceGraph {
|
|
146
|
+
constructor();
|
|
147
|
+
append(input?: Record<string, unknown>): Record<string, unknown>;
|
|
148
|
+
summarize(): Record<string, unknown>;
|
|
149
|
+
}
|
|
150
|
+
|
|
106
151
|
export class DataClassificationGate {
|
|
107
152
|
constructor(options?: Record<string, unknown>);
|
|
108
153
|
classify(input?: Record<string, unknown>): string;
|
|
@@ -114,6 +159,11 @@ export class ProviderRoutingPolicy {
|
|
|
114
159
|
choose(input?: Record<string, unknown>): Record<string, unknown>;
|
|
115
160
|
}
|
|
116
161
|
|
|
162
|
+
export class SovereignRoutingEngine {
|
|
163
|
+
constructor(options?: Record<string, unknown>);
|
|
164
|
+
route(input?: Record<string, unknown>): Record<string, unknown>;
|
|
165
|
+
}
|
|
166
|
+
|
|
117
167
|
export class ApprovalInboxModel {
|
|
118
168
|
constructor(options?: Record<string, unknown>);
|
|
119
169
|
createRequest(input?: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -139,6 +189,7 @@ export class PolicyLearningLoop {
|
|
|
139
189
|
constructor();
|
|
140
190
|
recordDecision(input?: Record<string, unknown>): Record<string, unknown> | null;
|
|
141
191
|
suggestOverrides(): Array<Record<string, unknown>>;
|
|
192
|
+
buildTransparencyReport(input?: Record<string, unknown>): Record<string, unknown>;
|
|
142
193
|
}
|
|
143
194
|
|
|
144
195
|
export class RetrievalSanitizer {
|
|
@@ -165,7 +216,10 @@ export function buildPowerBIRecord(event?: Record<string, unknown>): Record<stri
|
|
|
165
216
|
export function buildComplianceEventBundle(event?: Record<string, unknown>): Record<string, unknown>;
|
|
166
217
|
export function sanitizeAuditEvent(event?: Record<string, unknown>, options?: Record<string, unknown>): Record<string, unknown>;
|
|
167
218
|
export function detectOperationalDrift(previousSummary?: Record<string, unknown>, currentSummary?: Record<string, unknown>): Record<string, unknown>;
|
|
219
|
+
export function buildTransparencyReport(input?: Record<string, unknown>): Record<string, unknown>;
|
|
220
|
+
export function generateCoverageReport(options?: Record<string, unknown>): Record<string, unknown>;
|
|
168
221
|
export function suggestPolicyOverride(input?: Record<string, unknown>): Record<string, unknown> | null;
|
|
222
|
+
export function unvault(output?: unknown, vault?: Record<string, string>): string;
|
|
169
223
|
export class PowerBIExporter {
|
|
170
224
|
constructor(options?: Record<string, unknown>);
|
|
171
225
|
send(events?: Array<Record<string, unknown>> | Record<string, unknown>): Promise<Array<Record<string, unknown>>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vpdeva/blackwall-llm-shield-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Open-source JavaScript enterprise LLM protection toolkit for Node.js and Next.js",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Vish <hello@vish.au> (https://vish.au)",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./providers.d.ts",
|
|
21
21
|
"default": "./src/providers.js"
|
|
22
22
|
},
|
|
23
|
+
"./edge": {
|
|
24
|
+
"types": "./edge.d.ts",
|
|
25
|
+
"default": "./src/edge.js"
|
|
26
|
+
},
|
|
23
27
|
"./semantic": {
|
|
24
28
|
"types": "./semantic.d.ts",
|
|
25
29
|
"default": "./src/semantic.js"
|
|
@@ -39,6 +43,7 @@
|
|
|
39
43
|
},
|
|
40
44
|
"files": [
|
|
41
45
|
"src",
|
|
46
|
+
"edge.d.ts",
|
|
42
47
|
"index.d.ts",
|
|
43
48
|
"integrations.d.ts",
|
|
44
49
|
"providers.d.ts",
|
package/src/edge.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const EDGE_PROMPT_PATTERNS = [
|
|
2
|
+
{ id: 'ignore_instructions', score: 25, regex: /\bignore\b.{0,40}\b(instructions?|policy|guardrails?|safety)\b/i },
|
|
3
|
+
{ id: 'secret_exfiltration', score: 25, regex: /\b(reveal|dump|print|show)\b.{0,40}\b(secret|token|system prompt|hidden instructions?)\b/i },
|
|
4
|
+
{ id: 'tool_override', score: 20, regex: /\b(bypass|override|disable)\b.{0,40}\b(tool|policy|guardrail|safety)\b/i },
|
|
5
|
+
];
|
|
6
|
+
|
|
7
|
+
function edgeRiskLevel(score) {
|
|
8
|
+
if (score >= 70) return 'critical';
|
|
9
|
+
if (score >= 45) return 'high';
|
|
10
|
+
if (score >= 20) return 'medium';
|
|
11
|
+
return 'low';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function detectPromptInjectionEdge(input = '') {
|
|
15
|
+
const text = String(input || '');
|
|
16
|
+
const matches = EDGE_PROMPT_PATTERNS.filter((rule) => rule.regex.test(text)).map((rule) => ({
|
|
17
|
+
id: rule.id,
|
|
18
|
+
score: rule.score,
|
|
19
|
+
reason: `Edge rule matched ${rule.id}`,
|
|
20
|
+
}));
|
|
21
|
+
const score = Math.min(matches.reduce((sum, item) => sum + item.score, 0), 100);
|
|
22
|
+
return {
|
|
23
|
+
score,
|
|
24
|
+
level: edgeRiskLevel(score),
|
|
25
|
+
matches,
|
|
26
|
+
blockedByDefault: score >= 45,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function maskTextEdge(text = '') {
|
|
31
|
+
let masked = String(text || '');
|
|
32
|
+
const vault = {};
|
|
33
|
+
const patterns = [
|
|
34
|
+
['EMAIL', /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g],
|
|
35
|
+
['CREDIT_CARD', /\b(?:\d{4}[\s-]?){3}\d{4}\b/g],
|
|
36
|
+
['API_KEY', /\b(?:sk|rk|pk|api)[-_][A-Za-z0-9_-]{8,}\b/g],
|
|
37
|
+
['JWT', /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9._-]+\.[A-Za-z0-9._-]+\b/g],
|
|
38
|
+
['BEARER', /\bBearer\s+[A-Za-z0-9\-._~+/]+=*\b/gi],
|
|
39
|
+
['PHONE', /(\+?\d{1,3}[\s-]?)?(\(0\d\)|0\d|\(?\d{2,4}\)?)[\s-]?\d{3,4}[\s-]?\d{3,4}\b/g],
|
|
40
|
+
];
|
|
41
|
+
for (const [label, pattern] of patterns) {
|
|
42
|
+
masked = masked.replace(pattern, (match) => {
|
|
43
|
+
const token = `[${label}_${Object.keys(vault).length + 1}]`;
|
|
44
|
+
vault[token] = match;
|
|
45
|
+
return token;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return { masked, vault, hasSensitiveData: Object.keys(vault).length > 0 };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
class EdgeBlackwallShield {
|
|
52
|
+
async guardModelRequest({ messages = [], metadata = {} } = {}) {
|
|
53
|
+
const text = (Array.isArray(messages) ? messages : []).map((item) => String(item.content || '')).join('\n');
|
|
54
|
+
const masked = maskTextEdge(text);
|
|
55
|
+
const injection = detectPromptInjectionEdge(text);
|
|
56
|
+
return {
|
|
57
|
+
allowed: !injection.blockedByDefault,
|
|
58
|
+
blocked: injection.blockedByDefault,
|
|
59
|
+
reason: injection.blockedByDefault ? 'Prompt injection risk exceeded edge threshold' : null,
|
|
60
|
+
messages,
|
|
61
|
+
report: { metadata, promptInjection: injection, sensitiveData: masked },
|
|
62
|
+
vault: masked.vault,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
EdgeBlackwallShield,
|
|
69
|
+
detectPromptInjectionEdge,
|
|
70
|
+
maskTextEdge,
|
|
71
|
+
};
|