@panguard-ai/atr 1.4.2 → 1.4.3

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 (200) hide show
  1. package/.github/ISSUE_TEMPLATE/evasion-report.yml +75 -0
  2. package/.github/ISSUE_TEMPLATE/false-positive.yml +31 -0
  3. package/.github/ISSUE_TEMPLATE/mirofish-prediction.yml +128 -0
  4. package/.github/ISSUE_TEMPLATE/new-rule.yml +37 -0
  5. package/.github/PULL_REQUEST_TEMPLATE.md +23 -0
  6. package/.github/workflows/rule-quality.yml +203 -0
  7. package/.github/workflows/validate.yml +42 -0
  8. package/CHANGELOG.md +30 -0
  9. package/CONTRIBUTING.md +168 -0
  10. package/CONTRIBUTORS.md +28 -0
  11. package/COVERAGE.md +135 -0
  12. package/LIMITATIONS.md +154 -0
  13. package/SECURITY.md +48 -0
  14. package/THREAT-MODEL.md +243 -0
  15. package/docs/contribution-paths.md +202 -0
  16. package/docs/mirofish-prediction-guide.md +304 -0
  17. package/docs/quick-start.md +245 -0
  18. package/docs/rule-writing-guide.md +647 -0
  19. package/docs/schema-spec.md +594 -0
  20. package/examples/how-to-write-a-rule.md +251 -0
  21. package/package.json +10 -57
  22. package/src/index.ts +7 -0
  23. package/tsconfig.json +17 -0
  24. package/dist/cli.d.ts +0 -14
  25. package/dist/cli.d.ts.map +0 -1
  26. package/dist/cli.js +0 -744
  27. package/dist/cli.js.map +0 -1
  28. package/dist/coverage-analyzer.d.ts +0 -43
  29. package/dist/coverage-analyzer.d.ts.map +0 -1
  30. package/dist/coverage-analyzer.js +0 -329
  31. package/dist/coverage-analyzer.js.map +0 -1
  32. package/dist/engine.d.ts +0 -136
  33. package/dist/engine.d.ts.map +0 -1
  34. package/dist/engine.js +0 -781
  35. package/dist/engine.js.map +0 -1
  36. package/dist/index.d.ts +0 -26
  37. package/dist/index.d.ts.map +0 -1
  38. package/dist/index.js +0 -18
  39. package/dist/index.js.map +0 -1
  40. package/dist/loader.d.ts +0 -21
  41. package/dist/loader.d.ts.map +0 -1
  42. package/dist/loader.js +0 -149
  43. package/dist/loader.js.map +0 -1
  44. package/dist/mcp-server.d.ts +0 -13
  45. package/dist/mcp-server.d.ts.map +0 -1
  46. package/dist/mcp-server.js +0 -244
  47. package/dist/mcp-server.js.map +0 -1
  48. package/dist/mcp-tools/coverage-gaps.d.ts +0 -13
  49. package/dist/mcp-tools/coverage-gaps.d.ts.map +0 -1
  50. package/dist/mcp-tools/coverage-gaps.js +0 -57
  51. package/dist/mcp-tools/coverage-gaps.js.map +0 -1
  52. package/dist/mcp-tools/list-rules.d.ts +0 -17
  53. package/dist/mcp-tools/list-rules.d.ts.map +0 -1
  54. package/dist/mcp-tools/list-rules.js +0 -45
  55. package/dist/mcp-tools/list-rules.js.map +0 -1
  56. package/dist/mcp-tools/scan.d.ts +0 -18
  57. package/dist/mcp-tools/scan.d.ts.map +0 -1
  58. package/dist/mcp-tools/scan.js +0 -87
  59. package/dist/mcp-tools/scan.js.map +0 -1
  60. package/dist/mcp-tools/submit-proposal.d.ts +0 -12
  61. package/dist/mcp-tools/submit-proposal.d.ts.map +0 -1
  62. package/dist/mcp-tools/submit-proposal.js +0 -116
  63. package/dist/mcp-tools/submit-proposal.js.map +0 -1
  64. package/dist/mcp-tools/threat-summary.d.ts +0 -12
  65. package/dist/mcp-tools/threat-summary.d.ts.map +0 -1
  66. package/dist/mcp-tools/threat-summary.js +0 -72
  67. package/dist/mcp-tools/threat-summary.js.map +0 -1
  68. package/dist/mcp-tools/validate.d.ts +0 -15
  69. package/dist/mcp-tools/validate.d.ts.map +0 -1
  70. package/dist/mcp-tools/validate.js +0 -57
  71. package/dist/mcp-tools/validate.js.map +0 -1
  72. package/dist/modules/index.d.ts +0 -144
  73. package/dist/modules/index.d.ts.map +0 -1
  74. package/dist/modules/index.js +0 -82
  75. package/dist/modules/index.js.map +0 -1
  76. package/dist/modules/semantic.d.ts +0 -105
  77. package/dist/modules/semantic.d.ts.map +0 -1
  78. package/dist/modules/semantic.js +0 -289
  79. package/dist/modules/semantic.js.map +0 -1
  80. package/dist/modules/session.d.ts +0 -70
  81. package/dist/modules/session.d.ts.map +0 -1
  82. package/dist/modules/session.js +0 -163
  83. package/dist/modules/session.js.map +0 -1
  84. package/dist/rule-scaffolder.d.ts +0 -39
  85. package/dist/rule-scaffolder.d.ts.map +0 -1
  86. package/dist/rule-scaffolder.js +0 -171
  87. package/dist/rule-scaffolder.js.map +0 -1
  88. package/dist/session-tracker.d.ts +0 -56
  89. package/dist/session-tracker.d.ts.map +0 -1
  90. package/dist/session-tracker.js +0 -175
  91. package/dist/session-tracker.js.map +0 -1
  92. package/dist/skill-fingerprint.d.ts +0 -96
  93. package/dist/skill-fingerprint.d.ts.map +0 -1
  94. package/dist/skill-fingerprint.js +0 -336
  95. package/dist/skill-fingerprint.js.map +0 -1
  96. package/dist/types.d.ts +0 -211
  97. package/dist/types.d.ts.map +0 -1
  98. package/dist/types.js +0 -6
  99. package/dist/types.js.map +0 -1
  100. package/rules/agent-manipulation/ATR-2026-00030-cross-agent-attack.yaml +0 -177
  101. package/rules/agent-manipulation/ATR-2026-00032-goal-hijacking.yaml +0 -137
  102. package/rules/agent-manipulation/ATR-2026-00074-cross-agent-privilege-escalation.yaml +0 -117
  103. package/rules/agent-manipulation/ATR-2026-00076-inter-agent-message-spoofing.yaml +0 -167
  104. package/rules/agent-manipulation/ATR-2026-00077-human-trust-exploitation.yaml +0 -146
  105. package/rules/agent-manipulation/ATR-2026-00108-consensus-sybil-attack.yaml +0 -105
  106. package/rules/agent-manipulation/ATR-2026-00116-a2a-message-validation.yaml +0 -92
  107. package/rules/agent-manipulation/ATR-2026-00117-agent-identity-spoofing.yaml +0 -92
  108. package/rules/agent-manipulation/ATR-2026-00118-approval-fatigue.yaml +0 -89
  109. package/rules/agent-manipulation/ATR-2026-00119-social-engineering-via-agent.yaml +0 -89
  110. package/rules/agent-manipulation/ATR-2026-00132-casual-authority-escalation.yaml +0 -99
  111. package/rules/agent-manipulation/ATR-2026-00139-casual-authority-redirect.yaml +0 -53
  112. package/rules/context-exfiltration/ATR-2026-00020-system-prompt-leak.yaml +0 -177
  113. package/rules/context-exfiltration/ATR-2026-00021-api-key-exposure.yaml +0 -178
  114. package/rules/context-exfiltration/ATR-2026-00075-agent-memory-manipulation.yaml +0 -117
  115. package/rules/context-exfiltration/ATR-2026-00102-disguised-analytics-exfiltration.yaml +0 -71
  116. package/rules/context-exfiltration/ATR-2026-00113-credential-theft.yaml +0 -89
  117. package/rules/context-exfiltration/ATR-2026-00114-oauth-token-abuse.yaml +0 -89
  118. package/rules/context-exfiltration/ATR-2026-00115-env-var-harvesting.yaml +0 -90
  119. package/rules/context-exfiltration/ATR-2026-00136-tool-response-data-piggyback.yaml +0 -100
  120. package/rules/context-exfiltration/ATR-2026-00141-example-format-key-leak.yaml +0 -52
  121. package/rules/context-exfiltration/ATR-2026-00142-piggyback-transition-words.yaml +0 -55
  122. package/rules/context-exfiltration/ATR-2026-00145-obfuscated-key-disclosure.yaml +0 -49
  123. package/rules/context-exfiltration/ATR-2026-00146-env-var-existence-probe.yaml +0 -49
  124. package/rules/data-poisoning/ATR-2026-00070-data-poisoning.yaml +0 -162
  125. package/rules/excessive-autonomy/ATR-2026-00050-runaway-agent-loop.yaml +0 -136
  126. package/rules/excessive-autonomy/ATR-2026-00051-resource-exhaustion.yaml +0 -139
  127. package/rules/excessive-autonomy/ATR-2026-00052-cascading-failure.yaml +0 -155
  128. package/rules/excessive-autonomy/ATR-2026-00098-unauthorized-financial-action.yaml +0 -157
  129. package/rules/excessive-autonomy/ATR-2026-00099-high-risk-tool-gate.yaml +0 -176
  130. package/rules/model-security/ATR-2026-00072-model-behavior-extraction.yaml +0 -117
  131. package/rules/model-security/ATR-2026-00073-malicious-finetuning-data.yaml +0 -110
  132. package/rules/privilege-escalation/ATR-2026-00040-privilege-escalation.yaml +0 -177
  133. package/rules/privilege-escalation/ATR-2026-00041-scope-creep.yaml +0 -126
  134. package/rules/privilege-escalation/ATR-2026-00107-delayed-execution-bypass.yaml +0 -69
  135. package/rules/privilege-escalation/ATR-2026-00110-eval-injection.yaml +0 -92
  136. package/rules/privilege-escalation/ATR-2026-00111-shell-escape.yaml +0 -93
  137. package/rules/privilege-escalation/ATR-2026-00112-dynamic-import-exploitation.yaml +0 -89
  138. package/rules/privilege-escalation/ATR-2026-00143-casual-privilege-escalation.yaml +0 -53
  139. package/rules/privilege-escalation/ATR-2026-00144-rationalized-safety-bypass.yaml +0 -49
  140. package/rules/prompt-injection/ATR-2026-00001-direct-prompt-injection.yaml +0 -563
  141. package/rules/prompt-injection/ATR-2026-00002-indirect-prompt-injection.yaml +0 -216
  142. package/rules/prompt-injection/ATR-2026-00003-jailbreak-attempt.yaml +0 -397
  143. package/rules/prompt-injection/ATR-2026-00004-system-prompt-override.yaml +0 -308
  144. package/rules/prompt-injection/ATR-2026-00005-multi-turn-injection.yaml +0 -183
  145. package/rules/prompt-injection/ATR-2026-00080-encoding-evasion.yaml +0 -88
  146. package/rules/prompt-injection/ATR-2026-00081-semantic-multi-turn.yaml +0 -85
  147. package/rules/prompt-injection/ATR-2026-00082-fingerprint-evasion.yaml +0 -84
  148. package/rules/prompt-injection/ATR-2026-00083-indirect-tool-injection.yaml +0 -87
  149. package/rules/prompt-injection/ATR-2026-00084-structured-data-injection.yaml +0 -86
  150. package/rules/prompt-injection/ATR-2026-00085-audit-evasion.yaml +0 -84
  151. package/rules/prompt-injection/ATR-2026-00086-visual-spoofing.yaml +0 -88
  152. package/rules/prompt-injection/ATR-2026-00087-rule-probing.yaml +0 -82
  153. package/rules/prompt-injection/ATR-2026-00088-adaptive-countermeasure.yaml +0 -84
  154. package/rules/prompt-injection/ATR-2026-00089-polymorphic-skill.yaml +0 -85
  155. package/rules/prompt-injection/ATR-2026-00090-threat-intel-exfil.yaml +0 -84
  156. package/rules/prompt-injection/ATR-2026-00091-nested-payload.yaml +0 -88
  157. package/rules/prompt-injection/ATR-2026-00092-consensus-poisoning.yaml +0 -92
  158. package/rules/prompt-injection/ATR-2026-00093-gradual-escalation.yaml +0 -86
  159. package/rules/prompt-injection/ATR-2026-00094-audit-bypass.yaml +0 -86
  160. package/rules/prompt-injection/ATR-2026-00097-cjk-injection-patterns.yaml +0 -339
  161. package/rules/prompt-injection/ATR-2026-00104-persona-hijacking.yaml +0 -74
  162. package/rules/prompt-injection/ATR-2026-00130-indirect-authority-claim.yaml +0 -97
  163. package/rules/prompt-injection/ATR-2026-00131-fictional-academic-framing.yaml +0 -93
  164. package/rules/prompt-injection/ATR-2026-00133-paraphrase-injection.yaml +0 -111
  165. package/rules/prompt-injection/ATR-2026-00137-authority-claim-injection.yaml +0 -52
  166. package/rules/prompt-injection/ATR-2026-00138-fictional-framing-bypass.yaml +0 -51
  167. package/rules/prompt-injection/ATR-2026-00140-indirect-reference-reversal.yaml +0 -52
  168. package/rules/prompt-injection/ATR-2026-00148-language-switch-injection.yaml +0 -71
  169. package/rules/skill-compromise/ATR-2026-00060-skill-impersonation.yaml +0 -155
  170. package/rules/skill-compromise/ATR-2026-00061-description-behavior-mismatch.yaml +0 -100
  171. package/rules/skill-compromise/ATR-2026-00062-hidden-capability.yaml +0 -98
  172. package/rules/skill-compromise/ATR-2026-00063-skill-chain-attack.yaml +0 -99
  173. package/rules/skill-compromise/ATR-2026-00064-over-permissioned-skill.yaml +0 -117
  174. package/rules/skill-compromise/ATR-2026-00065-skill-update-attack.yaml +0 -95
  175. package/rules/skill-compromise/ATR-2026-00066-parameter-injection.yaml +0 -108
  176. package/rules/skill-compromise/ATR-2026-00120-skill-instruction-injection.yaml +0 -121
  177. package/rules/skill-compromise/ATR-2026-00121-skill-dangerous-script.yaml +0 -165
  178. package/rules/skill-compromise/ATR-2026-00122-skill-weaponized-instruction.yaml +0 -114
  179. package/rules/skill-compromise/ATR-2026-00123-skill-overreach-permissions.yaml +0 -118
  180. package/rules/skill-compromise/ATR-2026-00124-skill-name-squatting.yaml +0 -98
  181. package/rules/skill-compromise/ATR-2026-00125-context-poisoning-compaction.yaml +0 -93
  182. package/rules/skill-compromise/ATR-2026-00126-skill-rug-pull-setup.yaml +0 -99
  183. package/rules/skill-compromise/ATR-2026-00127-subcommand-overflow.yaml +0 -74
  184. package/rules/skill-compromise/ATR-2026-00128-html-comment-hidden-payload.yaml +0 -79
  185. package/rules/skill-compromise/ATR-2026-00129-unicode-smuggling.yaml +0 -73
  186. package/rules/skill-compromise/ATR-2026-00134-fork-claim-impersonation.yaml +0 -86
  187. package/rules/skill-compromise/ATR-2026-00135-exfil-url-in-instructions.yaml +0 -82
  188. package/rules/skill-compromise/ATR-2026-00147-fork-impersonation.yaml +0 -48
  189. package/rules/tool-poisoning/ATR-2026-00010-mcp-malicious-response.yaml +0 -239
  190. package/rules/tool-poisoning/ATR-2026-00011-tool-output-injection.yaml +0 -196
  191. package/rules/tool-poisoning/ATR-2026-00012-unauthorized-tool-call.yaml +0 -201
  192. package/rules/tool-poisoning/ATR-2026-00013-tool-ssrf.yaml +0 -219
  193. package/rules/tool-poisoning/ATR-2026-00095-supply-chain-poisoning.yaml +0 -93
  194. package/rules/tool-poisoning/ATR-2026-00096-registry-poisoning.yaml +0 -95
  195. package/rules/tool-poisoning/ATR-2026-00100-consent-bypass-instruction.yaml +0 -82
  196. package/rules/tool-poisoning/ATR-2026-00101-trust-escalation-override.yaml +0 -68
  197. package/rules/tool-poisoning/ATR-2026-00103-hidden-safety-bypass-instruction.yaml +0 -73
  198. package/rules/tool-poisoning/ATR-2026-00105-silent-action-concealment.yaml +0 -69
  199. package/rules/tool-poisoning/ATR-2026-00106-schema-description-contradiction.yaml +0 -68
  200. package/spec/atr-schema.yaml +0 -404
@@ -1,163 +0,0 @@
1
- /**
2
- * ATR Session Module - Built-in behavioral detection module
3
- *
4
- * Provides cross-event analysis using SessionTracker.
5
- * This is the reference implementation for ATR modules.
6
- *
7
- * Functions:
8
- * - call_frequency: Count tool calls within a time window
9
- * - pattern_frequency: Count pattern occurrences within a window
10
- * - event_count: Total events in a session within a window
11
- * - session_age: Time since first event in session (seconds)
12
- *
13
- * @module agent-threat-rules/modules/session
14
- */
15
- import { SessionTracker } from '../session-tracker.js';
16
- export class SessionModule {
17
- name = 'session';
18
- description = 'Cross-event behavioral analysis using session state tracking';
19
- version = '0.1.0';
20
- functions = [
21
- {
22
- name: 'call_frequency',
23
- description: 'Count how many times a specific tool was called within a time window',
24
- args: [
25
- {
26
- name: 'tool_name',
27
- type: 'string',
28
- required: true,
29
- description: 'Tool name to count',
30
- },
31
- {
32
- name: 'window',
33
- type: 'string',
34
- required: false,
35
- description: 'Time window (e.g., "5m", "1h"). Default: 5m',
36
- },
37
- ],
38
- },
39
- {
40
- name: 'pattern_frequency',
41
- description: 'Count how many times a pattern was matched within a time window',
42
- args: [
43
- {
44
- name: 'pattern',
45
- type: 'string',
46
- required: true,
47
- description: 'Pattern string to count',
48
- },
49
- {
50
- name: 'window',
51
- type: 'string',
52
- required: false,
53
- description: 'Time window. Default: 5m',
54
- },
55
- ],
56
- },
57
- {
58
- name: 'event_count',
59
- description: 'Total number of events in the current session within a time window',
60
- args: [
61
- {
62
- name: 'window',
63
- type: 'string',
64
- required: false,
65
- description: 'Time window. Default: 5m',
66
- },
67
- ],
68
- },
69
- {
70
- name: 'session_age',
71
- description: 'Time in seconds since the first event in this session',
72
- args: [],
73
- },
74
- ];
75
- tracker;
76
- constructor(tracker) {
77
- this.tracker = tracker ?? new SessionTracker();
78
- }
79
- async initialize() {
80
- // SessionTracker is ready immediately, no async setup needed
81
- }
82
- async evaluate(event, condition) {
83
- const sessionId = event.sessionId ?? 'default';
84
- const fn = condition.function;
85
- const args = condition.args;
86
- let value = 0;
87
- let description = '';
88
- switch (fn) {
89
- case 'call_frequency': {
90
- const toolName = String(args['tool_name'] ?? '');
91
- const window = String(args['window'] ?? '5m');
92
- const windowMs = parseWindow(window);
93
- value = this.tracker.getCallFrequency(sessionId, toolName, windowMs);
94
- description = `Tool "${toolName}" called ${value} times in ${window}`;
95
- break;
96
- }
97
- case 'pattern_frequency': {
98
- const pattern = String(args['pattern'] ?? '');
99
- const window = String(args['window'] ?? '5m');
100
- const windowMs = parseWindow(window);
101
- value = this.tracker.getPatternFrequency(sessionId, pattern, windowMs);
102
- description = `Pattern "${pattern}" seen ${value} times in ${window}`;
103
- break;
104
- }
105
- case 'event_count': {
106
- const window = String(args['window'] ?? '5m');
107
- const windowMs = parseWindow(window);
108
- value = this.tracker.getEventCount(sessionId, windowMs);
109
- description = `${value} events in session within ${window}`;
110
- break;
111
- }
112
- case 'session_age': {
113
- const snapshot = this.tracker.getSessionSnapshot(sessionId);
114
- if (snapshot && snapshot.oldestEventTimestamp) {
115
- value = Math.floor((Date.now() - snapshot.oldestEventTimestamp) / 1000);
116
- }
117
- description = `Session age: ${value} seconds`;
118
- break;
119
- }
120
- default:
121
- return { matched: false, value: 0, description: `Unknown function: ${fn}` };
122
- }
123
- const matched = compare(value, condition.operator, condition.threshold);
124
- return { matched, value, description };
125
- }
126
- async destroy() {
127
- // No cleanup needed
128
- }
129
- }
130
- function compare(value, operator, threshold) {
131
- switch (operator) {
132
- case 'gt':
133
- return value > threshold;
134
- case 'lt':
135
- return value < threshold;
136
- case 'eq':
137
- return value === threshold;
138
- case 'gte':
139
- return value >= threshold;
140
- case 'lte':
141
- return value <= threshold;
142
- default:
143
- return false;
144
- }
145
- }
146
- function parseWindow(window) {
147
- const match = window.match(/^(\d+)(s|m|h)$/);
148
- if (!match)
149
- return 300_000; // default 5m
150
- const [, num, unit] = match;
151
- const n = parseInt(num, 10);
152
- switch (unit) {
153
- case 's':
154
- return n * 1000;
155
- case 'm':
156
- return n * 60_000;
157
- case 'h':
158
- return n * 3_600_000;
159
- default:
160
- return 300_000;
161
- }
162
- }
163
- //# sourceMappingURL=session.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/modules/session.ts"],"names":[],"mappings":"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"}
@@ -1,39 +0,0 @@
1
- /**
2
- * ATR Rule Scaffolder - Generates ATR rule YAML scaffolds from structured input
3
- * @module agent-threat-rules/rule-scaffolder
4
- */
5
- import type { ATRCategory, ATRSeverity, ATRSourceType } from './types.js';
6
- export interface ScaffoldInput {
7
- title: string;
8
- category: ATRCategory;
9
- severity?: ATRSeverity;
10
- attackDescription: string;
11
- examplePayloads: string[];
12
- agentSourceType?: ATRSourceType;
13
- owaspRefs?: string[];
14
- mitreRefs?: string[];
15
- }
16
- export interface ScaffoldResult {
17
- yaml: string;
18
- id: string;
19
- warnings: string[];
20
- }
21
- export interface ScaffoldOptions {
22
- author?: string;
23
- schemaVersion?: string;
24
- }
25
- export declare class RuleScaffolder {
26
- private readonly options;
27
- constructor(options?: ScaffoldOptions);
28
- /**
29
- * Generate a complete ATR YAML rule from structured input.
30
- * Returns a ScaffoldResult with the YAML string, generated ID, and any warnings.
31
- */
32
- scaffold(input: ScaffoldInput): ScaffoldResult;
33
- /**
34
- * Validate scaffold input, throwing on invalid required fields
35
- * and returning warnings for non-critical issues.
36
- */
37
- private validateInput;
38
- }
39
- //# sourceMappingURL=rule-scaffolder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rule-scaffolder.d.ts","sourceRoot":"","sources":["../src/rule-scaffolder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,aAAa,EAGd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,aAAa,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,OAAO,GAAE,eAAoB;IAOzC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc;IAoF9C;;;OAGG;IACH,OAAO,CAAC,aAAa;CAwBtB"}
@@ -1,171 +0,0 @@
1
- /**
2
- * ATR Rule Scaffolder - Generates ATR rule YAML scaffolds from structured input
3
- * @module agent-threat-rules/rule-scaffolder
4
- */
5
- import yaml from 'js-yaml';
6
- const CATEGORY_TO_SOURCE_TYPE = {
7
- 'prompt-injection': 'llm_io',
8
- 'tool-poisoning': 'tool_call',
9
- 'context-exfiltration': 'context_window',
10
- 'agent-manipulation': 'multi_agent_comm',
11
- 'privilege-escalation': 'agent_behavior',
12
- 'excessive-autonomy': 'agent_behavior',
13
- 'data-poisoning': 'llm_io',
14
- 'model-abuse': 'llm_io',
15
- 'skill-compromise': 'skill_lifecycle',
16
- };
17
- const CATEGORY_TO_FIELD = {
18
- 'prompt-injection': 'user_input',
19
- 'tool-poisoning': 'tool_response',
20
- 'context-exfiltration': 'agent_output',
21
- 'agent-manipulation': 'agent_message',
22
- 'privilege-escalation': 'agent_action',
23
- 'excessive-autonomy': 'agent_action',
24
- 'data-poisoning': 'training_input',
25
- 'model-abuse': 'user_input',
26
- 'skill-compromise': 'skill_manifest',
27
- };
28
- const SEVERITY_TO_ACTIONS = {
29
- critical: ['block_input', 'alert', 'escalate'],
30
- high: ['block_input', 'alert'],
31
- medium: ['alert', 'snapshot'],
32
- low: ['alert'],
33
- informational: ['alert'],
34
- };
35
- const REGEX_SPECIAL_CHARS = /[.*+?^${}()|[\]\\]/g;
36
- function escapeRegex(str) {
37
- return str.replace(REGEX_SPECIAL_CHARS, '\\$&');
38
- }
39
- /**
40
- * Build a case-insensitive regex pattern from a payload string.
41
- * Extracts significant keywords (length > 3) and creates lookahead assertions,
42
- * falling back to a simple escaped match for short payloads.
43
- */
44
- function buildRegexPattern(payload) {
45
- const trimmed = payload.trim();
46
- const words = trimmed.split(/\s+/).filter((w) => w.length > 3);
47
- if (words.length === 0) {
48
- return `(?i).*${escapeRegex(trimmed)}.*`;
49
- }
50
- const keywords = words.slice(0, 4);
51
- return `(?i)${keywords.map((k) => `(?=.*${escapeRegex(k)})`).join('')}`;
52
- }
53
- function generateId() {
54
- const year = new Date().getFullYear();
55
- const seq = String(Math.floor(Math.random() * 900) + 100);
56
- return `ATR-${year}-${seq}`;
57
- }
58
- function getCurrentDate() {
59
- return new Date().toISOString().split('T')[0];
60
- }
61
- export class RuleScaffolder {
62
- options;
63
- constructor(options = {}) {
64
- this.options = {
65
- author: options.author ?? 'ATR Community (auto-scaffolded)',
66
- schemaVersion: options.schemaVersion ?? '0.1',
67
- };
68
- }
69
- /**
70
- * Generate a complete ATR YAML rule from structured input.
71
- * Returns a ScaffoldResult with the YAML string, generated ID, and any warnings.
72
- */
73
- scaffold(input) {
74
- const warnings = this.validateInput(input);
75
- const severity = input.severity ?? 'medium';
76
- const sourceType = input.agentSourceType ?? CATEGORY_TO_SOURCE_TYPE[input.category];
77
- const field = CATEGORY_TO_FIELD[input.category];
78
- const id = generateId();
79
- const date = getCurrentDate();
80
- const conditions = input.examplePayloads.map((payload, idx) => ({
81
- field,
82
- operator: 'regex',
83
- value: buildRegexPattern(payload),
84
- description: `Pattern ${idx + 1}: detects "${payload.trim()}"`,
85
- }));
86
- const truePositives = input.examplePayloads.map((payload) => ({
87
- input: payload.trim(),
88
- expected: 'trigger',
89
- }));
90
- const trueNegatives = [
91
- {
92
- input: 'TODO: Add benign input that should not trigger this rule',
93
- expected: 'no_trigger',
94
- },
95
- ];
96
- const references = {};
97
- if (input.owaspRefs && input.owaspRefs.length > 0) {
98
- references.owasp_llm = [...input.owaspRefs];
99
- }
100
- if (input.mitreRefs && input.mitreRefs.length > 0) {
101
- references.mitre_atlas = [...input.mitreRefs];
102
- }
103
- const conditionExpr = conditions.length > 1 ? 'any' : 'all';
104
- const rule = {
105
- title: input.title,
106
- id,
107
- schema_version: this.options.schemaVersion,
108
- status: 'draft',
109
- description: input.attackDescription,
110
- author: this.options.author,
111
- date,
112
- severity,
113
- detection_tier: 'pattern',
114
- maturity: 'draft',
115
- ...(Object.keys(references).length > 0 ? { references } : {}),
116
- tags: {
117
- category: input.category,
118
- confidence: severity === 'critical' || severity === 'high' ? 'high' : 'medium',
119
- },
120
- agent_source: {
121
- type: sourceType,
122
- },
123
- detection: {
124
- conditions,
125
- condition: conditionExpr,
126
- false_positives: ['TODO: Document known false positive scenarios'],
127
- },
128
- response: {
129
- actions: [...SEVERITY_TO_ACTIONS[severity]],
130
- message_template: `Potential ${input.category} detected: {{matched_patterns}}`,
131
- },
132
- test_cases: {
133
- true_positives: truePositives,
134
- true_negatives: trueNegatives,
135
- },
136
- };
137
- const yamlStr = yaml.dump(rule, {
138
- indent: 2,
139
- lineWidth: 120,
140
- noRefs: true,
141
- sortKeys: false,
142
- quotingType: '"',
143
- forceQuotes: false,
144
- });
145
- return { yaml: yamlStr, id, warnings };
146
- }
147
- /**
148
- * Validate scaffold input, throwing on invalid required fields
149
- * and returning warnings for non-critical issues.
150
- */
151
- validateInput(input) {
152
- const warnings = [];
153
- if (!input.title || input.title.trim().length === 0) {
154
- throw new Error('ScaffoldInput.title is required and must be non-empty');
155
- }
156
- if (!input.category) {
157
- throw new Error('ScaffoldInput.category is required');
158
- }
159
- if (!input.attackDescription || input.attackDescription.trim().length === 0) {
160
- throw new Error('ScaffoldInput.attackDescription is required and must be non-empty');
161
- }
162
- if (!input.examplePayloads || input.examplePayloads.length === 0) {
163
- throw new Error('ScaffoldInput.examplePayloads must contain at least one payload');
164
- }
165
- if (input.examplePayloads.length < 3) {
166
- warnings.push('Fewer than 3 example payloads - consider adding more for better pattern coverage.');
167
- }
168
- return warnings;
169
- }
170
- }
171
- //# sourceMappingURL=rule-scaffolder.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rule-scaffolder.js","sourceRoot":"","sources":["../src/rule-scaffolder.ts"],"names":[],"mappings":"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"}
@@ -1,56 +0,0 @@
1
- /**
2
- * SessionTracker - Tracks per-session state for behavioral detection operators.
3
- *
4
- * Enables multi-turn injection detection, call frequency tracking,
5
- * and pattern repetition counting. All state is internal; public methods
6
- * return copies to preserve immutability.
7
- *
8
- * @module agent-threat-rules/session-tracker
9
- */
10
- import type { AgentEvent } from './types.js';
11
- /** Snapshot of session state returned to callers (immutable copy) */
12
- export interface SessionStateSnapshot {
13
- readonly sessionId: string;
14
- readonly eventCount: number;
15
- readonly oldestEventTimestamp: number | undefined;
16
- readonly newestEventTimestamp: number | undefined;
17
- }
18
- export declare class SessionTracker {
19
- private readonly sessions;
20
- /**
21
- * Record an agent event for the given session.
22
- * Extracts tool name and patterns from event fields/content.
23
- */
24
- recordEvent(sessionId: string, event: AgentEvent, patterns?: readonly string[]): void;
25
- /**
26
- * Get the number of calls to a specific tool within a time window.
27
- */
28
- getCallFrequency(sessionId: string, toolName: string, windowMs: number): number;
29
- /**
30
- * Get the number of times a pattern has been observed within a time window.
31
- */
32
- getPatternFrequency(sessionId: string, pattern: string, windowMs: number): number;
33
- /**
34
- * Get total event count for a session, optionally within a time window.
35
- */
36
- getEventCount(sessionId: string, windowMs?: number): number;
37
- /**
38
- * Get an immutable snapshot of session state. Returns undefined if session does not exist.
39
- */
40
- getSessionSnapshot(sessionId: string): SessionStateSnapshot | undefined;
41
- /**
42
- * Evict sessions that have been inactive longer than maxAgeMs.
43
- * Returns the number of sessions evicted.
44
- */
45
- cleanup(maxAgeMs: number): number;
46
- /** Get the number of tracked sessions */
47
- getSessionCount(): number;
48
- /**
49
- * Ensure we don't exceed the maximum session count.
50
- * Evicts the oldest session if at capacity.
51
- */
52
- private ensureCapacity;
53
- private getOrCreateSession;
54
- private extractToolName;
55
- }
56
- //# sourceMappingURL=session-tracker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-tracker.d.ts","sourceRoot":"","sources":["../src/session-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgB7C,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CACnD;AAWD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAE5D;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,GAAE,SAAS,MAAM,EAAO,GAAG,IAAI;IAkCzF;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAc/E;;OAEG;IACH,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAcjF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAkB3D;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAgBvE;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAcjC,yCAAyC;IACzC,eAAe,IAAI,MAAM;IAIzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,eAAe;CAMxB"}
@@ -1,175 +0,0 @@
1
- /**
2
- * SessionTracker - Tracks per-session state for behavioral detection operators.
3
- *
4
- * Enables multi-turn injection detection, call frequency tracking,
5
- * and pattern repetition counting. All state is internal; public methods
6
- * return copies to preserve immutability.
7
- *
8
- * @module agent-threat-rules/session-tracker
9
- */
10
- /** Maximum number of events stored per session */
11
- const MAX_EVENTS_PER_SESSION = 1000;
12
- /** Maximum number of tracked sessions */
13
- const MAX_SESSIONS = 10_000;
14
- export class SessionTracker {
15
- sessions = new Map();
16
- /**
17
- * Record an agent event for the given session.
18
- * Extracts tool name and patterns from event fields/content.
19
- */
20
- recordEvent(sessionId, event, patterns = []) {
21
- this.ensureCapacity();
22
- const state = this.getOrCreateSession(sessionId);
23
- const toolName = this.extractToolName(event);
24
- const now = Date.now();
25
- const tracked = {
26
- event: Object.freeze({ ...event }),
27
- recordedAt: now,
28
- toolName,
29
- patterns,
30
- };
31
- // Evict oldest if at capacity
32
- if (state.events.length >= MAX_EVENTS_PER_SESSION) {
33
- state.events = state.events.slice(1);
34
- }
35
- state.events = [...state.events, tracked];
36
- state.lastActivityAt = now;
37
- // Update call counts
38
- if (toolName) {
39
- const prev = state.callCounts.get(toolName) ?? 0;
40
- state.callCounts.set(toolName, prev + 1);
41
- }
42
- // Update pattern counts
43
- for (const p of patterns) {
44
- const prev = state.patternCounts.get(p) ?? 0;
45
- state.patternCounts.set(p, prev + 1);
46
- }
47
- }
48
- /**
49
- * Get the number of calls to a specific tool within a time window.
50
- */
51
- getCallFrequency(sessionId, toolName, windowMs) {
52
- const state = this.sessions.get(sessionId);
53
- if (!state)
54
- return 0;
55
- const cutoff = Date.now() - windowMs;
56
- let count = 0;
57
- for (const tracked of state.events) {
58
- if (tracked.recordedAt >= cutoff && tracked.toolName === toolName) {
59
- count++;
60
- }
61
- }
62
- return count;
63
- }
64
- /**
65
- * Get the number of times a pattern has been observed within a time window.
66
- */
67
- getPatternFrequency(sessionId, pattern, windowMs) {
68
- const state = this.sessions.get(sessionId);
69
- if (!state)
70
- return 0;
71
- const cutoff = Date.now() - windowMs;
72
- let count = 0;
73
- for (const tracked of state.events) {
74
- if (tracked.recordedAt >= cutoff && tracked.patterns.includes(pattern)) {
75
- count++;
76
- }
77
- }
78
- return count;
79
- }
80
- /**
81
- * Get total event count for a session, optionally within a time window.
82
- */
83
- getEventCount(sessionId, windowMs) {
84
- const state = this.sessions.get(sessionId);
85
- if (!state)
86
- return 0;
87
- if (windowMs === undefined) {
88
- return state.events.length;
89
- }
90
- const cutoff = Date.now() - windowMs;
91
- let count = 0;
92
- for (const tracked of state.events) {
93
- if (tracked.recordedAt >= cutoff) {
94
- count++;
95
- }
96
- }
97
- return count;
98
- }
99
- /**
100
- * Get an immutable snapshot of session state. Returns undefined if session does not exist.
101
- */
102
- getSessionSnapshot(sessionId) {
103
- const state = this.sessions.get(sessionId);
104
- if (!state)
105
- return undefined;
106
- const oldest = state.events.length > 0 ? state.events[0].recordedAt : undefined;
107
- const newest = state.events.length > 0 ? state.events[state.events.length - 1].recordedAt : undefined;
108
- return Object.freeze({
109
- sessionId,
110
- eventCount: state.events.length,
111
- oldestEventTimestamp: oldest,
112
- newestEventTimestamp: newest,
113
- });
114
- }
115
- /**
116
- * Evict sessions that have been inactive longer than maxAgeMs.
117
- * Returns the number of sessions evicted.
118
- */
119
- cleanup(maxAgeMs) {
120
- const cutoff = Date.now() - maxAgeMs;
121
- let evicted = 0;
122
- for (const [id, state] of this.sessions) {
123
- if (state.lastActivityAt < cutoff) {
124
- this.sessions.delete(id);
125
- evicted++;
126
- }
127
- }
128
- return evicted;
129
- }
130
- /** Get the number of tracked sessions */
131
- getSessionCount() {
132
- return this.sessions.size;
133
- }
134
- /**
135
- * Ensure we don't exceed the maximum session count.
136
- * Evicts the oldest session if at capacity.
137
- */
138
- ensureCapacity() {
139
- if (this.sessions.size < MAX_SESSIONS)
140
- return;
141
- let oldestId;
142
- let oldestTime = Infinity;
143
- for (const [id, state] of this.sessions) {
144
- if (state.lastActivityAt < oldestTime) {
145
- oldestTime = state.lastActivityAt;
146
- oldestId = id;
147
- }
148
- }
149
- if (oldestId) {
150
- this.sessions.delete(oldestId);
151
- }
152
- }
153
- getOrCreateSession(sessionId) {
154
- const existing = this.sessions.get(sessionId);
155
- if (existing)
156
- return existing;
157
- const now = Date.now();
158
- const state = {
159
- events: [],
160
- callCounts: new Map(),
161
- patternCounts: new Map(),
162
- createdAt: now,
163
- lastActivityAt: now,
164
- };
165
- this.sessions.set(sessionId, state);
166
- return state;
167
- }
168
- extractToolName(event) {
169
- if (event.type === 'tool_call' || event.type === 'tool_response') {
170
- return event.fields?.['tool_name'] ?? event.content;
171
- }
172
- return undefined;
173
- }
174
- }
175
- //# sourceMappingURL=session-tracker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session-tracker.js","sourceRoot":"","sources":["../src/session-tracker.ts"],"names":[],"mappings":"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"}