agentshield-sdk 7.0.0 → 7.2.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/CHANGELOG.md +28 -0
- package/README.md +43 -9
- package/package.json +4 -2
- package/src/adaptive-defense.js +942 -0
- package/src/ipia-detector.js +821 -0
- package/src/main.js +24 -0
- package/src/mcp-security-runtime.js +149 -5
- package/types/index.d.ts +69 -0
package/src/main.js
CHANGED
|
@@ -59,6 +59,9 @@ const { ERROR_CODES, createShieldError, deprecationWarning } = safeRequire('./er
|
|
|
59
59
|
// v7.0 — MCP Security Runtime
|
|
60
60
|
const { MCPSecurityRuntime, MCPSessionStateMachine, SESSION_STATES } = safeRequire('./mcp-security-runtime', 'mcp-security-runtime');
|
|
61
61
|
|
|
62
|
+
// v7.0 — Adaptive Defense
|
|
63
|
+
const { LearningLoop, AgentContract: BehaviorContract, ContractRegistry, ComplianceAttestor, ATTESTATION_FRAMEWORKS } = safeRequire('./adaptive-defense', 'adaptive-defense');
|
|
64
|
+
|
|
62
65
|
// v7.0 — MCP SDK Integration
|
|
63
66
|
const { shieldMCPServer, createMCPSecurityLayer } = safeRequire('./mcp-sdk-integration', 'mcp-sdk-integration');
|
|
64
67
|
|
|
@@ -167,6 +170,9 @@ const { AdaptiveDetector, SemanticAnalysisHook, CommunityPatterns } = safeRequir
|
|
|
167
170
|
// OpenClaw
|
|
168
171
|
const { OpenClawShieldSkill, shieldOpenClawMessages, generateOpenClawSkill } = safeRequire('./openclaw', 'openclaw');
|
|
169
172
|
|
|
173
|
+
// v7.2 — IPIA Detector
|
|
174
|
+
const { IPIADetector, ContextConstructor, FeatureExtractor, TreeClassifier, ExternalEmbedder, createIPIAScanner, ipiaMiddleware, FEATURE_NAMES: IPIA_FEATURE_NAMES, INJECTION_LEXICON: IPIA_INJECTION_LEXICON } = safeRequire('./ipia-detector', 'ipia-detector');
|
|
175
|
+
|
|
170
176
|
// --- v1.2 Modules ---
|
|
171
177
|
|
|
172
178
|
// Semantic Detection
|
|
@@ -713,6 +719,13 @@ const _exports = {
|
|
|
713
719
|
IntentValidator,
|
|
714
720
|
ConfusedDeputyGuard,
|
|
715
721
|
|
|
722
|
+
// v7.0 — Adaptive Defense
|
|
723
|
+
LearningLoop,
|
|
724
|
+
BehaviorContract,
|
|
725
|
+
ContractRegistry,
|
|
726
|
+
ComplianceAttestor,
|
|
727
|
+
ATTESTATION_FRAMEWORKS,
|
|
728
|
+
|
|
716
729
|
// v7.0 — MCP SDK Integration
|
|
717
730
|
shieldMCPServer,
|
|
718
731
|
createMCPSecurityLayer,
|
|
@@ -729,6 +742,17 @@ const _exports = {
|
|
|
729
742
|
MCP_THREAT_CATEGORIES: CERT_THREAT_CATEGORIES,
|
|
730
743
|
CERTIFICATION_REQUIREMENTS,
|
|
731
744
|
CERTIFICATION_LEVELS,
|
|
745
|
+
|
|
746
|
+
// v7.2 — IPIA Detector
|
|
747
|
+
IPIADetector,
|
|
748
|
+
ContextConstructor,
|
|
749
|
+
FeatureExtractor,
|
|
750
|
+
TreeClassifier,
|
|
751
|
+
ExternalEmbedder,
|
|
752
|
+
createIPIAScanner,
|
|
753
|
+
ipiaMiddleware,
|
|
754
|
+
IPIA_FEATURE_NAMES,
|
|
755
|
+
IPIA_INJECTION_LEXICON,
|
|
732
756
|
};
|
|
733
757
|
|
|
734
758
|
// Filter out undefined exports (from modules that failed to load)
|
|
@@ -26,6 +26,7 @@ const crypto = require('crypto');
|
|
|
26
26
|
const { MCPBridge, MCPSessionGuard, MCPResourceScanner, MCPToolPolicy } = require('./mcp-bridge');
|
|
27
27
|
const { AuthorizationContext, ConfusedDeputyGuard } = require('./confused-deputy');
|
|
28
28
|
const { BehaviorProfile } = require('./behavior-profiling');
|
|
29
|
+
const { LearningLoop, ContractRegistry, ComplianceAttestor } = require('./adaptive-defense');
|
|
29
30
|
|
|
30
31
|
const LOG_PREFIX = '[Agent Shield]';
|
|
31
32
|
|
|
@@ -142,6 +143,19 @@ class MCPSecurityRuntime {
|
|
|
142
143
|
this._userSessions = new Map(); // userId → Set<sessionId>
|
|
143
144
|
this._behaviorProfiles = new Map(); // userId → BehaviorProfile
|
|
144
145
|
|
|
146
|
+
// Adaptive defense systems
|
|
147
|
+
this._learningLoop = new LearningLoop({
|
|
148
|
+
minHitsToPromote: options.minHitsToPromote || 3,
|
|
149
|
+
maxLearnedPatterns: options.maxLearnedPatterns || 500,
|
|
150
|
+
onPatternLearned: options.onPatternLearned || null
|
|
151
|
+
});
|
|
152
|
+
this._contracts = new ContractRegistry();
|
|
153
|
+
this._attestor = new ComplianceAttestor({
|
|
154
|
+
frameworks: options.complianceFrameworks,
|
|
155
|
+
driftThreshold: options.complianceDriftThreshold || 0.9,
|
|
156
|
+
onComplianceDrift: options.onComplianceDrift || null
|
|
157
|
+
});
|
|
158
|
+
|
|
145
159
|
// Callbacks
|
|
146
160
|
this._onThreat = options.onThreat || null;
|
|
147
161
|
this._onBlock = options.onBlock || null;
|
|
@@ -159,7 +173,9 @@ class MCPSecurityRuntime {
|
|
|
159
173
|
threatsDetected: 0,
|
|
160
174
|
authFailures: 0,
|
|
161
175
|
behaviorAnomalies: 0,
|
|
162
|
-
stateViolations: 0
|
|
176
|
+
stateViolations: 0,
|
|
177
|
+
patternsLearned: 0,
|
|
178
|
+
contractViolations: 0
|
|
163
179
|
};
|
|
164
180
|
|
|
165
181
|
// Cleanup expired sessions periodically
|
|
@@ -357,11 +373,44 @@ class MCPSecurityRuntime {
|
|
|
357
373
|
// 6. Threat scanning (injection, exfiltration, etc.)
|
|
358
374
|
const scanResult = this._bridge.wrapToolCall(toolName, args);
|
|
359
375
|
const threats = scanResult.threats || [];
|
|
360
|
-
|
|
376
|
+
|
|
377
|
+
// 6a. Check against learned patterns (self-learning loop)
|
|
378
|
+
const learnedCheck = this._learningLoop.check(typeof args === 'string' ? args : JSON.stringify(args || {}));
|
|
379
|
+
if (learnedCheck.matches.length > 0) {
|
|
380
|
+
for (const match of learnedCheck.matches) {
|
|
381
|
+
threats.push({
|
|
382
|
+
category: match.category,
|
|
383
|
+
severity: 'high',
|
|
384
|
+
confidence: match.confidence,
|
|
385
|
+
description: `Learned pattern match: ${match.patternId}`,
|
|
386
|
+
source: 'learning_loop'
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (!scanResult.allowed || learnedCheck.matches.length > 0) {
|
|
361
392
|
this.stats.toolCallsBlocked++;
|
|
362
393
|
this.stats.threatsDetected += threats.length;
|
|
363
|
-
|
|
394
|
+
|
|
395
|
+
// LEARNING LOOP: Feed blocked attack into the learning system
|
|
396
|
+
for (const threat of threats) {
|
|
397
|
+
this._learningLoop.ingest({
|
|
398
|
+
text: typeof args === 'string' ? args : JSON.stringify(args || {}),
|
|
399
|
+
category: threat.category || 'unknown',
|
|
400
|
+
threats,
|
|
401
|
+
toolName,
|
|
402
|
+
sessionId
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
this.stats.patternsLearned = this._learningLoop.getActivePatterns().length;
|
|
406
|
+
|
|
407
|
+
this._audit('threat_detected', { sessionId, toolName, threats, learnedMatches: learnedCheck.matches.length });
|
|
364
408
|
if (this._onThreat) this._onThreat({ sessionId, toolName, threats });
|
|
409
|
+
|
|
410
|
+
// Update compliance signals
|
|
411
|
+
this._attestor.updateSignal('threat_scanning_active', true);
|
|
412
|
+
this._attestor.updateSignal('blocking_enabled', true);
|
|
413
|
+
|
|
365
414
|
return {
|
|
366
415
|
allowed: false,
|
|
367
416
|
threats,
|
|
@@ -372,7 +421,31 @@ class MCPSecurityRuntime {
|
|
|
372
421
|
};
|
|
373
422
|
}
|
|
374
423
|
|
|
375
|
-
// 7.
|
|
424
|
+
// 7. Agent contract enforcement
|
|
425
|
+
const contractResult = this._contracts.enforce(session.authCtx.agentId, {
|
|
426
|
+
type: 'tool_call',
|
|
427
|
+
toolName,
|
|
428
|
+
args,
|
|
429
|
+
intent: session.authCtx.intent,
|
|
430
|
+
delegationDepth: session.authCtx.delegationDepth
|
|
431
|
+
});
|
|
432
|
+
if (!contractResult.allowed) {
|
|
433
|
+
this.stats.contractViolations++;
|
|
434
|
+
this._audit('contract_violation', {
|
|
435
|
+
sessionId, toolName, agentId: session.authCtx.agentId,
|
|
436
|
+
violations: contractResult.violations
|
|
437
|
+
});
|
|
438
|
+
return {
|
|
439
|
+
allowed: false,
|
|
440
|
+
threats: [],
|
|
441
|
+
violations: contractResult.violations,
|
|
442
|
+
anomalies: [],
|
|
443
|
+
token: null,
|
|
444
|
+
reason: 'Contract violation: ' + contractResult.violations.map(v => v.message).join('; ')
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// 8. Behavioral anomaly detection
|
|
376
449
|
const anomalies = [];
|
|
377
450
|
if (this._enableBehavior) {
|
|
378
451
|
const profile = this._behaviorProfiles.get(session.authCtx.userId);
|
|
@@ -395,7 +468,19 @@ class MCPSecurityRuntime {
|
|
|
395
468
|
}
|
|
396
469
|
}
|
|
397
470
|
|
|
398
|
-
//
|
|
471
|
+
// 9. Update compliance attestation signals
|
|
472
|
+
this._attestor.updateSignals({
|
|
473
|
+
injection_scans_active: true,
|
|
474
|
+
tool_authorization_active: this._enforceAuth,
|
|
475
|
+
rate_limiting_active: true,
|
|
476
|
+
threat_scanning_active: true,
|
|
477
|
+
behavior_monitoring_active: this._enableBehavior,
|
|
478
|
+
blocking_enabled: true,
|
|
479
|
+
audit_trail_active: true,
|
|
480
|
+
contract_enforcement_active: contractResult.hasContract
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// 10. Record success and return
|
|
399
484
|
this._audit('tool_allowed', {
|
|
400
485
|
sessionId, toolName, userId: session.authCtx.userId,
|
|
401
486
|
threats: threats.length, anomalies: anomalies.length
|
|
@@ -444,6 +529,61 @@ class MCPSecurityRuntime {
|
|
|
444
529
|
return this._resourceScanner.scanResource(uri, content, mimeType);
|
|
445
530
|
}
|
|
446
531
|
|
|
532
|
+
// =======================================================================
|
|
533
|
+
// Adaptive Defense — Learning, Contracts, Compliance
|
|
534
|
+
// =======================================================================
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Registers a behavioral contract for an agent.
|
|
538
|
+
* The contract is verified on every tool call automatically.
|
|
539
|
+
* @param {import('./adaptive-defense').AgentContract} contract
|
|
540
|
+
*/
|
|
541
|
+
registerContract(contract) {
|
|
542
|
+
this._contracts.register(contract);
|
|
543
|
+
this._attestor.updateSignal('contract_enforcement_active', true);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Returns the learning loop for direct access.
|
|
548
|
+
* @returns {import('./adaptive-defense').LearningLoop}
|
|
549
|
+
*/
|
|
550
|
+
getLearningLoop() {
|
|
551
|
+
return this._learningLoop;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Returns a real-time compliance attestation.
|
|
556
|
+
* @returns {object}
|
|
557
|
+
*/
|
|
558
|
+
attest() {
|
|
559
|
+
return this._attestor.attest();
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Generates a signed compliance proof that can be verified externally.
|
|
564
|
+
* @param {string} signingKey
|
|
565
|
+
* @returns {{ attestation: object, signature: string }}
|
|
566
|
+
*/
|
|
567
|
+
generateComplianceProof(signingKey) {
|
|
568
|
+
return this._attestor.generateProof(signingKey || this._signingKey);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Returns contract compliance rates for all registered agents.
|
|
573
|
+
* @returns {object}
|
|
574
|
+
*/
|
|
575
|
+
getContractCompliance() {
|
|
576
|
+
return this._contracts.getComplianceReport();
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Returns compliance trend direction.
|
|
581
|
+
* @returns {'improving' | 'stable' | 'degrading' | 'unknown'}
|
|
582
|
+
*/
|
|
583
|
+
getComplianceTrend() {
|
|
584
|
+
return this._attestor.getTrend();
|
|
585
|
+
}
|
|
586
|
+
|
|
447
587
|
// =======================================================================
|
|
448
588
|
// Tool Registration
|
|
449
589
|
// =======================================================================
|
|
@@ -639,6 +779,10 @@ class MCPSecurityRuntime {
|
|
|
639
779
|
sessions,
|
|
640
780
|
behaviorProfiles: behaviorSummaries,
|
|
641
781
|
guard: this._guard.getStats(),
|
|
782
|
+
learningLoop: this._learningLoop.getReport(),
|
|
783
|
+
contracts: this._contracts.getComplianceReport(),
|
|
784
|
+
compliance: this._attestor.getCurrentState(),
|
|
785
|
+
complianceTrend: this._attestor.getTrend(),
|
|
642
786
|
recentAudit: this._auditLog.slice(-50)
|
|
643
787
|
};
|
|
644
788
|
}
|
package/types/index.d.ts
CHANGED
|
@@ -2086,3 +2086,72 @@ export declare class ConfusedDeputyGuard {
|
|
|
2086
2086
|
getStats(): any;
|
|
2087
2087
|
getAuditLog(limit?: number): any[];
|
|
2088
2088
|
}
|
|
2089
|
+
|
|
2090
|
+
// =========================================================================
|
|
2091
|
+
// v7.2 — IPIA Detector
|
|
2092
|
+
// =========================================================================
|
|
2093
|
+
|
|
2094
|
+
export interface IPIAResult {
|
|
2095
|
+
isInjection: boolean;
|
|
2096
|
+
confidence: number;
|
|
2097
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
2098
|
+
reason: string;
|
|
2099
|
+
features: Record<string, number>;
|
|
2100
|
+
source: string;
|
|
2101
|
+
metadata: any | null;
|
|
2102
|
+
patternScan: any | null;
|
|
2103
|
+
timestamp: number;
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
export interface EmbeddingBackend {
|
|
2107
|
+
embed(text: string): Promise<number[]>;
|
|
2108
|
+
similarity?(a: number[], b: number[]): number;
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
export interface IPIADetectorOptions {
|
|
2112
|
+
threshold?: number;
|
|
2113
|
+
separator?: string;
|
|
2114
|
+
embeddingBackend?: EmbeddingBackend;
|
|
2115
|
+
usePatternScan?: boolean;
|
|
2116
|
+
maxContentLength?: number;
|
|
2117
|
+
maxIntentLength?: number;
|
|
2118
|
+
enabled?: boolean;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
export declare class IPIADetector {
|
|
2122
|
+
threshold: number;
|
|
2123
|
+
enabled: boolean;
|
|
2124
|
+
constructor(options?: IPIADetectorOptions);
|
|
2125
|
+
scan(externalContent: string, userIntent: string, options?: { source?: string; metadata?: any }): IPIAResult;
|
|
2126
|
+
scanAsync(externalContent: string, userIntent: string, options?: { source?: string; metadata?: any }): Promise<IPIAResult>;
|
|
2127
|
+
scanBatch(contentItems: string[], userIntent: string, options?: { source?: string; metadata?: any }): { results: IPIAResult[]; summary: { total: number; blocked: number; safe: number; maxConfidence: number } };
|
|
2128
|
+
getStats(): { total: number; blocked: number; safe: number; blockRate: string };
|
|
2129
|
+
setThreshold(threshold: number): void;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
export declare class ContextConstructor {
|
|
2133
|
+
constructor(options?: { separator?: string; maxContentLength?: number; maxIntentLength?: number });
|
|
2134
|
+
build(externalContent: string, userIntent: string): { joint: string; content: string; intent: string };
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
export declare class FeatureExtractor {
|
|
2138
|
+
extract(ctx: { joint: string; content: string; intent: string }): { features: number[]; featureMap: Record<string, number> };
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
export declare class TreeClassifier {
|
|
2142
|
+
threshold: number;
|
|
2143
|
+
constructor(options?: { threshold?: number });
|
|
2144
|
+
classify(features: number[], featureMap: Record<string, number>): { isInjection: boolean; confidence: number; reason: string };
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
export declare class ExternalEmbedder {
|
|
2148
|
+
constructor(backend: EmbeddingBackend);
|
|
2149
|
+
static defaultSimilarity(a: number[], b: number[]): number;
|
|
2150
|
+
extractCosineFeatures(ctx: { joint: string; content: string; intent: string }): Promise<{ cosine_intent_content: number; cosine_joint_intent: number; cosine_joint_content: number }>;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
export declare function createIPIAScanner(options?: IPIADetectorOptions): (content: string, intent: string, options?: any) => IPIAResult;
|
|
2154
|
+
export declare function ipiaMiddleware(options?: { contentField?: string; intentField?: string; action?: 'block' | 'flag' | 'log'; threshold?: number }): (req: any, res: any, next: any) => void;
|
|
2155
|
+
|
|
2156
|
+
export declare const IPIA_FEATURE_NAMES: string[];
|
|
2157
|
+
export declare const IPIA_INJECTION_LEXICON: Record<string, number>;
|