matimo 0.1.0-alpha.9 → 0.1.1

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 (168) hide show
  1. package/package.json +10 -8
  2. package/packages/cli/dist/bin.d.ts +3 -0
  3. package/packages/cli/dist/bin.d.ts.map +1 -0
  4. package/packages/cli/dist/bin.js +50 -0
  5. package/packages/cli/dist/bin.js.map +1 -0
  6. package/packages/cli/dist/cli.d.ts.map +1 -1
  7. package/packages/cli/dist/cli.js +64 -2
  8. package/packages/cli/dist/cli.js.map +1 -1
  9. package/packages/cli/dist/commands/doctor.d.ts +2 -0
  10. package/packages/cli/dist/commands/doctor.d.ts.map +1 -0
  11. package/packages/cli/dist/commands/doctor.js +174 -0
  12. package/packages/cli/dist/commands/doctor.js.map +1 -0
  13. package/packages/cli/dist/commands/mcp-setup.d.ts +9 -0
  14. package/packages/cli/dist/commands/mcp-setup.d.ts.map +1 -0
  15. package/packages/cli/dist/commands/mcp-setup.js +106 -0
  16. package/packages/cli/dist/commands/mcp-setup.js.map +1 -0
  17. package/packages/cli/dist/commands/mcp.d.ts +17 -0
  18. package/packages/cli/dist/commands/mcp.d.ts.map +1 -0
  19. package/packages/cli/dist/commands/mcp.js +228 -0
  20. package/packages/cli/dist/commands/mcp.js.map +1 -0
  21. package/packages/cli/dist/commands/review.d.ts +10 -0
  22. package/packages/cli/dist/commands/review.d.ts.map +1 -0
  23. package/packages/cli/dist/commands/review.js +176 -0
  24. package/packages/cli/dist/commands/review.js.map +1 -0
  25. package/packages/core/dist/approval/approval-handler.d.ts +5 -1
  26. package/packages/core/dist/approval/approval-handler.d.ts.map +1 -1
  27. package/packages/core/dist/approval/approval-handler.js +6 -0
  28. package/packages/core/dist/approval/approval-handler.js.map +1 -1
  29. package/packages/core/dist/core/schema.d.ts +41 -10
  30. package/packages/core/dist/core/schema.d.ts.map +1 -1
  31. package/packages/core/dist/core/schema.js +40 -4
  32. package/packages/core/dist/core/schema.js.map +1 -1
  33. package/packages/core/dist/core/skill-content-parser.d.ts +91 -0
  34. package/packages/core/dist/core/skill-content-parser.d.ts.map +1 -0
  35. package/packages/core/dist/core/skill-content-parser.js +248 -0
  36. package/packages/core/dist/core/skill-content-parser.js.map +1 -0
  37. package/packages/core/dist/core/skill-loader.d.ts +46 -0
  38. package/packages/core/dist/core/skill-loader.d.ts.map +1 -0
  39. package/packages/core/dist/core/skill-loader.js +310 -0
  40. package/packages/core/dist/core/skill-loader.js.map +1 -0
  41. package/packages/core/dist/core/skill-registry.d.ts +131 -0
  42. package/packages/core/dist/core/skill-registry.d.ts.map +1 -0
  43. package/packages/core/dist/core/skill-registry.js +316 -0
  44. package/packages/core/dist/core/skill-registry.js.map +1 -0
  45. package/packages/core/dist/core/tfidf-embedding.d.ts +45 -0
  46. package/packages/core/dist/core/tfidf-embedding.d.ts.map +1 -0
  47. package/packages/core/dist/core/tfidf-embedding.js +199 -0
  48. package/packages/core/dist/core/tfidf-embedding.js.map +1 -0
  49. package/packages/core/dist/core/tool-loader.d.ts +3 -1
  50. package/packages/core/dist/core/tool-loader.d.ts.map +1 -1
  51. package/packages/core/dist/core/tool-loader.js +33 -10
  52. package/packages/core/dist/core/tool-loader.js.map +1 -1
  53. package/packages/core/dist/core/types.d.ts +203 -6
  54. package/packages/core/dist/core/types.d.ts.map +1 -1
  55. package/packages/core/dist/encodings/parameter-encoding.d.ts +1 -1
  56. package/packages/core/dist/encodings/parameter-encoding.d.ts.map +1 -1
  57. package/packages/core/dist/encodings/parameter-encoding.js +9 -4
  58. package/packages/core/dist/encodings/parameter-encoding.js.map +1 -1
  59. package/packages/core/dist/errors/matimo-error.d.ts +11 -2
  60. package/packages/core/dist/errors/matimo-error.d.ts.map +1 -1
  61. package/packages/core/dist/errors/matimo-error.js +25 -1
  62. package/packages/core/dist/errors/matimo-error.js.map +1 -1
  63. package/packages/core/dist/executors/command-executor.d.ts +9 -2
  64. package/packages/core/dist/executors/command-executor.d.ts.map +1 -1
  65. package/packages/core/dist/executors/command-executor.js +29 -5
  66. package/packages/core/dist/executors/command-executor.js.map +1 -1
  67. package/packages/core/dist/executors/function-executor.d.ts +10 -3
  68. package/packages/core/dist/executors/function-executor.d.ts.map +1 -1
  69. package/packages/core/dist/executors/function-executor.js +44 -24
  70. package/packages/core/dist/executors/function-executor.js.map +1 -1
  71. package/packages/core/dist/executors/http-executor.d.ts +79 -4
  72. package/packages/core/dist/executors/http-executor.d.ts.map +1 -1
  73. package/packages/core/dist/executors/http-executor.js +232 -28
  74. package/packages/core/dist/executors/http-executor.js.map +1 -1
  75. package/packages/core/dist/index.d.ts +25 -3
  76. package/packages/core/dist/index.d.ts.map +1 -1
  77. package/packages/core/dist/index.js +19 -1
  78. package/packages/core/dist/index.js.map +1 -1
  79. package/packages/core/dist/integrations/langchain.d.ts +55 -0
  80. package/packages/core/dist/integrations/langchain.d.ts.map +1 -1
  81. package/packages/core/dist/integrations/langchain.js +71 -4
  82. package/packages/core/dist/integrations/langchain.js.map +1 -1
  83. package/packages/core/dist/logging/winston-logger.d.ts.map +1 -1
  84. package/packages/core/dist/logging/winston-logger.js +9 -1
  85. package/packages/core/dist/logging/winston-logger.js.map +1 -1
  86. package/packages/core/dist/matimo-instance.d.ts +230 -18
  87. package/packages/core/dist/matimo-instance.d.ts.map +1 -1
  88. package/packages/core/dist/matimo-instance.js +739 -40
  89. package/packages/core/dist/matimo-instance.js.map +1 -1
  90. package/packages/core/dist/mcp/index.d.ts +18 -0
  91. package/packages/core/dist/mcp/index.d.ts.map +1 -0
  92. package/packages/core/dist/mcp/index.js +24 -0
  93. package/packages/core/dist/mcp/index.js.map +1 -0
  94. package/packages/core/dist/mcp/mcp-server.d.ts +141 -0
  95. package/packages/core/dist/mcp/mcp-server.d.ts.map +1 -0
  96. package/packages/core/dist/mcp/mcp-server.js +754 -0
  97. package/packages/core/dist/mcp/mcp-server.js.map +1 -0
  98. package/packages/core/dist/mcp/secrets/aws-resolver.d.ts +41 -0
  99. package/packages/core/dist/mcp/secrets/aws-resolver.d.ts.map +1 -0
  100. package/packages/core/dist/mcp/secrets/aws-resolver.js +141 -0
  101. package/packages/core/dist/mcp/secrets/aws-resolver.js.map +1 -0
  102. package/packages/core/dist/mcp/secrets/dotenv-resolver.d.ts +23 -0
  103. package/packages/core/dist/mcp/secrets/dotenv-resolver.d.ts.map +1 -0
  104. package/packages/core/dist/mcp/secrets/dotenv-resolver.js +94 -0
  105. package/packages/core/dist/mcp/secrets/dotenv-resolver.js.map +1 -0
  106. package/packages/core/dist/mcp/secrets/env-resolver.d.ts +14 -0
  107. package/packages/core/dist/mcp/secrets/env-resolver.d.ts.map +1 -0
  108. package/packages/core/dist/mcp/secrets/env-resolver.js +27 -0
  109. package/packages/core/dist/mcp/secrets/env-resolver.js.map +1 -0
  110. package/packages/core/dist/mcp/secrets/index.d.ts +14 -0
  111. package/packages/core/dist/mcp/secrets/index.d.ts.map +1 -0
  112. package/packages/core/dist/mcp/secrets/index.js +13 -0
  113. package/packages/core/dist/mcp/secrets/index.js.map +1 -0
  114. package/packages/core/dist/mcp/secrets/resolver-chain.d.ts +34 -0
  115. package/packages/core/dist/mcp/secrets/resolver-chain.d.ts.map +1 -0
  116. package/packages/core/dist/mcp/secrets/resolver-chain.js +141 -0
  117. package/packages/core/dist/mcp/secrets/resolver-chain.js.map +1 -0
  118. package/packages/core/dist/mcp/secrets/types.d.ts +73 -0
  119. package/packages/core/dist/mcp/secrets/types.d.ts.map +1 -0
  120. package/packages/core/dist/mcp/secrets/types.js +8 -0
  121. package/packages/core/dist/mcp/secrets/types.js.map +1 -0
  122. package/packages/core/dist/mcp/secrets/vault-resolver.d.ts +43 -0
  123. package/packages/core/dist/mcp/secrets/vault-resolver.d.ts.map +1 -0
  124. package/packages/core/dist/mcp/secrets/vault-resolver.js +127 -0
  125. package/packages/core/dist/mcp/secrets/vault-resolver.js.map +1 -0
  126. package/packages/core/dist/mcp/tool-converter.d.ts +40 -0
  127. package/packages/core/dist/mcp/tool-converter.d.ts.map +1 -0
  128. package/packages/core/dist/mcp/tool-converter.js +185 -0
  129. package/packages/core/dist/mcp/tool-converter.js.map +1 -0
  130. package/packages/core/dist/policy/approval-manifest.d.ts +76 -0
  131. package/packages/core/dist/policy/approval-manifest.d.ts.map +1 -0
  132. package/packages/core/dist/policy/approval-manifest.js +197 -0
  133. package/packages/core/dist/policy/approval-manifest.js.map +1 -0
  134. package/packages/core/dist/policy/content-validator.d.ts +19 -0
  135. package/packages/core/dist/policy/content-validator.d.ts.map +1 -0
  136. package/packages/core/dist/policy/content-validator.js +196 -0
  137. package/packages/core/dist/policy/content-validator.js.map +1 -0
  138. package/packages/core/dist/policy/default-policy.d.ts +46 -0
  139. package/packages/core/dist/policy/default-policy.d.ts.map +1 -0
  140. package/packages/core/dist/policy/default-policy.js +241 -0
  141. package/packages/core/dist/policy/default-policy.js.map +1 -0
  142. package/packages/core/dist/policy/events.d.ts +71 -0
  143. package/packages/core/dist/policy/events.d.ts.map +1 -0
  144. package/packages/core/dist/policy/events.js +8 -0
  145. package/packages/core/dist/policy/events.js.map +1 -0
  146. package/packages/core/dist/policy/index.d.ts +13 -0
  147. package/packages/core/dist/policy/index.d.ts.map +1 -0
  148. package/packages/core/dist/policy/index.js +9 -0
  149. package/packages/core/dist/policy/index.js.map +1 -0
  150. package/packages/core/dist/policy/integrity-tracker.d.ts +62 -0
  151. package/packages/core/dist/policy/integrity-tracker.d.ts.map +1 -0
  152. package/packages/core/dist/policy/integrity-tracker.js +79 -0
  153. package/packages/core/dist/policy/integrity-tracker.js.map +1 -0
  154. package/packages/core/dist/policy/policy-loader.d.ts +58 -0
  155. package/packages/core/dist/policy/policy-loader.d.ts.map +1 -0
  156. package/packages/core/dist/policy/policy-loader.js +156 -0
  157. package/packages/core/dist/policy/policy-loader.js.map +1 -0
  158. package/packages/core/dist/policy/risk-classifier.d.ts +18 -0
  159. package/packages/core/dist/policy/risk-classifier.d.ts.map +1 -0
  160. package/packages/core/dist/policy/risk-classifier.js +47 -0
  161. package/packages/core/dist/policy/risk-classifier.js.map +1 -0
  162. package/packages/core/dist/policy/types.d.ts +131 -0
  163. package/packages/core/dist/policy/types.d.ts.map +1 -0
  164. package/packages/core/dist/policy/types.js +8 -0
  165. package/packages/core/dist/policy/types.js.map +1 -0
  166. package/LICENSE +0 -21
  167. package/README.md +0 -243
  168. package/packages/cli/bin/matimo.cjs +0 -26
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Approval Manifest for Matimo.
3
+ *
4
+ * Manages HMAC-signed approval records for agent-created tools.
5
+ * Prevents agent forgery of approvals via cryptographic verification.
6
+ */
7
+ import { createHmac, randomUUID, createHash } from 'crypto';
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+ import { MatimoError, ErrorCode } from '../errors/matimo-error';
11
+ import { getGlobalMatimoLogger } from '../logging';
12
+ export class ApprovalManifest {
13
+ /**
14
+ * @param approvalDir - Directory where `.matimo-approvals.json` lives
15
+ * @param secret - HMAC secret. If not provided, reads `MATIMO_APPROVAL_SECRET`
16
+ * from env. If that's also missing, generates one and logs it.
17
+ * @param ttlSeconds - Optional TTL in seconds. Approvals older than this are treated as expired.
18
+ */
19
+ constructor(approvalDir, secret, ttlSeconds) {
20
+ this.cache = new Map();
21
+ this.pendingSet = new Set();
22
+ this.ttlSeconds = ttlSeconds;
23
+ this.manifestPath = path.join(approvalDir, '.matimo-approvals.json');
24
+ if (secret) {
25
+ this.secret = secret;
26
+ }
27
+ else if (process.env.MATIMO_APPROVAL_SECRET) {
28
+ this.secret = process.env.MATIMO_APPROVAL_SECRET;
29
+ }
30
+ else {
31
+ if (process.env.NODE_ENV === 'production' || process.env.MATIMO_ENV === 'production') {
32
+ throw new MatimoError('MATIMO_APPROVAL_SECRET is required in production environments. ' +
33
+ 'Set it to a stable, securely generated value (e.g. from a secrets manager).', ErrorCode.AUTH_FAILED);
34
+ }
35
+ this.secret = randomUUID();
36
+ const logger = getGlobalMatimoLogger();
37
+ // Create a non-sensitive fingerprint for debugging (first 4 chars only)
38
+ const fingerprint = this.secret.substring(0, 4);
39
+ logger.warn('No MATIMO_APPROVAL_SECRET set. An ephemeral secret was auto-generated ' +
40
+ '(fingerprint: ' +
41
+ fingerprint +
42
+ '...) ' +
43
+ 'for this process. Approvals may not persist across restarts. ' +
44
+ 'To persist approvals, set MATIMO_APPROVAL_SECRET to a stable, securely ' +
45
+ 'generated value in the environment.');
46
+ }
47
+ this.loadFromDisk();
48
+ }
49
+ /**
50
+ * Compute the HMAC signature for a tool approval.
51
+ */
52
+ sign(toolName, yamlHash) {
53
+ return createHmac('sha256', this.secret).update(`${toolName}:${yamlHash}`).digest('hex');
54
+ }
55
+ /**
56
+ * Compute SHA-256 hash of content.
57
+ */
58
+ computeHash(content) {
59
+ return createHash('sha256').update(content, 'utf8').digest('hex');
60
+ }
61
+ /**
62
+ * Verify that an approval record has a valid HMAC signature and
63
+ * the stored hash matches the current YAML content hash.
64
+ */
65
+ isApproved(toolName, currentYamlHash) {
66
+ const record = this.cache.get(toolName);
67
+ if (!record)
68
+ return false;
69
+ // Hash mismatch = YAML was modified after approval → revoked
70
+ if (record.hash !== currentYamlHash)
71
+ return false;
72
+ // TTL check — if configured, reject approvals older than ttlSeconds
73
+ if (this.ttlSeconds !== undefined) {
74
+ // Fail closed if timestamp is missing or unparsable
75
+ if (!record.approvedAt)
76
+ return false;
77
+ const approvedAt = new Date(record.approvedAt).getTime();
78
+ if (!Number.isFinite(approvedAt))
79
+ return false;
80
+ const ageMs = Date.now() - approvedAt;
81
+ if (ageMs > this.ttlSeconds * 1000)
82
+ return false;
83
+ }
84
+ // Verify HMAC to detect manifest tampering
85
+ const expectedSig = this.sign(toolName, record.hash);
86
+ return record.signature === expectedSig;
87
+ }
88
+ /**
89
+ * Approve a tool. Creates an HMAC-signed record in the manifest.
90
+ */
91
+ approve(toolName, yamlHash, approvedBy) {
92
+ const signature = this.sign(toolName, yamlHash);
93
+ const record = {
94
+ name: toolName,
95
+ hash: yamlHash,
96
+ signature,
97
+ approvedAt: new Date().toISOString(),
98
+ approvedBy,
99
+ };
100
+ this.cache.set(toolName, record);
101
+ this.saveToDisk();
102
+ }
103
+ /**
104
+ * Revoke a tool's approval. Removes from both cache and pendingSet
105
+ * to ensure consistent state (tool no longer tracked as approved or pending).
106
+ */
107
+ revoke(toolName) {
108
+ const cacheDeleted = this.cache.delete(toolName);
109
+ const pendingDeleted = this.pendingSet.delete(toolName);
110
+ if (cacheDeleted || pendingDeleted) {
111
+ this.saveToDisk();
112
+ }
113
+ return cacheDeleted || pendingDeleted;
114
+ }
115
+ /**
116
+ * Get the approval record for a tool.
117
+ */
118
+ getApproval(toolName) {
119
+ return this.cache.get(toolName);
120
+ }
121
+ /**
122
+ * List all approved tool names.
123
+ */
124
+ listApproved() {
125
+ return Array.from(this.cache.keys());
126
+ }
127
+ /**
128
+ * Mark a tool as pending approval. Called by matimo_create_tool after writing to disk.
129
+ */
130
+ markPending(toolName) {
131
+ this.pendingSet.add(toolName);
132
+ this.saveToDisk();
133
+ }
134
+ /**
135
+ * Return all tool names that have been proposed (written to disk) but not yet approved.
136
+ */
137
+ getPendingTools() {
138
+ return Array.from(this.pendingSet).filter((name) => !this.cache.has(name));
139
+ }
140
+ /**
141
+ * Load the manifest file from disk.
142
+ */
143
+ loadFromDisk() {
144
+ try {
145
+ if (!fs.existsSync(this.manifestPath))
146
+ return;
147
+ const raw = fs.readFileSync(this.manifestPath, 'utf-8');
148
+ const data = JSON.parse(raw);
149
+ if (data.version !== '1' || !Array.isArray(data.approvals))
150
+ return;
151
+ this.cache.clear();
152
+ for (const record of data.approvals) {
153
+ if (record.name && record.hash && record.signature) {
154
+ this.cache.set(record.name, record);
155
+ }
156
+ }
157
+ this.pendingSet.clear();
158
+ if (Array.isArray(data.pending)) {
159
+ for (const name of data.pending) {
160
+ if (typeof name === 'string')
161
+ this.pendingSet.add(name);
162
+ }
163
+ }
164
+ }
165
+ catch {
166
+ // Corrupted manifest — start fresh
167
+ const logger = getGlobalMatimoLogger();
168
+ logger.warn('Failed to load approval manifest, starting fresh', {
169
+ path: this.manifestPath,
170
+ });
171
+ this.cache.clear();
172
+ this.pendingSet.clear();
173
+ }
174
+ }
175
+ /**
176
+ * Save current approvals to disk using atomic write pattern.
177
+ * Writes to a temporary file first, then atomically renames it.
178
+ * This prevents data corruption if the process crashes mid-write.
179
+ */
180
+ saveToDisk() {
181
+ const data = {
182
+ version: '1',
183
+ approvals: Array.from(this.cache.values()),
184
+ pending: Array.from(this.pendingSet).filter((name) => !this.cache.has(name)),
185
+ };
186
+ const dir = path.dirname(this.manifestPath);
187
+ if (!fs.existsSync(dir)) {
188
+ fs.mkdirSync(dir, { recursive: true });
189
+ }
190
+ // Atomic write: write to temp file, then rename
191
+ const json = JSON.stringify(data, null, 2);
192
+ const tempPath = path.join(dir, `${path.basename(this.manifestPath)}.tmp-${process.pid}-${Date.now()}`);
193
+ fs.writeFileSync(tempPath, json, 'utf-8');
194
+ fs.renameSync(tempPath, this.manifestPath);
195
+ }
196
+ }
197
+ //# sourceMappingURL=approval-manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-manifest.js","sourceRoot":"","sources":["../../src/policy/approval-manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Content Validator for Matimo tools.
3
+ *
4
+ * Deterministic structural rules that detect malicious or unsafe patterns
5
+ * in agent-created tool definitions. No LLM involved.
6
+ */
7
+ import type { ToolDefinition } from '../core/schema';
8
+ import type { ValidationResult, ValidationContext } from './types';
9
+ /**
10
+ * Validate a tool definition against content safety rules.
11
+ * Returns all violations found (does not short-circuit).
12
+ */
13
+ export declare function validateToolContent(tool: ToolDefinition, context: ValidationContext): ValidationResult;
14
+ /**
15
+ * Check if a URL targets an internal/metadata network (SSRF protection).
16
+ * Handles IPv4, IPv6, and common internal hostnames.
17
+ */
18
+ export declare function isSSRFTarget(url: string): boolean;
19
+ //# sourceMappingURL=content-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-validator.d.ts","sourceRoot":"","sources":["../../src/policy/content-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAa,MAAM,SAAS,CAAC;AAM9E;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,iBAAiB,GACzB,gBAAgB,CAqHlB;AAkBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA4CjD"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Content Validator for Matimo tools.
3
+ *
4
+ * Deterministic structural rules that detect malicious or unsafe patterns
5
+ * in agent-created tool definitions. No LLM involved.
6
+ */
7
+ import { extractAuthPlaceholders } from '../mcp/tool-converter';
8
+ const DEFAULT_ALLOWED_HTTP_METHODS = ['GET', 'POST'];
9
+ const DEFAULT_PROTECTED_NAMESPACES = ['matimo_'];
10
+ /**
11
+ * Validate a tool definition against content safety rules.
12
+ * Returns all violations found (does not short-circuit).
13
+ */
14
+ export function validateToolContent(tool, context) {
15
+ const violations = [];
16
+ const config = context.policy ?? {};
17
+ // Only apply restrictive rules to untrusted sources
18
+ if (context.source !== 'untrusted') {
19
+ return { valid: true, violations: [] };
20
+ }
21
+ // Rule 1: Block execution type: function (arbitrary code)
22
+ if (tool.execution.type === 'function') {
23
+ if (!config.allowFunctionTools) {
24
+ violations.push({
25
+ rule: 'no-function-execution',
26
+ severity: 'critical',
27
+ message: 'Agent-created tools cannot use execution type "function" (arbitrary code execution)',
28
+ });
29
+ }
30
+ }
31
+ // Rule 2: Block execution type: command (shell injection)
32
+ if (tool.execution.type === 'command') {
33
+ if (!config.allowCommandTools) {
34
+ violations.push({
35
+ rule: 'no-command-execution',
36
+ severity: 'critical',
37
+ message: 'Agent-created tools cannot use execution type "command" (shell injection risk)',
38
+ });
39
+ }
40
+ }
41
+ // Rule 3: Block SSRF targets in HTTP URLs
42
+ if (tool.execution.type === 'http') {
43
+ const url = tool.execution.url;
44
+ if (isSSRFTarget(url)) {
45
+ violations.push({
46
+ rule: 'no-ssrf',
47
+ severity: 'critical',
48
+ message: `URL targets internal/metadata network: ${url}`,
49
+ });
50
+ }
51
+ }
52
+ // Rule 4: Block unauthorized credential references
53
+ if (config.allowedCredentials && config.allowedCredentials.length > 0) {
54
+ const referencedVars = extractAuthPlaceholders(tool);
55
+ for (const envVar of referencedVars) {
56
+ if (!config.allowedCredentials.includes(envVar)) {
57
+ violations.push({
58
+ rule: 'unauthorized-credential',
59
+ severity: 'high',
60
+ message: `Tool references credential "${envVar}" not in allowlist`,
61
+ });
62
+ }
63
+ }
64
+ }
65
+ // Rule 5: Block reserved namespaces
66
+ const namespaces = config.protectedNamespaces ?? DEFAULT_PROTECTED_NAMESPACES;
67
+ for (const ns of namespaces) {
68
+ if (tool.name.startsWith(ns)) {
69
+ violations.push({
70
+ rule: 'reserved-namespace',
71
+ severity: 'critical',
72
+ message: `Tool name prefix "${ns}" is reserved for built-in tools`,
73
+ });
74
+ }
75
+ }
76
+ // Rule 6: Force requires_approval on agent-created tools
77
+ if (tool.requires_approval === false || tool.requires_approval === undefined) {
78
+ violations.push({
79
+ rule: 'forced-approval',
80
+ severity: 'high',
81
+ message: 'Agent-created tools must have requires_approval: true',
82
+ });
83
+ }
84
+ // Rule 7: Block disallowed HTTP methods
85
+ if (tool.execution.type === 'http') {
86
+ const allowed = config.allowedHttpMethods ?? DEFAULT_ALLOWED_HTTP_METHODS;
87
+ const method = tool.execution.method.toUpperCase();
88
+ if (!allowed.map((m) => m.toUpperCase()).includes(method)) {
89
+ violations.push({
90
+ rule: 'blocked-http-method',
91
+ severity: 'high',
92
+ message: `HTTP method "${method}" is not in the allowed list: ${allowed.join(', ')}`,
93
+ });
94
+ }
95
+ }
96
+ // Rule 8: Block domains not in allowlist (if configured)
97
+ if (tool.execution.type === 'http' && config.allowedDomains && config.allowedDomains.length > 0) {
98
+ const hostname = extractHostname(tool.execution.url);
99
+ if (hostname &&
100
+ !config.allowedDomains.some((d) => hostname === d || hostname.endsWith(`.${d}`))) {
101
+ violations.push({
102
+ rule: 'blocked-domain',
103
+ severity: 'high',
104
+ message: `URL domain "${hostname}" is not in the allowed list`,
105
+ });
106
+ }
107
+ }
108
+ // Rule 9: Force draft status on agent-created tools
109
+ if (tool.status !== undefined && tool.status !== 'draft') {
110
+ violations.push({
111
+ rule: 'forced-draft-status',
112
+ severity: 'medium',
113
+ message: 'Agent-created tools must have status "draft"',
114
+ });
115
+ }
116
+ return { valid: violations.length === 0, violations };
117
+ }
118
+ /**
119
+ * Replace all {...} placeholder patterns with 'placeholder' string.
120
+ * Uses safe string operations (indexOf) to avoid ReDoS vulnerabilities.
121
+ */
122
+ function cleanUrlPlaceholders(url) {
123
+ let cleaned = url;
124
+ while (true) {
125
+ const start = cleaned.indexOf('{');
126
+ if (start === -1)
127
+ break;
128
+ const end = cleaned.indexOf('}', start);
129
+ if (end === -1)
130
+ break;
131
+ cleaned = cleaned.substring(0, start) + 'placeholder' + cleaned.substring(end + 1);
132
+ }
133
+ return cleaned;
134
+ }
135
+ /**
136
+ * Check if a URL targets an internal/metadata network (SSRF protection).
137
+ * Handles IPv4, IPv6, and common internal hostnames.
138
+ */
139
+ export function isSSRFTarget(url) {
140
+ let hostname;
141
+ try {
142
+ const cleanUrl = cleanUrlPlaceholders(url);
143
+ const parsed = new URL(cleanUrl);
144
+ hostname = parsed.hostname.toLowerCase();
145
+ }
146
+ catch {
147
+ // If URL can't be parsed, it may contain only placeholders — allow it
148
+ return false;
149
+ }
150
+ // Strip IPv6 brackets
151
+ if (hostname.startsWith('[') && hostname.endsWith(']')) {
152
+ hostname = hostname.slice(1, -1);
153
+ }
154
+ // Exact matches
155
+ if (hostname === 'localhost' ||
156
+ hostname === '127.0.0.1' ||
157
+ hostname === '::1' ||
158
+ hostname === '0.0.0.0' ||
159
+ hostname === '0') {
160
+ return true;
161
+ }
162
+ // AWS/cloud metadata endpoint
163
+ if (hostname === '169.254.169.254') {
164
+ return true;
165
+ }
166
+ // Private IPv4 ranges
167
+ if (hostname.startsWith('169.254.'))
168
+ return true;
169
+ if (hostname.startsWith('10.'))
170
+ return true;
171
+ if (hostname.startsWith('192.168.'))
172
+ return true;
173
+ if (/^172\.(1[6-9]|2\d|3[01])\./.test(hostname))
174
+ return true;
175
+ // Internal/local domain suffixes
176
+ if (hostname.endsWith('.internal'))
177
+ return true;
178
+ if (hostname.endsWith('.local'))
179
+ return true;
180
+ if (hostname.endsWith('.localhost'))
181
+ return true;
182
+ return false;
183
+ }
184
+ /**
185
+ * Extract the hostname from a URL string. Returns undefined if unparseable.
186
+ */
187
+ function extractHostname(url) {
188
+ try {
189
+ const cleanUrl = cleanUrlPlaceholders(url);
190
+ return new URL(cleanUrl).hostname.toLowerCase();
191
+ }
192
+ catch {
193
+ return undefined;
194
+ }
195
+ }
196
+ //# sourceMappingURL=content-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-validator.js","sourceRoot":"","sources":["../../src/policy/content-validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,4BAA4B,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACrD,MAAM,4BAA4B,GAAG,CAAC,SAAS,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAoB,EACpB,OAA0B;IAE1B,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IAEpC,oDAAoD;IACpD,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IACzC,CAAC;IAED,0DAA0D;IAC1D,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,uBAAuB;gBAC7B,QAAQ,EAAE,UAAU;gBACpB,OAAO,EACL,qFAAqF;aACxF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,sBAAsB;gBAC5B,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,gFAAgF;aAC1F,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAC/B,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,0CAA0C,GAAG,EAAE;aACzD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,IAAI,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtE,MAAM,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;QACrD,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChD,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,yBAAyB;oBAC/B,QAAQ,EAAE,MAAM;oBAChB,OAAO,EAAE,+BAA+B,MAAM,oBAAoB;iBACnE,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,MAAM,UAAU,GAAG,MAAM,CAAC,mBAAmB,IAAI,4BAA4B,CAAC;IAC9E,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,oBAAoB;gBAC1B,QAAQ,EAAE,UAAU;gBACpB,OAAO,EAAE,qBAAqB,EAAE,kCAAkC;aACnE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,IAAI,CAAC,iBAAiB,KAAK,KAAK,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC7E,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,iBAAiB;YACvB,QAAQ,EAAE,MAAM;YAChB,OAAO,EAAE,uDAAuD;SACjE,CAAC,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,IAAI,4BAA4B,CAAC;QAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1D,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,qBAAqB;gBAC3B,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,gBAAgB,MAAM,iCAAiC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aACrF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChG,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACrD,IACE,QAAQ;YACR,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAChF,CAAC;YACD,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,gBAAgB;gBACtB,QAAQ,EAAE,MAAM;gBAChB,OAAO,EAAE,eAAe,QAAQ,8BAA8B;aAC/D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QACzD,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,qBAAqB;YAC3B,QAAQ,EAAE,QAAQ;YAClB,OAAO,EAAE,8CAA8C;SACxD,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM;QACxB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACrF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;QACtE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,sBAAsB;IACtB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,gBAAgB;IAChB,IACE,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,KAAK;QAClB,QAAQ,KAAK,SAAS;QACtB,QAAQ,KAAK,GAAG,EAChB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,sBAAsB;IACtB,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,4BAA4B,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7D,iCAAiC;IACjC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC3C,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Default Policy Engine for Matimo.
3
+ *
4
+ * Conservative defaults that protect against malicious agent-created tools.
5
+ * Frozen at boot time — agents cannot modify policy at runtime.
6
+ */
7
+ import type { ToolDefinition } from '../core/schema';
8
+ import type { PolicyEngine, PolicyContext, PolicyDecision, PolicyConfig, PolicyTier } from './types';
9
+ export declare class DefaultPolicyEngine implements PolicyEngine {
10
+ private config;
11
+ constructor(config?: PolicyConfig);
12
+ /**
13
+ * Check whether a tool definition may be created/proposed.
14
+ * First applies the tier gate (fast early-return for TIER 3 blocked tools),
15
+ * then runs ContentValidator rules.
16
+ */
17
+ canCreate(context: PolicyContext, toolDef: ToolDefinition): PolicyDecision;
18
+ /**
19
+ * Check whether the caller is allowed to execute a given tool.
20
+ */
21
+ canExecute(context: PolicyContext, tool: ToolDefinition): PolicyDecision;
22
+ /**
23
+ * Filter tools to only those the caller is allowed to see and use.
24
+ */
25
+ filterForAgent(context: PolicyContext, tools: ToolDefinition[]): ToolDefinition[];
26
+ /** Expose the resolved config (read-only snapshot). */
27
+ getConfig(): Readonly<Required<Omit<PolicyConfig, 'approvalTtlSeconds'>> & Pick<PolicyConfig, 'approvalTtlSeconds'>>;
28
+ /**
29
+ * Hot-reload policy configuration at runtime.
30
+ * Merges the new config with DEFAULT_CONFIG (preserving conservative defaults
31
+ * for any unset fields), then replaces the active config atomically.
32
+ */
33
+ updateConfig(config: PolicyConfig): void;
34
+ }
35
+ /**
36
+ * Pure utility: classify an agent-proposed tool into a policy tier.
37
+ *
38
+ * - `blocked`: reserved namespace, function/command execution type, SSRF URL
39
+ * - `approval-required`: any auth credential, non-GET HTTP method, any data write
40
+ * - `auto`: low-risk read-only HTTP GET with no auth
41
+ *
42
+ * This runs BEFORE content validation and is a hard gate — `blocked` tools
43
+ * are rejected immediately without running the full content-validator.
44
+ */
45
+ export declare function getTierForTool(tool: ToolDefinition, config?: PolicyConfig): PolicyTier;
46
+ //# sourceMappingURL=default-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-policy.d.ts","sourceRoot":"","sources":["../../src/policy/default-policy.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,UAAU,EAEX,MAAM,SAAS,CAAC;AAiBjB,qBAAa,mBAAoB,YAAW,YAAY;IACtD,OAAO,CAAC,MAAM,CAC6B;gBAE/B,MAAM,CAAC,EAAE,YAAY;IAIjC;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,cAAc;IAuG1E;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,GAAG,cAAc;IA8CxE;;OAEG;IACH,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE;IAOjF,uDAAuD;IACvD,SAAS,IAAI,QAAQ,CACnB,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAC9F;IAID;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;CAGzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,UAAU,CAsBtF"}