@agent-trust/gateway 1.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.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @agent-trust/gateway
2
+
3
+ Express middleware that lets trusted AI agents interact with your website. Part of the [AgentTrust](https://github.com/mmsadek96/agentgateway) ecosystem.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @agent-trust/gateway
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import express from 'express';
15
+ import { createGateway } from '@agent-trust/gateway';
16
+
17
+ const app = express();
18
+ app.use(express.json());
19
+
20
+ const gateway = createGateway({
21
+ stationUrl: 'https://agentgateway-6f041c655eb3.herokuapp.com',
22
+ gatewayId: 'my-store',
23
+ stationApiKey: 'YOUR_API_KEY',
24
+ actions: {
25
+ 'search_products': {
26
+ description: 'Search the product catalog',
27
+ minScore: 30,
28
+ parameters: {
29
+ query: { type: 'string', required: true, description: 'Search query' }
30
+ },
31
+ handler: async (params) => {
32
+ return await db.products.search(params.query);
33
+ }
34
+ },
35
+ 'place_order': {
36
+ description: 'Place an order',
37
+ minScore: 70, // Higher trust required
38
+ parameters: {
39
+ productId: { type: 'string', required: true },
40
+ quantity: { type: 'number', required: true }
41
+ },
42
+ handler: async (params, agent) => {
43
+ return await db.orders.create({ ...params, agentId: agent.agentId });
44
+ }
45
+ }
46
+ },
47
+ behavior: {
48
+ maxActionsPerMinute: 30,
49
+ onSuspiciousActivity: (event) => {
50
+ console.warn('Suspicious agent:', event.flag, event.description);
51
+ }
52
+ }
53
+ });
54
+
55
+ app.use('/agent-gateway', gateway.router());
56
+ app.listen(3000);
57
+ ```
58
+
59
+ ## Features
60
+
61
+ - **Certificate verification** — validates RS256 JWT certificates from the AgentTrust Station
62
+ - **Score-based access** — different actions require different reputation levels
63
+ - **Real-time behavioral tracking** — detects and blocks suspicious agents mid-session
64
+ - **Auto-reporting** — reports agent behavior back to Station automatically
65
+ - **Discovery endpoints** — agents can discover available actions programmatically
66
+
67
+ ## Behavioral Tracking
68
+
69
+ The gateway monitors agent behavior in real-time and detects:
70
+
71
+ | Detection | What it catches |
72
+ |-----------|----------------|
73
+ | `rapid_fire` | Too many requests per minute |
74
+ | `high_failure_rate` | Probing / brute force |
75
+ | `action_enumeration` | Scanning endpoints |
76
+ | `repeated_action` | Automation (same action on loop) |
77
+ | `scope_violation` | Accessing above trust level |
78
+ | `burst_detected` | Sudden activity after idle |
79
+
80
+ Agents get a behavioral score (0-100) that degrades with violations. Drop below threshold = blocked mid-session.
81
+
82
+ ## API
83
+
84
+ ### Routes (mounted on your chosen path)
85
+
86
+ | Method | Path | Description |
87
+ |--------|------|-------------|
88
+ | `GET` | `/.well-known/agent-gateway` | Discovery manifest |
89
+ | `GET` | `/actions` | List available actions |
90
+ | `POST` | `/actions/:name` | Execute an action (cert required) |
91
+ | `GET` | `/behavior/sessions` | Monitor active sessions |
92
+
93
+ ## Links
94
+
95
+ - [Full documentation](https://github.com/mmsadek96/agentgateway)
96
+ - [Live Station](https://agentgateway-6f041c655eb3.herokuapp.com/)
97
+ - [API docs](https://agentgateway-6f041c655eb3.herokuapp.com/docs)
98
+
99
+ ## License
100
+
101
+ MIT
@@ -0,0 +1,29 @@
1
+ import { ActionDefinition, ActionResult, AgentContext, PublicActionInfo } from './types';
2
+ /**
3
+ * Manages action definitions and handles execution.
4
+ * Validates parameters, checks score thresholds, and runs handler functions.
5
+ */
6
+ export declare class ActionRegistry {
7
+ private actions;
8
+ constructor(actions: Record<string, ActionDefinition>);
9
+ /** Get an action definition by name */
10
+ getAction(name: string): ActionDefinition | undefined;
11
+ /** Get all action names */
12
+ getActionNames(): string[];
13
+ /**
14
+ * Get the public discovery payload (schemas without handler functions).
15
+ * This is safe to expose to external agents.
16
+ */
17
+ getDiscoveryPayload(): Record<string, PublicActionInfo>;
18
+ /**
19
+ * Validate parameters against an action's schema.
20
+ * Returns an array of error messages (empty if valid).
21
+ */
22
+ validateParams(actionName: string, params: Record<string, unknown>): string[];
23
+ /**
24
+ * Execute an action.
25
+ * Checks score threshold, validates params, then calls the handler.
26
+ */
27
+ execute(actionName: string, params: Record<string, unknown>, agentContext: AgentContext): Promise<ActionResult>;
28
+ }
29
+ //# sourceMappingURL=action-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-registry.d.ts","sourceRoot":"","sources":["../src/action-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAgC;gBAEnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIrD,uCAAuC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIrD,2BAA2B;IAC3B,cAAc,IAAI,MAAM,EAAE;IAI1B;;;OAGG;IACH,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAcvD;;;OAGG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE;IAuC7E;;;OAGG;IACG,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,YAAY,CAAC;CAoCzB"}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionRegistry = void 0;
4
+ /**
5
+ * Manages action definitions and handles execution.
6
+ * Validates parameters, checks score thresholds, and runs handler functions.
7
+ */
8
+ class ActionRegistry {
9
+ constructor(actions) {
10
+ this.actions = new Map(Object.entries(actions));
11
+ }
12
+ /** Get an action definition by name */
13
+ getAction(name) {
14
+ return this.actions.get(name);
15
+ }
16
+ /** Get all action names */
17
+ getActionNames() {
18
+ return Array.from(this.actions.keys());
19
+ }
20
+ /**
21
+ * Get the public discovery payload (schemas without handler functions).
22
+ * This is safe to expose to external agents.
23
+ */
24
+ getDiscoveryPayload() {
25
+ const payload = {};
26
+ for (const [name, def] of this.actions) {
27
+ payload[name] = {
28
+ description: def.description,
29
+ minScore: def.minScore,
30
+ parameters: def.parameters
31
+ };
32
+ }
33
+ return payload;
34
+ }
35
+ /**
36
+ * Validate parameters against an action's schema.
37
+ * Returns an array of error messages (empty if valid).
38
+ */
39
+ validateParams(actionName, params) {
40
+ const action = this.actions.get(actionName);
41
+ if (!action) {
42
+ return [`Action "${actionName}" not found`];
43
+ }
44
+ const errors = [];
45
+ // Check required parameters
46
+ for (const [paramName, paramDef] of Object.entries(action.parameters)) {
47
+ const value = params[paramName];
48
+ if (paramDef.required && (value === undefined || value === null)) {
49
+ errors.push(`Parameter "${paramName}" is required`);
50
+ continue;
51
+ }
52
+ if (value !== undefined && value !== null) {
53
+ // Type checking
54
+ const actualType = Array.isArray(value) ? 'array' : typeof value;
55
+ if (actualType !== paramDef.type) {
56
+ errors.push(`Parameter "${paramName}" must be of type ${paramDef.type}, got ${actualType}`);
57
+ }
58
+ }
59
+ }
60
+ // Check for unknown parameters
61
+ const knownParams = new Set(Object.keys(action.parameters));
62
+ for (const paramName of Object.keys(params)) {
63
+ if (!knownParams.has(paramName)) {
64
+ errors.push(`Unknown parameter "${paramName}"`);
65
+ }
66
+ }
67
+ return errors;
68
+ }
69
+ /**
70
+ * Execute an action.
71
+ * Checks score threshold, validates params, then calls the handler.
72
+ */
73
+ async execute(actionName, params, agentContext) {
74
+ const action = this.actions.get(actionName);
75
+ if (!action) {
76
+ return {
77
+ success: false,
78
+ error: `Action "${actionName}" not found`
79
+ };
80
+ }
81
+ // Check minimum score
82
+ if (agentContext.score < action.minScore) {
83
+ return {
84
+ success: false,
85
+ error: `Insufficient reputation score: ${agentContext.score} < ${action.minScore} required`
86
+ };
87
+ }
88
+ // Validate parameters
89
+ const validationErrors = this.validateParams(actionName, params);
90
+ if (validationErrors.length > 0) {
91
+ return {
92
+ success: false,
93
+ error: `Parameter validation failed: ${validationErrors.join(', ')}`
94
+ };
95
+ }
96
+ // Execute the handler
97
+ try {
98
+ const data = await action.handler(params, agentContext);
99
+ return { success: true, data };
100
+ }
101
+ catch (error) {
102
+ const message = error instanceof Error ? error.message : 'Action execution failed';
103
+ return { success: false, error: message };
104
+ }
105
+ }
106
+ }
107
+ exports.ActionRegistry = ActionRegistry;
108
+ //# sourceMappingURL=action-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-registry.js","sourceRoot":"","sources":["../src/action-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import { BehaviorConfig, BehaviorFlag, SessionStats } from './types';
2
+ /**
3
+ * BehaviorTracker — real-time behavioral analysis of agent sessions.
4
+ *
5
+ * Tracks what agents do within a gateway and detects suspicious patterns:
6
+ * - Rapid-fire requests (rate abuse)
7
+ * - High failure rates (probing/brute force)
8
+ * - Action enumeration (scanning available endpoints)
9
+ * - Repeated identical actions (automation)
10
+ * - Scope violations (trying actions above their trust level)
11
+ * - Burst patterns (sudden activity after idle)
12
+ *
13
+ * Each agent gets a behavioral score (0-100) that starts at 100 and
14
+ * decreases with each violation. If the score drops below the block
15
+ * threshold, the agent is blocked mid-session.
16
+ */
17
+ export declare class BehaviorTracker {
18
+ private sessions;
19
+ private config;
20
+ private cleanupInterval;
21
+ constructor(config?: BehaviorConfig);
22
+ /**
23
+ * Record an action and analyze behavior.
24
+ * Returns the current behavioral score and any new flags.
25
+ */
26
+ recordAction(agentId: string, externalId: string, actionName: string, params: Record<string, unknown>, success: boolean, scoreMet: boolean): {
27
+ behaviorScore: number;
28
+ flags: BehaviorFlag[];
29
+ blocked: boolean;
30
+ };
31
+ /**
32
+ * Check if an agent is currently blocked.
33
+ */
34
+ isBlocked(agentId: string): boolean;
35
+ /**
36
+ * Get the current behavioral score for an agent.
37
+ */
38
+ getScore(agentId: string): number;
39
+ /**
40
+ * Get session stats for an agent.
41
+ */
42
+ getStats(agentId: string): SessionStats | null;
43
+ /**
44
+ * Manually block an agent.
45
+ */
46
+ blockAgent(agentId: string): void;
47
+ /**
48
+ * Clear an agent's session (reset).
49
+ */
50
+ clearSession(agentId: string): void;
51
+ /**
52
+ * Get all active sessions (for monitoring/dashboard).
53
+ */
54
+ getActiveSessions(): Array<{
55
+ agentId: string;
56
+ externalId: string;
57
+ stats: SessionStats;
58
+ }>;
59
+ /**
60
+ * Destroy the tracker and stop cleanup interval.
61
+ */
62
+ destroy(): void;
63
+ /** Check 1: Too many actions per minute */
64
+ private checkRapidFire;
65
+ /** Check 2: Too many failures */
66
+ private checkHighFailureRate;
67
+ /** Check 3: Trying many different action types (scanning) */
68
+ private checkActionEnumeration;
69
+ /** Check 4: Same action with same params repeated (automation) */
70
+ private checkRepeatedActions;
71
+ /** Check 6: Sudden burst of activity after being idle */
72
+ private checkBurstPattern;
73
+ private hashParams;
74
+ private getSessionStats;
75
+ private getDescription;
76
+ private cleanupSessions;
77
+ }
78
+ //# sourceMappingURL=behavior-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-tracker.d.ts","sourceRoot":"","sources":["../src/behavior-tracker.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EAEd,YAAY,EAGZ,YAAY,EACb,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,MAAM,CAEZ;IACF,OAAO,CAAC,eAAe,CAAiC;gBAE5C,MAAM,GAAE,cAAmB;IAiBvC;;;OAGG;IACH,YAAY,CACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,GAChB;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,EAAE,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAuHrE;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKnC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKjC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAM9C;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQjC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,iBAAiB,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IAYxF;;OAEG;IACH,OAAO,IAAI,IAAI;IAOf,2CAA2C;IAC3C,OAAO,CAAC,cAAc;IAMtB,iCAAiC;IACjC,OAAO,CAAC,oBAAoB;IAK5B,6DAA6D;IAC7D,OAAO,CAAC,sBAAsB;IAO9B,kEAAkE;IAClE,OAAO,CAAC,oBAAoB;IAoB5B,yDAAyD;IACzD,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,eAAe;CAQxB"}
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.BehaviorTracker = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ /**
9
+ * BehaviorTracker — real-time behavioral analysis of agent sessions.
10
+ *
11
+ * Tracks what agents do within a gateway and detects suspicious patterns:
12
+ * - Rapid-fire requests (rate abuse)
13
+ * - High failure rates (probing/brute force)
14
+ * - Action enumeration (scanning available endpoints)
15
+ * - Repeated identical actions (automation)
16
+ * - Scope violations (trying actions above their trust level)
17
+ * - Burst patterns (sudden activity after idle)
18
+ *
19
+ * Each agent gets a behavioral score (0-100) that starts at 100 and
20
+ * decreases with each violation. If the score drops below the block
21
+ * threshold, the agent is blocked mid-session.
22
+ */
23
+ class BehaviorTracker {
24
+ constructor(config = {}) {
25
+ this.sessions = new Map();
26
+ this.config = {
27
+ enabled: config.enabled ?? true,
28
+ sessionTimeout: config.sessionTimeout ?? 300000, // 5 minutes
29
+ maxActionsPerMinute: config.maxActionsPerMinute ?? 30,
30
+ maxFailuresBeforeFlag: config.maxFailuresBeforeFlag ?? 5,
31
+ maxUniqueActionsPerMinute: config.maxUniqueActionsPerMinute ?? 10,
32
+ maxRepeatedActionsPerMinute: config.maxRepeatedActionsPerMinute ?? 10,
33
+ violationPenalty: config.violationPenalty ?? 10,
34
+ blockThreshold: config.blockThreshold ?? 20,
35
+ onSuspiciousActivity: config.onSuspiciousActivity,
36
+ };
37
+ // Clean up expired sessions every 60 seconds
38
+ this.cleanupInterval = setInterval(() => this.cleanupSessions(), 60000);
39
+ }
40
+ /**
41
+ * Record an action and analyze behavior.
42
+ * Returns the current behavioral score and any new flags.
43
+ */
44
+ recordAction(agentId, externalId, actionName, params, success, scoreMet) {
45
+ if (!this.config.enabled) {
46
+ return { behaviorScore: 100, flags: [], blocked: false };
47
+ }
48
+ const now = Date.now();
49
+ let session = this.sessions.get(agentId);
50
+ // Create new session if none exists or previous one expired
51
+ if (!session || (now - session.lastActivityAt) > this.config.sessionTimeout) {
52
+ session = {
53
+ agentId,
54
+ externalId,
55
+ startedAt: now,
56
+ lastActivityAt: now,
57
+ behaviorScore: 100,
58
+ actions: [],
59
+ flags: new Set(),
60
+ blocked: false
61
+ };
62
+ this.sessions.set(agentId, session);
63
+ }
64
+ // Record the action
65
+ const action = {
66
+ actionName,
67
+ paramsHash: this.hashParams(actionName, params),
68
+ success,
69
+ scopeViolation: !scoreMet,
70
+ timestamp: now
71
+ };
72
+ session.actions.push(action);
73
+ session.lastActivityAt = now;
74
+ // If already blocked, don't re-analyze
75
+ if (session.blocked) {
76
+ return { behaviorScore: session.behaviorScore, flags: Array.from(session.flags), blocked: true };
77
+ }
78
+ // ─── Run all behavioral checks ───
79
+ const newFlags = [];
80
+ // Check 1: Rapid-fire detection
81
+ if (this.checkRapidFire(session, now)) {
82
+ newFlags.push('rapid_fire');
83
+ }
84
+ // Check 2: High failure rate
85
+ if (this.checkHighFailureRate(session)) {
86
+ newFlags.push('high_failure_rate');
87
+ }
88
+ // Check 3: Action enumeration
89
+ if (this.checkActionEnumeration(session, now)) {
90
+ newFlags.push('action_enumeration');
91
+ }
92
+ // Check 4: Repeated identical actions
93
+ if (this.checkRepeatedActions(session, now)) {
94
+ newFlags.push('repeated_action');
95
+ }
96
+ // Check 5: Scope violation
97
+ if (!scoreMet) {
98
+ newFlags.push('scope_violation');
99
+ }
100
+ // Check 6: Burst detection (activity after idle)
101
+ if (this.checkBurstPattern(session, now)) {
102
+ newFlags.push('burst_detected');
103
+ }
104
+ // Apply penalties for NEW flags only
105
+ for (const flag of newFlags) {
106
+ if (!session.flags.has(flag)) {
107
+ session.flags.add(flag);
108
+ session.behaviorScore = Math.max(0, session.behaviorScore - this.config.violationPenalty);
109
+ // Emit event
110
+ if (this.config.onSuspiciousActivity) {
111
+ const event = {
112
+ agentId,
113
+ externalId,
114
+ flag,
115
+ description: this.getDescription(flag),
116
+ behaviorScore: session.behaviorScore,
117
+ sessionStats: this.getSessionStats(session),
118
+ timestamp: new Date().toISOString()
119
+ };
120
+ this.config.onSuspiciousActivity(event);
121
+ }
122
+ }
123
+ }
124
+ // For repeated violations of the SAME type, apply reduced penalties
125
+ for (const flag of newFlags) {
126
+ if (session.flags.has(flag) && flag !== 'scope_violation') {
127
+ // Escalating penalty: each repeat costs more
128
+ session.behaviorScore = Math.max(0, session.behaviorScore - Math.floor(this.config.violationPenalty / 2));
129
+ }
130
+ }
131
+ // Scope violations always cost (they're deliberate)
132
+ if (!scoreMet && session.flags.has('scope_violation')) {
133
+ session.behaviorScore = Math.max(0, session.behaviorScore - this.config.violationPenalty);
134
+ }
135
+ // Check if agent should be blocked
136
+ if (session.behaviorScore <= this.config.blockThreshold) {
137
+ session.blocked = true;
138
+ }
139
+ return {
140
+ behaviorScore: session.behaviorScore,
141
+ flags: newFlags,
142
+ blocked: session.blocked
143
+ };
144
+ }
145
+ /**
146
+ * Check if an agent is currently blocked.
147
+ */
148
+ isBlocked(agentId) {
149
+ const session = this.sessions.get(agentId);
150
+ return session?.blocked ?? false;
151
+ }
152
+ /**
153
+ * Get the current behavioral score for an agent.
154
+ */
155
+ getScore(agentId) {
156
+ const session = this.sessions.get(agentId);
157
+ return session?.behaviorScore ?? 100;
158
+ }
159
+ /**
160
+ * Get session stats for an agent.
161
+ */
162
+ getStats(agentId) {
163
+ const session = this.sessions.get(agentId);
164
+ if (!session)
165
+ return null;
166
+ return this.getSessionStats(session);
167
+ }
168
+ /**
169
+ * Manually block an agent.
170
+ */
171
+ blockAgent(agentId) {
172
+ const session = this.sessions.get(agentId);
173
+ if (session) {
174
+ session.blocked = true;
175
+ session.behaviorScore = 0;
176
+ }
177
+ }
178
+ /**
179
+ * Clear an agent's session (reset).
180
+ */
181
+ clearSession(agentId) {
182
+ this.sessions.delete(agentId);
183
+ }
184
+ /**
185
+ * Get all active sessions (for monitoring/dashboard).
186
+ */
187
+ getActiveSessions() {
188
+ const result = [];
189
+ for (const session of this.sessions.values()) {
190
+ result.push({
191
+ agentId: session.agentId,
192
+ externalId: session.externalId,
193
+ stats: this.getSessionStats(session)
194
+ });
195
+ }
196
+ return result;
197
+ }
198
+ /**
199
+ * Destroy the tracker and stop cleanup interval.
200
+ */
201
+ destroy() {
202
+ clearInterval(this.cleanupInterval);
203
+ this.sessions.clear();
204
+ }
205
+ // ─── Behavioral Checks ───
206
+ /** Check 1: Too many actions per minute */
207
+ checkRapidFire(session, now) {
208
+ const oneMinuteAgo = now - 60000;
209
+ const recentActions = session.actions.filter(a => a.timestamp > oneMinuteAgo);
210
+ return recentActions.length > this.config.maxActionsPerMinute;
211
+ }
212
+ /** Check 2: Too many failures */
213
+ checkHighFailureRate(session) {
214
+ const failures = session.actions.filter(a => !a.success).length;
215
+ return failures >= this.config.maxFailuresBeforeFlag;
216
+ }
217
+ /** Check 3: Trying many different action types (scanning) */
218
+ checkActionEnumeration(session, now) {
219
+ const oneMinuteAgo = now - 60000;
220
+ const recentActions = session.actions.filter(a => a.timestamp > oneMinuteAgo);
221
+ const uniqueActions = new Set(recentActions.map(a => a.actionName));
222
+ return uniqueActions.size > this.config.maxUniqueActionsPerMinute;
223
+ }
224
+ /** Check 4: Same action with same params repeated (automation) */
225
+ checkRepeatedActions(session, now) {
226
+ const oneMinuteAgo = now - 60000;
227
+ const recentActions = session.actions.filter(a => a.timestamp > oneMinuteAgo);
228
+ // Count identical action+params combos
229
+ const counts = new Map();
230
+ for (const action of recentActions) {
231
+ const key = action.paramsHash;
232
+ counts.set(key, (counts.get(key) || 0) + 1);
233
+ }
234
+ // Check if any combo exceeds threshold
235
+ for (const count of counts.values()) {
236
+ if (count > this.config.maxRepeatedActionsPerMinute) {
237
+ return true;
238
+ }
239
+ }
240
+ return false;
241
+ }
242
+ /** Check 6: Sudden burst of activity after being idle */
243
+ checkBurstPattern(session, now) {
244
+ if (session.actions.length < 5)
245
+ return false; // Need enough data
246
+ const actions = session.actions;
247
+ const lastFive = actions.slice(-5);
248
+ const fiveActionsAgo = actions.length >= 6 ? actions[actions.length - 6] : null;
249
+ if (!fiveActionsAgo)
250
+ return false;
251
+ // Gap between 6th-last and 5th-last action
252
+ const gap = lastFive[0].timestamp - fiveActionsAgo.timestamp;
253
+ // Time span of last 5 actions
254
+ const recentSpan = lastFive[lastFive.length - 1].timestamp - lastFive[0].timestamp;
255
+ // If there was a long idle period (>30s) followed by 5 rapid actions (<5s)
256
+ return gap > 30000 && recentSpan < 5000;
257
+ }
258
+ // ─── Helpers ───
259
+ hashParams(actionName, params) {
260
+ const key = `${actionName}:${JSON.stringify(params, Object.keys(params).sort())}`;
261
+ return crypto_1.default.createHash('md5').update(key).digest('hex').substring(0, 12);
262
+ }
263
+ getSessionStats(session) {
264
+ const now = Date.now();
265
+ const oneMinuteAgo = now - 60000;
266
+ const recentActions = session.actions.filter(a => a.timestamp > oneMinuteAgo);
267
+ return {
268
+ totalActions: session.actions.length,
269
+ successfulActions: session.actions.filter(a => a.success).length,
270
+ failedActions: session.actions.filter(a => !a.success).length,
271
+ actionsLastMinute: recentActions.length,
272
+ uniqueActionsLastMinute: new Set(recentActions.map(a => a.actionName)).size,
273
+ sessionDuration: now - session.startedAt,
274
+ scopeViolations: session.actions.filter(a => a.scopeViolation).length,
275
+ flagsTriggered: Array.from(session.flags)
276
+ };
277
+ }
278
+ getDescription(flag) {
279
+ const descriptions = {
280
+ 'rapid_fire': `Agent exceeded ${this.config.maxActionsPerMinute} actions per minute`,
281
+ 'high_failure_rate': `Agent has ${this.config.maxFailuresBeforeFlag}+ failed actions (possible probing)`,
282
+ 'action_enumeration': `Agent tried ${this.config.maxUniqueActionsPerMinute}+ unique actions in one minute (scanning)`,
283
+ 'repeated_action': `Agent repeated the same action ${this.config.maxRepeatedActionsPerMinute}+ times per minute (automation)`,
284
+ 'scope_violation': 'Agent attempted an action above their trust level',
285
+ 'session_anomaly': 'Unusual session pattern detected',
286
+ 'burst_detected': 'Sudden burst of activity after idle period'
287
+ };
288
+ return descriptions[flag];
289
+ }
290
+ cleanupSessions() {
291
+ const now = Date.now();
292
+ for (const [agentId, session] of this.sessions) {
293
+ if ((now - session.lastActivityAt) > this.config.sessionTimeout) {
294
+ this.sessions.delete(agentId);
295
+ }
296
+ }
297
+ }
298
+ }
299
+ exports.BehaviorTracker = BehaviorTracker;
300
+ //# sourceMappingURL=behavior-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behavior-tracker.js","sourceRoot":"","sources":["../src/behavior-tracker.ts"],"names":[],"mappings":"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"}