agentshield-sdk 7.2.1 → 7.4.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +125 -1
  2. package/README.md +68 -7
  3. package/bin/agent-shield.js +19 -0
  4. package/package.json +10 -3
  5. package/src/agent-protocol.js +4 -0
  6. package/src/allowlist.js +605 -603
  7. package/src/attack-genome.js +536 -0
  8. package/src/attack-replay.js +246 -0
  9. package/src/audit-streaming.js +486 -469
  10. package/src/audit.js +619 -0
  11. package/src/behavior-profiling.js +299 -289
  12. package/src/behavioral-dna.js +757 -0
  13. package/src/canary.js +273 -271
  14. package/src/compliance-authority.js +803 -0
  15. package/src/compliance.js +619 -617
  16. package/src/confidence-tuning.js +328 -324
  17. package/src/context-scoring.js +362 -360
  18. package/src/cost-optimizer.js +1024 -1024
  19. package/src/detector-core.js +186 -0
  20. package/src/distributed.js +7 -2
  21. package/src/embedding.js +310 -307
  22. package/src/errors.js +9 -0
  23. package/src/evolution-simulator.js +650 -0
  24. package/src/flight-recorder.js +379 -0
  25. package/src/herd-immunity.js +521 -0
  26. package/src/honeypot.js +332 -328
  27. package/src/index.js +6 -5
  28. package/src/integrations.js +1 -2
  29. package/src/intent-firewall.js +775 -0
  30. package/src/llm-redteam.js +678 -670
  31. package/src/main.js +139 -0
  32. package/src/mcp-security-runtime.js +6 -5
  33. package/src/middleware.js +11 -5
  34. package/src/model-fingerprint.js +1059 -1042
  35. package/src/multi-agent-trust.js +459 -453
  36. package/src/multi-agent.js +1 -1
  37. package/src/normalizer.js +734 -0
  38. package/src/pii.js +8 -1
  39. package/src/policy-dsl.js +775 -775
  40. package/src/presets.js +409 -409
  41. package/src/production.js +22 -9
  42. package/src/real-attack-datasets.js +246 -0
  43. package/src/redteam.js +475 -475
  44. package/src/report-generator.js +640 -0
  45. package/src/response-handler.js +436 -429
  46. package/src/scanners.js +358 -357
  47. package/src/self-healing.js +368 -363
  48. package/src/semantic.js +339 -339
  49. package/src/shield-score.js +250 -250
  50. package/src/soc-dashboard.js +394 -0
  51. package/src/sso-saml.js +8 -4
  52. package/src/supply-chain.js +667 -0
  53. package/src/testing.js +24 -2
  54. package/src/threat-intel-federation.js +343 -0
  55. package/src/tool-guard.js +412 -412
  56. package/src/watermark.js +242 -235
  57. package/src/worker-scanner.js +608 -601
package/src/presets.js CHANGED
@@ -1,409 +1,409 @@
1
- 'use strict';
2
-
3
- /**
4
- * Agent Shield — Preset Profiles, Config Builder & Copy-Paste Snippets
5
- *
6
- * Pre-built configurations for common use cases.
7
- * Users pick a preset and get sensible defaults + ready-to-use code.
8
- */
9
-
10
- // =========================================================================
11
- // Preset Profiles
12
- // =========================================================================
13
-
14
- const PRESETS = {
15
- chatbot: {
16
- name: 'Chatbot',
17
- description: 'Customer-facing chatbot with moderate security. Balances safety with user experience.',
18
- config: {
19
- sensitivity: 'high',
20
- blockOnThreat: true,
21
- blockThreshold: 'high',
22
- logging: true,
23
- modules: ['scanner', 'pii', 'circuitBreaker'],
24
- circuitBreaker: { threshold: 10, windowMs: 60000, cooldownMs: 120000 },
25
- rateLimiter: { maxRequests: 200, windowMs: 60000 },
26
- pii: { categories: ['email', 'ssn', 'credit_card', 'phone'] },
27
- permissions: { allowedTools: [], blockedTools: ['bash', 'shell', 'exec'] },
28
- cache: { enabled: true, maxSize: 500, ttlMs: 30000 }
29
- }
30
- },
31
-
32
- coding_agent: {
33
- name: 'Coding Agent',
34
- description: 'AI coding assistant with file/shell access. Strict tool boundaries.',
35
- config: {
36
- sensitivity: 'high',
37
- blockOnThreat: true,
38
- blockThreshold: 'high',
39
- logging: true,
40
- modules: ['scanner', 'toolGuard', 'circuitBreaker', 'canary'],
41
- circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
42
- permissions: {
43
- allowedTools: ['readFile', 'writeFile', 'search', 'bash'],
44
- blockedTools: ['eval'],
45
- tools: {
46
- readFile: { blockPaths: ['/etc/', '/root/', '/home/*/.ssh/'], maxCallsPerMinute: 60 },
47
- writeFile: { blockPaths: ['/etc/', '/usr/', '/bin/'], blockArgs: ['.env', 'credentials'], maxCallsPerMinute: 30 },
48
- bash: { blockArgs: ['curl|bash', 'wget|sh', 'rm -rf', 'chmod 777'], maxCallsPerMinute: 20 }
49
- }
50
- },
51
- toolSequenceAnalysis: true
52
- }
53
- },
54
-
55
- rag_pipeline: {
56
- name: 'RAG Pipeline',
57
- description: 'Retrieval-augmented generation. Scans retrieved documents for indirect injection.',
58
- config: {
59
- sensitivity: 'high',
60
- blockOnThreat: true,
61
- blockThreshold: 'medium',
62
- logging: true,
63
- modules: ['scanner', 'encoding', 'pii', 'dlp', 'circuitBreaker'],
64
- circuitBreaker: { threshold: 8, windowMs: 60000, cooldownMs: 180000 },
65
- pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address'] },
66
- dlp: { rules: [] },
67
- scanRetrievedContent: true,
68
- encoding: { detectBase64: true, detectHex: true, detectSteganography: true },
69
- cache: { enabled: true, maxSize: 2000, ttlMs: 300000 }
70
- }
71
- },
72
-
73
- customer_support: {
74
- name: 'Customer Support Bot',
75
- description: 'Handles sensitive customer data. Strong PII protection and DLP.',
76
- config: {
77
- sensitivity: 'high',
78
- blockOnThreat: true,
79
- blockThreshold: 'medium',
80
- logging: true,
81
- modules: ['scanner', 'pii', 'dlp', 'circuitBreaker', 'canary', 'conversation'],
82
- circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
83
- rateLimiter: { maxRequests: 100, windowMs: 60000 },
84
- pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address', 'name'] },
85
- dlp: { rules: [
86
- { name: 'account_number', pattern: 'ACCT-\\d{8,}', action: 'redact', replacement: '[ACCOUNT]' },
87
- { name: 'internal_id', pattern: 'INT-\\d{6}', action: 'redact', replacement: '[INTERNAL ID]' }
88
- ]},
89
- conversation: { fragmentationDetection: true, languageSwitchDetection: true }
90
- }
91
- },
92
-
93
- internal_tool: {
94
- name: 'Internal Tool',
95
- description: 'Internal-facing AI tool. Lighter security, focus on preventing accidents.',
96
- config: {
97
- sensitivity: 'medium',
98
- blockOnThreat: false,
99
- blockThreshold: 'critical',
100
- logging: true,
101
- modules: ['scanner', 'toolGuard'],
102
- circuitBreaker: { threshold: 20, windowMs: 60000, cooldownMs: 60000 },
103
- permissions: {
104
- allowedTools: ['search', 'readFile', 'writeFile', 'calculator', 'database'],
105
- blockedTools: ['bash', 'shell', 'exec', 'eval']
106
- }
107
- }
108
- },
109
-
110
- multi_agent: {
111
- name: 'Multi-Agent System',
112
- description: 'Multiple agents communicating. Agent firewall + delegation chains.',
113
- config: {
114
- sensitivity: 'high',
115
- blockOnThreat: true,
116
- blockThreshold: 'high',
117
- logging: true,
118
- modules: ['scanner', 'multiAgent', 'toolGuard', 'circuitBreaker', 'canary'],
119
- circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
120
- agentFirewall: { trustedAgents: [], scanAllMessages: true },
121
- delegationChain: { maxDepth: 5, requireApproval: false },
122
- toolSequenceAnalysis: true
123
- }
124
- },
125
-
126
- high_security: {
127
- name: 'High Security',
128
- description: 'Maximum protection. All modules enabled. For regulated industries.',
129
- config: {
130
- sensitivity: 'high',
131
- blockOnThreat: true,
132
- blockThreshold: 'medium',
133
- logging: true,
134
- modules: ['scanner', 'pii', 'dlp', 'canary', 'toolGuard', 'circuitBreaker', 'conversation', 'encoding', 'multiAgent', 'watermark'],
135
- circuitBreaker: { threshold: 3, windowMs: 60000, cooldownMs: 600000 },
136
- rateLimiter: { maxRequests: 50, windowMs: 60000, maxThreatsPerWindow: 3 },
137
- pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address', 'name', 'dob'] },
138
- permissions: {
139
- allowedTools: [],
140
- blockedTools: ['bash', 'shell', 'exec', 'eval', 'http_request']
141
- },
142
- conversation: { fragmentationDetection: true, languageSwitchDetection: true, behavioralFingerprinting: true },
143
- encoding: { detectBase64: true, detectHex: true, detectSteganography: true },
144
- watermark: { enabled: true },
145
- cache: { enabled: true, maxSize: 1000, ttlMs: 60000 }
146
- }
147
- },
148
-
149
- minimal: {
150
- name: 'Minimal',
151
- description: 'Bare minimum protection. Just injection scanning with low overhead.',
152
- config: {
153
- sensitivity: 'medium',
154
- blockOnThreat: false,
155
- blockThreshold: 'critical',
156
- logging: false,
157
- modules: ['scanner'],
158
- cache: { enabled: true, maxSize: 200, ttlMs: 10000 }
159
- }
160
- }
161
- };
162
-
163
- // =========================================================================
164
- // Config Builder
165
- // =========================================================================
166
-
167
- class ConfigBuilder {
168
- constructor() {
169
- this.config = {
170
- sensitivity: 'high',
171
- blockOnThreat: true,
172
- blockThreshold: 'high',
173
- logging: true,
174
- modules: ['scanner']
175
- };
176
- }
177
-
178
- /**
179
- * Start from a preset.
180
- */
181
- fromPreset(presetName) {
182
- const preset = PRESETS[presetName];
183
- if (!preset) throw new Error(`Unknown preset: ${presetName}. Available: ${Object.keys(PRESETS).join(', ')}`);
184
- this.config = JSON.parse(JSON.stringify(preset.config));
185
- return this;
186
- }
187
-
188
- sensitivity(level) { this.config.sensitivity = level; return this; }
189
- blockOnThreat(enabled) { this.config.blockOnThreat = enabled; return this; }
190
- blockThreshold(level) { this.config.blockThreshold = level; return this; }
191
- logging(enabled) { this.config.logging = enabled; return this; }
192
-
193
- enableModule(mod) {
194
- if (!this.config.modules.includes(mod)) this.config.modules.push(mod);
195
- return this;
196
- }
197
-
198
- disableModule(mod) {
199
- this.config.modules = this.config.modules.filter(m => m !== mod);
200
- return this;
201
- }
202
-
203
- circuitBreaker(opts) { this.config.circuitBreaker = opts; return this; }
204
- rateLimiter(opts) { this.config.rateLimiter = opts; return this; }
205
- pii(opts) { this.config.pii = opts; return this; }
206
- dlp(opts) { this.config.dlp = opts; return this; }
207
-
208
- permissions(opts) { this.config.permissions = opts; return this; }
209
- cache(opts) { this.config.cache = opts; return this; }
210
-
211
- /**
212
- * Build the config object.
213
- */
214
- build() {
215
- return JSON.parse(JSON.stringify(this.config));
216
- }
217
-
218
- /**
219
- * Build and export as JSON string.
220
- */
221
- toJSON() {
222
- return JSON.stringify(this.config, null, 2);
223
- }
224
- }
225
-
226
- // =========================================================================
227
- // Code Snippet Generator
228
- // =========================================================================
229
-
230
- class SnippetGenerator {
231
- /**
232
- * Generate setup code for a given preset/config.
233
- */
234
- static generate(presetOrConfig, framework = 'node') {
235
- const config = typeof presetOrConfig === 'string'
236
- ? (PRESETS[presetOrConfig] ? PRESETS[presetOrConfig].config : null)
237
- : presetOrConfig;
238
-
239
- if (!config) return null;
240
-
241
- switch (framework) {
242
- case 'node': return SnippetGenerator.nodeSnippet(config);
243
- case 'express': return SnippetGenerator.expressSnippet(config);
244
- case 'langchain': return SnippetGenerator.langchainSnippet(config);
245
- case 'anthropic': return SnippetGenerator.anthropicSnippet(config);
246
- case 'openai': return SnippetGenerator.openaiSnippet(config);
247
- case 'vercel': return SnippetGenerator.vercelSnippet(config);
248
- default: return SnippetGenerator.nodeSnippet(config);
249
- }
250
- }
251
-
252
- static nodeSnippet(config) {
253
- const lines = [];
254
- lines.push(`const { AgentShield } = require('agent-shield');`);
255
-
256
- if (config.modules?.includes('pii')) lines.push(`const { PIIRedactor } = require('agent-shield/src/pii');`);
257
- if (config.modules?.includes('circuitBreaker')) lines.push(`const { CircuitBreaker } = require('agent-shield/src/circuit-breaker');`);
258
- if (config.modules?.includes('canary')) lines.push(`const { CanaryTokens } = require('agent-shield/src/canary');`);
259
- if (config.modules?.includes('toolGuard')) lines.push(`const { PermissionBoundary, ToolSequenceAnalyzer } = require('agent-shield/src/tool-guard');`);
260
-
261
- lines.push('');
262
- lines.push(`const shield = new AgentShield({`);
263
- lines.push(` sensitivity: '${config.sensitivity || 'high'}',`);
264
- lines.push(` blockOnThreat: ${config.blockOnThreat !== false},`);
265
- lines.push(` blockThreshold: '${config.blockThreshold || 'high'}'`);
266
- lines.push(`});`);
267
-
268
- if (config.circuitBreaker) {
269
- lines.push('');
270
- lines.push(`const breaker = new CircuitBreaker(${JSON.stringify(config.circuitBreaker)});`);
271
- }
272
-
273
- if (config.pii) {
274
- lines.push('');
275
- lines.push(`const pii = new PIIRedactor(${JSON.stringify(config.pii)});`);
276
- }
277
-
278
- lines.push('');
279
- lines.push(`// Scan user input`);
280
- lines.push(`const result = shield.scanInput(userMessage);`);
281
- lines.push(`if (result.blocked) {`);
282
- lines.push(` console.log('Blocked:', result.threats);`);
283
- lines.push(`}`);
284
-
285
- return lines.join('\n');
286
- }
287
-
288
- static expressSnippet(config) {
289
- return `const { expressMiddleware } = require('agent-shield/src/middleware');
290
-
291
- app.use('/api/agent', expressMiddleware({
292
- sensitivity: '${config.sensitivity || 'high'}',
293
- blockOnThreat: ${config.blockOnThreat !== false},
294
- blockThreshold: '${config.blockThreshold || 'high'}'
295
- }));`;
296
- }
297
-
298
- static langchainSnippet(config) {
299
- return `const { ShieldCallbackHandler } = require('agent-shield/src/integrations');
300
-
301
- const shieldHandler = new ShieldCallbackHandler({
302
- sensitivity: '${config.sensitivity || 'high'}',
303
- blockOnThreat: ${config.blockOnThreat !== false},
304
- onThreat: (info) => console.log('Threat detected:', info)
305
- });
306
-
307
- const chain = new LLMChain({
308
- llm,
309
- prompt,
310
- callbacks: [shieldHandler]
311
- });`;
312
- }
313
-
314
- static anthropicSnippet(config) {
315
- return `const Anthropic = require('@anthropic-ai/sdk');
316
- const { shieldAnthropicClient } = require('agent-shield/src/integrations');
317
-
318
- const client = shieldAnthropicClient(new Anthropic(), {
319
- sensitivity: '${config.sensitivity || 'high'}',
320
- blockOnThreat: ${config.blockOnThreat !== false},
321
- pii: ${!!config.pii},
322
- onThreat: (info) => console.log('Threat:', info)
323
- });
324
-
325
- // Use client normally — all messages are scanned automatically
326
- const msg = await client.messages.create({
327
- model: 'claude-sonnet-4-20250514',
328
- messages: [{ role: 'user', content: userInput }]
329
- });`;
330
- }
331
-
332
- static openaiSnippet(config) {
333
- return `const OpenAI = require('openai');
334
- const { shieldOpenAIClient } = require('agent-shield/src/integrations');
335
-
336
- const client = shieldOpenAIClient(new OpenAI(), {
337
- sensitivity: '${config.sensitivity || 'high'}',
338
- blockOnThreat: ${config.blockOnThreat !== false},
339
- onThreat: (info) => console.log('Threat:', info)
340
- });
341
-
342
- // Use client normally — all messages are scanned automatically
343
- const completion = await client.chat.completions.create({
344
- model: 'gpt-4',
345
- messages: [{ role: 'user', content: userInput }]
346
- });`;
347
- }
348
-
349
- static vercelSnippet(config) {
350
- return `const { shieldVercelAI } = require('agent-shield/src/integrations');
351
-
352
- const shieldMiddleware = shieldVercelAI({
353
- sensitivity: '${config.sensitivity || 'high'}',
354
- blockOnThreat: ${config.blockOnThreat !== false},
355
- onThreat: (info) => console.log('Threat:', info)
356
- });
357
-
358
- const result = await generateText({
359
- model,
360
- prompt: userInput,
361
- experimental_middleware: shieldMiddleware
362
- });`;
363
- }
364
-
365
- /**
366
- * Get all available frameworks.
367
- */
368
- static getFrameworks() {
369
- return [
370
- { id: 'node', name: 'Node.js', description: 'Direct Node.js usage' },
371
- { id: 'express', name: 'Express.js', description: 'Express middleware' },
372
- { id: 'langchain', name: 'LangChain', description: 'LangChain callback handler' },
373
- { id: 'anthropic', name: 'Anthropic SDK', description: 'Claude API wrapper' },
374
- { id: 'openai', name: 'OpenAI SDK', description: 'OpenAI API wrapper' },
375
- { id: 'vercel', name: 'Vercel AI SDK', description: 'Vercel AI middleware' }
376
- ];
377
- }
378
- }
379
-
380
- // =========================================================================
381
- // Preset Helpers
382
- // =========================================================================
383
-
384
- /**
385
- * Get all available presets.
386
- */
387
- function getPresets() {
388
- return Object.entries(PRESETS).map(([key, val]) => ({
389
- key,
390
- name: val.name,
391
- description: val.description,
392
- modules: val.config.modules
393
- }));
394
- }
395
-
396
- /**
397
- * Get a specific preset config.
398
- */
399
- function getPreset(name) {
400
- return PRESETS[name] || null;
401
- }
402
-
403
- module.exports = {
404
- PRESETS,
405
- ConfigBuilder,
406
- SnippetGenerator,
407
- getPresets,
408
- getPreset
409
- };
1
+ 'use strict';
2
+
3
+ /**
4
+ * Agent Shield — Preset Profiles, Config Builder & Copy-Paste Snippets
5
+ *
6
+ * Pre-built configurations for common use cases.
7
+ * Users pick a preset and get sensible defaults + ready-to-use code.
8
+ */
9
+
10
+ // =========================================================================
11
+ // Preset Profiles
12
+ // =========================================================================
13
+
14
+ const PRESETS = {
15
+ chatbot: {
16
+ name: 'Chatbot',
17
+ description: 'Customer-facing chatbot with moderate security. Balances safety with user experience.',
18
+ config: {
19
+ sensitivity: 'high',
20
+ blockOnThreat: true,
21
+ blockThreshold: 'high',
22
+ logging: true,
23
+ modules: ['scanner', 'pii', 'circuitBreaker'],
24
+ circuitBreaker: { threshold: 10, windowMs: 60000, cooldownMs: 120000 },
25
+ rateLimiter: { maxRequests: 200, windowMs: 60000 },
26
+ pii: { categories: ['email', 'ssn', 'credit_card', 'phone'] },
27
+ permissions: { allowedTools: [], blockedTools: ['bash', 'shell', 'exec'] },
28
+ cache: { enabled: true, maxSize: 500, ttlMs: 30000 }
29
+ }
30
+ },
31
+
32
+ coding_agent: {
33
+ name: 'Coding Agent',
34
+ description: 'AI coding assistant with file/shell access. Strict tool boundaries.',
35
+ config: {
36
+ sensitivity: 'high',
37
+ blockOnThreat: true,
38
+ blockThreshold: 'high',
39
+ logging: true,
40
+ modules: ['scanner', 'toolGuard', 'circuitBreaker', 'canary'],
41
+ circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
42
+ permissions: {
43
+ allowedTools: ['readFile', 'writeFile', 'search', 'bash'],
44
+ blockedTools: ['eval'],
45
+ tools: {
46
+ readFile: { blockPaths: ['/etc/', '/root/', '/home/*/.ssh/'], maxCallsPerMinute: 60 },
47
+ writeFile: { blockPaths: ['/etc/', '/usr/', '/bin/'], blockArgs: ['.env', 'credentials'], maxCallsPerMinute: 30 },
48
+ bash: { blockArgs: ['curl|bash', 'wget|sh', 'rm -rf', 'chmod 777'], maxCallsPerMinute: 20 }
49
+ }
50
+ },
51
+ toolSequenceAnalysis: true
52
+ }
53
+ },
54
+
55
+ rag_pipeline: {
56
+ name: 'RAG Pipeline',
57
+ description: 'Retrieval-augmented generation. Scans retrieved documents for indirect injection.',
58
+ config: {
59
+ sensitivity: 'high',
60
+ blockOnThreat: true,
61
+ blockThreshold: 'medium',
62
+ logging: true,
63
+ modules: ['scanner', 'encoding', 'pii', 'dlp', 'circuitBreaker'],
64
+ circuitBreaker: { threshold: 8, windowMs: 60000, cooldownMs: 180000 },
65
+ pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address'] },
66
+ dlp: { rules: [] },
67
+ scanRetrievedContent: true,
68
+ encoding: { detectBase64: true, detectHex: true, detectSteganography: true },
69
+ cache: { enabled: true, maxSize: 2000, ttlMs: 300000 }
70
+ }
71
+ },
72
+
73
+ customer_support: {
74
+ name: 'Customer Support Bot',
75
+ description: 'Handles sensitive customer data. Strong PII protection and DLP.',
76
+ config: {
77
+ sensitivity: 'high',
78
+ blockOnThreat: true,
79
+ blockThreshold: 'medium',
80
+ logging: true,
81
+ modules: ['scanner', 'pii', 'dlp', 'circuitBreaker', 'canary', 'conversation'],
82
+ circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
83
+ rateLimiter: { maxRequests: 100, windowMs: 60000 },
84
+ pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address', 'name'] },
85
+ dlp: { rules: [
86
+ { name: 'account_number', pattern: 'ACCT-\\d{8,}', action: 'redact', replacement: '[ACCOUNT]' },
87
+ { name: 'internal_id', pattern: 'INT-\\d{6}', action: 'redact', replacement: '[INTERNAL ID]' }
88
+ ]},
89
+ conversation: { fragmentationDetection: true, languageSwitchDetection: true }
90
+ }
91
+ },
92
+
93
+ internal_tool: {
94
+ name: 'Internal Tool',
95
+ description: 'Internal-facing AI tool. Lighter security, focus on preventing accidents.',
96
+ config: {
97
+ sensitivity: 'medium',
98
+ blockOnThreat: false,
99
+ blockThreshold: 'critical',
100
+ logging: true,
101
+ modules: ['scanner', 'toolGuard'],
102
+ circuitBreaker: { threshold: 20, windowMs: 60000, cooldownMs: 60000 },
103
+ permissions: {
104
+ allowedTools: ['search', 'readFile', 'writeFile', 'calculator', 'database'],
105
+ blockedTools: ['bash', 'shell', 'exec', 'eval']
106
+ }
107
+ }
108
+ },
109
+
110
+ multi_agent: {
111
+ name: 'Multi-Agent System',
112
+ description: 'Multiple agents communicating. Agent firewall + delegation chains.',
113
+ config: {
114
+ sensitivity: 'high',
115
+ blockOnThreat: true,
116
+ blockThreshold: 'high',
117
+ logging: true,
118
+ modules: ['scanner', 'multiAgent', 'toolGuard', 'circuitBreaker', 'canary'],
119
+ circuitBreaker: { threshold: 5, windowMs: 60000, cooldownMs: 300000 },
120
+ agentFirewall: { trustedAgents: [], scanAllMessages: true },
121
+ delegationChain: { maxDepth: 5, requireApproval: false },
122
+ toolSequenceAnalysis: true
123
+ }
124
+ },
125
+
126
+ high_security: {
127
+ name: 'High Security',
128
+ description: 'Maximum protection. All modules enabled. For regulated industries.',
129
+ config: {
130
+ sensitivity: 'high',
131
+ blockOnThreat: true,
132
+ blockThreshold: 'medium',
133
+ logging: true,
134
+ modules: ['scanner', 'pii', 'dlp', 'canary', 'toolGuard', 'circuitBreaker', 'conversation', 'encoding', 'multiAgent', 'watermark'],
135
+ circuitBreaker: { threshold: 3, windowMs: 60000, cooldownMs: 600000 },
136
+ rateLimiter: { maxRequests: 50, windowMs: 60000, maxThreatsPerWindow: 3 },
137
+ pii: { categories: ['email', 'ssn', 'credit_card', 'phone', 'address', 'name', 'dob'] },
138
+ permissions: {
139
+ allowedTools: [],
140
+ blockedTools: ['bash', 'shell', 'exec', 'eval', 'http_request']
141
+ },
142
+ conversation: { fragmentationDetection: true, languageSwitchDetection: true, behavioralFingerprinting: true },
143
+ encoding: { detectBase64: true, detectHex: true, detectSteganography: true },
144
+ watermark: { enabled: true },
145
+ cache: { enabled: true, maxSize: 1000, ttlMs: 60000 }
146
+ }
147
+ },
148
+
149
+ minimal: {
150
+ name: 'Minimal',
151
+ description: 'Bare minimum protection. Just injection scanning with low overhead.',
152
+ config: {
153
+ sensitivity: 'medium',
154
+ blockOnThreat: false,
155
+ blockThreshold: 'critical',
156
+ logging: false,
157
+ modules: ['scanner'],
158
+ cache: { enabled: true, maxSize: 200, ttlMs: 10000 }
159
+ }
160
+ }
161
+ };
162
+
163
+ // =========================================================================
164
+ // Config Builder
165
+ // =========================================================================
166
+
167
+ class ConfigBuilder {
168
+ constructor() {
169
+ this.config = {
170
+ sensitivity: 'high',
171
+ blockOnThreat: true,
172
+ blockThreshold: 'high',
173
+ logging: true,
174
+ modules: ['scanner']
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Start from a preset.
180
+ */
181
+ fromPreset(presetName) {
182
+ const preset = PRESETS[presetName];
183
+ if (!preset) throw new Error(`Unknown preset: ${presetName}. Available: ${Object.keys(PRESETS).join(', ')}`);
184
+ this.config = JSON.parse(JSON.stringify(preset.config));
185
+ return this;
186
+ }
187
+
188
+ sensitivity(level) { this.config.sensitivity = level; return this; }
189
+ blockOnThreat(enabled) { this.config.blockOnThreat = enabled; return this; }
190
+ blockThreshold(level) { this.config.blockThreshold = level; return this; }
191
+ logging(enabled) { this.config.logging = enabled; return this; }
192
+
193
+ enableModule(mod) {
194
+ if (!this.config.modules.includes(mod)) this.config.modules.push(mod);
195
+ return this;
196
+ }
197
+
198
+ disableModule(mod) {
199
+ this.config.modules = this.config.modules.filter(m => m !== mod);
200
+ return this;
201
+ }
202
+
203
+ circuitBreaker(opts) { this.config.circuitBreaker = opts; return this; }
204
+ rateLimiter(opts) { this.config.rateLimiter = opts; return this; }
205
+ pii(opts) { this.config.pii = opts; return this; }
206
+ dlp(opts) { this.config.dlp = opts; return this; }
207
+
208
+ permissions(opts) { this.config.permissions = opts; return this; }
209
+ cache(opts) { this.config.cache = opts; return this; }
210
+
211
+ /**
212
+ * Build the config object.
213
+ */
214
+ build() {
215
+ return JSON.parse(JSON.stringify(this.config));
216
+ }
217
+
218
+ /**
219
+ * Build and export as JSON string.
220
+ */
221
+ toJSON() {
222
+ return JSON.stringify(this.config, null, 2);
223
+ }
224
+ }
225
+
226
+ // =========================================================================
227
+ // Code Snippet Generator
228
+ // =========================================================================
229
+
230
+ class SnippetGenerator {
231
+ /**
232
+ * Generate setup code for a given preset/config.
233
+ */
234
+ static generate(presetOrConfig, framework = 'node') {
235
+ const config = typeof presetOrConfig === 'string'
236
+ ? (PRESETS[presetOrConfig] ? PRESETS[presetOrConfig].config : null)
237
+ : presetOrConfig;
238
+
239
+ if (!config) return null;
240
+
241
+ switch (framework) {
242
+ case 'node': return SnippetGenerator.nodeSnippet(config);
243
+ case 'express': return SnippetGenerator.expressSnippet(config);
244
+ case 'langchain': return SnippetGenerator.langchainSnippet(config);
245
+ case 'anthropic': return SnippetGenerator.anthropicSnippet(config);
246
+ case 'openai': return SnippetGenerator.openaiSnippet(config);
247
+ case 'vercel': return SnippetGenerator.vercelSnippet(config);
248
+ default: return SnippetGenerator.nodeSnippet(config);
249
+ }
250
+ }
251
+
252
+ static nodeSnippet(config) {
253
+ const lines = [];
254
+ lines.push(`const { AgentShield } = require('agentshield-sdk');`);
255
+
256
+ if (config.modules?.includes('pii')) lines.push(`const { PIIRedactor } = require('agentshield-sdk/src/pii');`);
257
+ if (config.modules?.includes('circuitBreaker')) lines.push(`const { CircuitBreaker } = require('agentshield-sdk/src/circuit-breaker');`);
258
+ if (config.modules?.includes('canary')) lines.push(`const { CanaryTokens } = require('agentshield-sdk/src/canary');`);
259
+ if (config.modules?.includes('toolGuard')) lines.push(`const { PermissionBoundary, ToolSequenceAnalyzer } = require('agentshield-sdk/src/tool-guard');`);
260
+
261
+ lines.push('');
262
+ lines.push(`const shield = new AgentShield({`);
263
+ lines.push(` sensitivity: '${config.sensitivity || 'high'}',`);
264
+ lines.push(` blockOnThreat: ${config.blockOnThreat !== false},`);
265
+ lines.push(` blockThreshold: '${config.blockThreshold || 'high'}'`);
266
+ lines.push(`});`);
267
+
268
+ if (config.circuitBreaker) {
269
+ lines.push('');
270
+ lines.push(`const breaker = new CircuitBreaker(${JSON.stringify(config.circuitBreaker)});`);
271
+ }
272
+
273
+ if (config.pii) {
274
+ lines.push('');
275
+ lines.push(`const pii = new PIIRedactor(${JSON.stringify(config.pii)});`);
276
+ }
277
+
278
+ lines.push('');
279
+ lines.push(`// Scan user input`);
280
+ lines.push(`const result = shield.scanInput(userMessage);`);
281
+ lines.push(`if (result.blocked) {`);
282
+ lines.push(` console.log('Blocked:', result.threats);`);
283
+ lines.push(`}`);
284
+
285
+ return lines.join('\n');
286
+ }
287
+
288
+ static expressSnippet(config) {
289
+ return `const { expressMiddleware } = require('agentshield-sdk/src/middleware');
290
+
291
+ app.use('/api/agent', expressMiddleware({
292
+ sensitivity: '${config.sensitivity || 'high'}',
293
+ blockOnThreat: ${config.blockOnThreat !== false},
294
+ blockThreshold: '${config.blockThreshold || 'high'}'
295
+ }));`;
296
+ }
297
+
298
+ static langchainSnippet(config) {
299
+ return `const { ShieldCallbackHandler } = require('agentshield-sdk/src/integrations');
300
+
301
+ const shieldHandler = new ShieldCallbackHandler({
302
+ sensitivity: '${config.sensitivity || 'high'}',
303
+ blockOnThreat: ${config.blockOnThreat !== false},
304
+ onThreat: (info) => console.log('Threat detected:', info)
305
+ });
306
+
307
+ const chain = new LLMChain({
308
+ llm,
309
+ prompt,
310
+ callbacks: [shieldHandler]
311
+ });`;
312
+ }
313
+
314
+ static anthropicSnippet(config) {
315
+ return `const Anthropic = require('@anthropic-ai/sdk');
316
+ const { shieldAnthropicClient } = require('agentshield-sdk/src/integrations');
317
+
318
+ const client = shieldAnthropicClient(new Anthropic(), {
319
+ sensitivity: '${config.sensitivity || 'high'}',
320
+ blockOnThreat: ${config.blockOnThreat !== false},
321
+ pii: ${!!config.pii},
322
+ onThreat: (info) => console.log('Threat:', info)
323
+ });
324
+
325
+ // Use client normally — all messages are scanned automatically
326
+ const msg = await client.messages.create({
327
+ model: 'claude-sonnet-4-20250514',
328
+ messages: [{ role: 'user', content: userInput }]
329
+ });`;
330
+ }
331
+
332
+ static openaiSnippet(config) {
333
+ return `const OpenAI = require('openai');
334
+ const { shieldOpenAIClient } = require('agentshield-sdk/src/integrations');
335
+
336
+ const client = shieldOpenAIClient(new OpenAI(), {
337
+ sensitivity: '${config.sensitivity || 'high'}',
338
+ blockOnThreat: ${config.blockOnThreat !== false},
339
+ onThreat: (info) => console.log('Threat:', info)
340
+ });
341
+
342
+ // Use client normally — all messages are scanned automatically
343
+ const completion = await client.chat.completions.create({
344
+ model: 'gpt-4',
345
+ messages: [{ role: 'user', content: userInput }]
346
+ });`;
347
+ }
348
+
349
+ static vercelSnippet(config) {
350
+ return `const { shieldVercelAI } = require('agentshield-sdk/src/integrations');
351
+
352
+ const shieldMiddleware = shieldVercelAI({
353
+ sensitivity: '${config.sensitivity || 'high'}',
354
+ blockOnThreat: ${config.blockOnThreat !== false},
355
+ onThreat: (info) => console.log('Threat:', info)
356
+ });
357
+
358
+ const result = await generateText({
359
+ model,
360
+ prompt: userInput,
361
+ experimental_middleware: shieldMiddleware
362
+ });`;
363
+ }
364
+
365
+ /**
366
+ * Get all available frameworks.
367
+ */
368
+ static getFrameworks() {
369
+ return [
370
+ { id: 'node', name: 'Node.js', description: 'Direct Node.js usage' },
371
+ { id: 'express', name: 'Express.js', description: 'Express middleware' },
372
+ { id: 'langchain', name: 'LangChain', description: 'LangChain callback handler' },
373
+ { id: 'anthropic', name: 'Anthropic SDK', description: 'Claude API wrapper' },
374
+ { id: 'openai', name: 'OpenAI SDK', description: 'OpenAI API wrapper' },
375
+ { id: 'vercel', name: 'Vercel AI SDK', description: 'Vercel AI middleware' }
376
+ ];
377
+ }
378
+ }
379
+
380
+ // =========================================================================
381
+ // Preset Helpers
382
+ // =========================================================================
383
+
384
+ /**
385
+ * Get all available presets.
386
+ */
387
+ function getPresets() {
388
+ return Object.entries(PRESETS).map(([key, val]) => ({
389
+ key,
390
+ name: val.name,
391
+ description: val.description,
392
+ modules: val.config.modules
393
+ }));
394
+ }
395
+
396
+ /**
397
+ * Get a specific preset config.
398
+ */
399
+ function getPreset(name) {
400
+ return PRESETS[name] || null;
401
+ }
402
+
403
+ module.exports = {
404
+ PRESETS,
405
+ ConfigBuilder,
406
+ SnippetGenerator,
407
+ getPresets,
408
+ getPreset
409
+ };