agentshield-sdk 7.0.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 (84) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/LICENSE +21 -0
  3. package/README.md +975 -0
  4. package/bin/agent-shield.js +680 -0
  5. package/package.json +118 -0
  6. package/src/adaptive.js +330 -0
  7. package/src/agent-protocol.js +998 -0
  8. package/src/alert-tuning.js +480 -0
  9. package/src/allowlist.js +603 -0
  10. package/src/audit-immutable.js +914 -0
  11. package/src/audit-streaming.js +469 -0
  12. package/src/badges.js +196 -0
  13. package/src/behavior-profiling.js +289 -0
  14. package/src/benchmark-harness.js +804 -0
  15. package/src/canary.js +271 -0
  16. package/src/certification.js +563 -0
  17. package/src/circuit-breaker.js +321 -0
  18. package/src/compliance.js +617 -0
  19. package/src/confidence-tuning.js +324 -0
  20. package/src/confused-deputy.js +624 -0
  21. package/src/context-scoring.js +360 -0
  22. package/src/conversation.js +494 -0
  23. package/src/cost-optimizer.js +1024 -0
  24. package/src/ctf.js +462 -0
  25. package/src/detector-core.js +1999 -0
  26. package/src/distributed.js +359 -0
  27. package/src/document-scanner.js +795 -0
  28. package/src/embedding.js +307 -0
  29. package/src/encoding.js +429 -0
  30. package/src/enterprise.js +405 -0
  31. package/src/errors.js +100 -0
  32. package/src/eu-ai-act.js +523 -0
  33. package/src/fuzzer.js +764 -0
  34. package/src/honeypot.js +328 -0
  35. package/src/i18n-patterns.js +523 -0
  36. package/src/index.js +430 -0
  37. package/src/integrations.js +528 -0
  38. package/src/llm-redteam.js +670 -0
  39. package/src/main.js +741 -0
  40. package/src/main.mjs +38 -0
  41. package/src/mcp-bridge.js +542 -0
  42. package/src/mcp-certification.js +846 -0
  43. package/src/mcp-sdk-integration.js +355 -0
  44. package/src/mcp-security-runtime.js +741 -0
  45. package/src/mcp-server.js +740 -0
  46. package/src/middleware.js +208 -0
  47. package/src/model-finetuning.js +884 -0
  48. package/src/model-fingerprint.js +1042 -0
  49. package/src/multi-agent-trust.js +453 -0
  50. package/src/multi-agent.js +404 -0
  51. package/src/multimodal.js +296 -0
  52. package/src/nist-mapping.js +505 -0
  53. package/src/observability.js +330 -0
  54. package/src/openclaw.js +450 -0
  55. package/src/otel.js +544 -0
  56. package/src/owasp-2025.js +483 -0
  57. package/src/pii.js +390 -0
  58. package/src/plugin-marketplace.js +628 -0
  59. package/src/plugin-system.js +349 -0
  60. package/src/policy-dsl.js +775 -0
  61. package/src/policy-extended.js +635 -0
  62. package/src/policy.js +443 -0
  63. package/src/presets.js +409 -0
  64. package/src/production.js +557 -0
  65. package/src/prompt-leakage.js +321 -0
  66. package/src/rag-vulnerability.js +579 -0
  67. package/src/redteam.js +475 -0
  68. package/src/response-handler.js +429 -0
  69. package/src/scanners.js +357 -0
  70. package/src/self-healing.js +363 -0
  71. package/src/semantic.js +339 -0
  72. package/src/shield-score.js +250 -0
  73. package/src/sso-saml.js +897 -0
  74. package/src/stream-scanner.js +806 -0
  75. package/src/testing.js +505 -0
  76. package/src/threat-encyclopedia.js +629 -0
  77. package/src/threat-intel-network.js +1017 -0
  78. package/src/token-analysis.js +467 -0
  79. package/src/tool-guard.js +412 -0
  80. package/src/tool-output-validator.js +354 -0
  81. package/src/utils.js +83 -0
  82. package/src/watermark.js +235 -0
  83. package/src/worker-scanner.js +601 -0
  84. package/types/index.d.ts +2088 -0
@@ -0,0 +1,289 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Agent Shield — Agent Behavior Profiling (v3.0)
5
+ *
6
+ * Establishes baselines for normal agent behavior and detects anomalies
7
+ * that may indicate compromise, drift, or attack influence.
8
+ *
9
+ * Tracks: response patterns, tool usage, topic distribution, timing,
10
+ * output length, sentiment shifts, and more.
11
+ *
12
+ * All processing runs locally — no data ever leaves your environment.
13
+ */
14
+
15
+ // =========================================================================
16
+ // STATISTICAL HELPERS
17
+ // =========================================================================
18
+
19
+ /**
20
+ * Calculate mean of an array.
21
+ * @param {number[]} arr
22
+ * @returns {number}
23
+ */
24
+ function mean(arr) {
25
+ return arr.length > 0 ? arr.reduce((a, b) => a + b, 0) / arr.length : 0;
26
+ }
27
+
28
+ /**
29
+ * Calculate standard deviation.
30
+ * @param {number[]} arr
31
+ * @returns {number}
32
+ */
33
+ function stdDev(arr) {
34
+ if (arr.length < 2) return 0;
35
+ const m = mean(arr);
36
+ const squaredDiffs = arr.map(x => (x - m) ** 2);
37
+ return Math.sqrt(squaredDiffs.reduce((a, b) => a + b, 0) / (arr.length - 1));
38
+ }
39
+
40
+ /**
41
+ * Check if a value is anomalous (beyond N standard deviations from mean).
42
+ * @param {number} value
43
+ * @param {number} m - Mean.
44
+ * @param {number} sd - Standard deviation.
45
+ * @param {number} [threshold=2] - Number of standard deviations.
46
+ * @returns {boolean}
47
+ */
48
+ function isAnomaly(value, m, sd, threshold = 2) {
49
+ if (sd === 0) return value !== m;
50
+ return Math.abs(value - m) > threshold * sd;
51
+ }
52
+
53
+ // =========================================================================
54
+ // BEHAVIOR PROFILE
55
+ // =========================================================================
56
+
57
+ /**
58
+ * Maintains a statistical profile of agent behavior.
59
+ */
60
+ class BehaviorProfile {
61
+ /**
62
+ * @param {object} [options]
63
+ * @param {number} [options.windowSize=200] - Number of observations to maintain.
64
+ * @param {number} [options.learningPeriod=20] - Observations before anomaly detection activates.
65
+ * @param {number} [options.anomalyThreshold=2.5] - Standard deviations for anomaly detection.
66
+ */
67
+ constructor(options = {}) {
68
+ this.windowSize = options.windowSize || 200;
69
+ this.learningPeriod = options.learningPeriod || 20;
70
+ this.anomalyThreshold = options.anomalyThreshold || 2.5;
71
+
72
+ this._metrics = {
73
+ responseLength: [],
74
+ responseTime: [],
75
+ toolCallCount: [],
76
+ threatScore: [],
77
+ topicEntropy: []
78
+ };
79
+
80
+ this._toolUsage = {};
81
+ this._topicDistribution = {};
82
+ this._totalObservations = 0;
83
+ this._anomalies = [];
84
+
85
+ console.log('[Agent Shield] BehaviorProfile initialized (windowSize: %d, learningPeriod: %d)', this.windowSize, this.learningPeriod);
86
+ }
87
+
88
+ /**
89
+ * Record an observation of agent behavior.
90
+ *
91
+ * @param {object} observation
92
+ * @param {number} [observation.responseLength] - Length of agent response.
93
+ * @param {number} [observation.responseTimeMs] - Time taken to respond.
94
+ * @param {string[]} [observation.toolsCalled] - Tools used in this turn.
95
+ * @param {number} [observation.threatScore] - Threat score from scanning.
96
+ * @param {string} [observation.topic] - Detected topic/category.
97
+ * @returns {object} { anomalies: Array, isLearning: boolean }
98
+ */
99
+ record(observation) {
100
+ this._totalObservations++;
101
+
102
+ // Record metrics
103
+ if (observation.responseLength !== undefined) {
104
+ this._addMetric('responseLength', observation.responseLength);
105
+ }
106
+ if (observation.responseTimeMs !== undefined) {
107
+ this._addMetric('responseTime', observation.responseTimeMs);
108
+ }
109
+ if (observation.toolsCalled) {
110
+ this._addMetric('toolCallCount', observation.toolsCalled.length);
111
+ for (const tool of observation.toolsCalled) {
112
+ this._toolUsage[tool] = (this._toolUsage[tool] || 0) + 1;
113
+ }
114
+ }
115
+ if (observation.threatScore !== undefined) {
116
+ this._addMetric('threatScore', observation.threatScore);
117
+ }
118
+ if (observation.topic) {
119
+ this._topicDistribution[observation.topic] = (this._topicDistribution[observation.topic] || 0) + 1;
120
+ }
121
+
122
+ // Check for anomalies (only after learning period)
123
+ const isLearning = this._totalObservations < this.learningPeriod;
124
+ const anomalies = isLearning ? [] : this._detectAnomalies(observation);
125
+
126
+ if (anomalies.length > 0) {
127
+ this._anomalies.push({
128
+ timestamp: Date.now(),
129
+ observation: this._totalObservations,
130
+ anomalies
131
+ });
132
+ }
133
+
134
+ return { anomalies, isLearning };
135
+ }
136
+
137
+ /**
138
+ * Get the current behavior baseline.
139
+ * @returns {object}
140
+ */
141
+ getBaseline() {
142
+ const baseline = {};
143
+ for (const [metric, values] of Object.entries(this._metrics)) {
144
+ if (values.length > 0) {
145
+ baseline[metric] = {
146
+ mean: Math.round(mean(values) * 100) / 100,
147
+ stdDev: Math.round(stdDev(values) * 100) / 100,
148
+ min: Math.min(...values),
149
+ max: Math.max(...values),
150
+ samples: values.length
151
+ };
152
+ }
153
+ }
154
+ return baseline;
155
+ }
156
+
157
+ /**
158
+ * Get a full behavior report.
159
+ * @returns {object}
160
+ */
161
+ getReport() {
162
+ return {
163
+ totalObservations: this._totalObservations,
164
+ isLearning: this._totalObservations < this.learningPeriod,
165
+ baseline: this.getBaseline(),
166
+ toolUsage: { ...this._toolUsage },
167
+ topicDistribution: { ...this._topicDistribution },
168
+ anomalyCount: this._anomalies.length,
169
+ recentAnomalies: this._anomalies.slice(-10),
170
+ riskLevel: this._calculateRiskLevel()
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Check if the agent appears to be behaving normally.
176
+ * @returns {object} { normal: boolean, riskLevel, concerns: string[] }
177
+ */
178
+ healthCheck() {
179
+ const concerns = [];
180
+ const report = this.getReport();
181
+
182
+ if (report.isLearning) {
183
+ return { normal: true, riskLevel: 'unknown', concerns: ['Still in learning period.'] };
184
+ }
185
+
186
+ // Check for sudden tool usage changes
187
+ const totalToolCalls = Object.values(this._toolUsage).reduce((a, b) => a + b, 0);
188
+ if (totalToolCalls > 0) {
189
+ for (const [tool, count] of Object.entries(this._toolUsage)) {
190
+ const ratio = count / totalToolCalls;
191
+ if (ratio > 0.7 && totalToolCalls > 10) {
192
+ concerns.push(`Tool "${tool}" dominates usage at ${(ratio * 100).toFixed(0)}%.`);
193
+ }
194
+ }
195
+ }
196
+
197
+ // Check for high threat score trend
198
+ const recentThreats = this._metrics.threatScore.slice(-20);
199
+ if (recentThreats.length >= 5 && mean(recentThreats) > 0.5) {
200
+ concerns.push('Recent threat scores are elevated.');
201
+ }
202
+
203
+ // Check for anomaly frequency
204
+ const recentAnomalies = this._anomalies.filter(a => Date.now() - a.timestamp < 300000);
205
+ if (recentAnomalies.length > 5) {
206
+ concerns.push(`${recentAnomalies.length} anomalies in the last 5 minutes.`);
207
+ }
208
+
209
+ return {
210
+ normal: concerns.length === 0,
211
+ riskLevel: report.riskLevel,
212
+ concerns
213
+ };
214
+ }
215
+
216
+ /** Reset the profile. */
217
+ reset() {
218
+ for (const key of Object.keys(this._metrics)) {
219
+ this._metrics[key] = [];
220
+ }
221
+ this._toolUsage = {};
222
+ this._topicDistribution = {};
223
+ this._totalObservations = 0;
224
+ this._anomalies = [];
225
+ }
226
+
227
+ /** @private */
228
+ _addMetric(name, value) {
229
+ if (!this._metrics[name]) this._metrics[name] = [];
230
+ this._metrics[name].push(value);
231
+ if (this._metrics[name].length > this.windowSize) {
232
+ this._metrics[name].shift();
233
+ }
234
+ }
235
+
236
+ /** @private */
237
+ _detectAnomalies(observation) {
238
+ const anomalies = [];
239
+
240
+ const checks = [
241
+ { metric: 'responseLength', value: observation.responseLength, label: 'Response length' },
242
+ { metric: 'responseTime', value: observation.responseTimeMs, label: 'Response time' },
243
+ { metric: 'toolCallCount', value: observation.toolsCalled ? observation.toolsCalled.length : undefined, label: 'Tool call count' },
244
+ { metric: 'threatScore', value: observation.threatScore, label: 'Threat score' }
245
+ ];
246
+
247
+ for (const check of checks) {
248
+ if (check.value === undefined) continue;
249
+
250
+ const values = this._metrics[check.metric];
251
+ if (values.length < this.learningPeriod) continue;
252
+
253
+ const m = mean(values.slice(0, -1)); // Exclude current observation
254
+ const sd = stdDev(values.slice(0, -1));
255
+
256
+ if (isAnomaly(check.value, m, sd, this.anomalyThreshold)) {
257
+ const zScore = sd > 0 ? Math.round(((check.value - m) / sd) * 100) / 100 : 0;
258
+ anomalies.push({
259
+ metric: check.metric,
260
+ label: check.label,
261
+ value: check.value,
262
+ expected: { mean: Math.round(m * 100) / 100, stdDev: Math.round(sd * 100) / 100 },
263
+ zScore,
264
+ direction: check.value > m ? 'above' : 'below'
265
+ });
266
+ }
267
+ }
268
+
269
+ return anomalies;
270
+ }
271
+
272
+ /** @private */
273
+ _calculateRiskLevel() {
274
+ if (this._totalObservations < this.learningPeriod) return 'unknown';
275
+
276
+ const recentAnomalies = this._anomalies.filter(a => Date.now() - a.timestamp < 600000);
277
+ if (recentAnomalies.length > 10) return 'critical';
278
+ if (recentAnomalies.length > 5) return 'high';
279
+ if (recentAnomalies.length > 2) return 'medium';
280
+ if (recentAnomalies.length > 0) return 'low';
281
+ return 'normal';
282
+ }
283
+ }
284
+
285
+ // =========================================================================
286
+ // EXPORTS
287
+ // =========================================================================
288
+
289
+ module.exports = { BehaviorProfile, mean, stdDev, isAnomaly };