cbrowser 18.3.10 → 18.3.12
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-server-remote.d.ts.map +1 -1
- package/dist/mcp-server-remote.js +8 -1
- package/dist/mcp-server-remote.js.map +1 -1
- package/dist/mcp-tools/base/index.d.ts +4 -2
- package/dist/mcp-tools/base/index.d.ts.map +1 -1
- package/dist/mcp-tools/base/index.js +7 -2
- package/dist/mcp-tools/base/index.js.map +1 -1
- package/dist/mcp-tools/base/security-tools.d.ts +12 -0
- package/dist/mcp-tools/base/security-tools.d.ts.map +1 -0
- package/dist/mcp-tools/base/security-tools.js +85 -0
- package/dist/mcp-tools/base/security-tools.js.map +1 -0
- package/dist/security/audit-wrapper.d.ts +148 -0
- package/dist/security/audit-wrapper.d.ts.map +1 -0
- package/dist/security/audit-wrapper.js +433 -0
- package/dist/security/audit-wrapper.js.map +1 -0
- package/dist/security/description-scanner.d.ts +132 -0
- package/dist/security/description-scanner.d.ts.map +1 -0
- package/dist/security/description-scanner.js +408 -0
- package/dist/security/description-scanner.js.map +1 -0
- package/dist/security/index.d.ts +23 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +29 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/output-sanitizer.d.ts +132 -0
- package/dist/security/output-sanitizer.d.ts.map +1 -0
- package/dist/security/output-sanitizer.js +344 -0
- package/dist/security/output-sanitizer.js.map +1 -0
- package/dist/security/request-signing.d.ts +53 -0
- package/dist/security/request-signing.d.ts.map +1 -0
- package/dist/security/request-signing.js +142 -0
- package/dist/security/request-signing.js.map +1 -0
- package/dist/security/tool-permissions.d.ts +96 -0
- package/dist/security/tool-permissions.d.ts.map +1 -0
- package/dist/security/tool-permissions.js +317 -0
- package/dist/security/tool-permissions.js.map +1 -0
- package/dist/security/tool-pinning.d.ts +143 -0
- package/dist/security/tool-pinning.d.ts.map +1 -0
- package/dist/security/tool-pinning.js +302 -0
- package/dist/security/tool-pinning.js.map +1 -0
- package/dist/types.d.ts +26 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/docs/SECURITY_WHITEPAPER.md +469 -0
- package/package.json +1 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBrowser - Cognitive Browser Automation
|
|
3
|
+
* Copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com
|
|
4
|
+
* Learn more at https://cbrowser.ai - MIT License
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Per-Tool Permission Model for CBrowser MCP Server
|
|
8
|
+
*
|
|
9
|
+
* Provides granular permission control for MCP tools based on security zones.
|
|
10
|
+
* Users can override default zone assignments to customize tool access.
|
|
11
|
+
*
|
|
12
|
+
* Zone Levels:
|
|
13
|
+
* - GREEN: Read-only, always safe - auto-execute
|
|
14
|
+
* - YELLOW: Interactive but safe - allowed, no confirmation
|
|
15
|
+
* - ORANGE: State-modifying - allowed with warning
|
|
16
|
+
* - RED: Sensitive/Autonomous - requires --force flag
|
|
17
|
+
* - BLACK: Prohibited - always blocked, even with --force
|
|
18
|
+
*
|
|
19
|
+
* Storage: ~/.cbrowser/tool-permissions.json
|
|
20
|
+
*/
|
|
21
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
import { join } from "node:path";
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Default Zone Assignments
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Default zone assignments for CBrowser tools.
|
|
29
|
+
* Conservative by default - unknown tools are classified as YELLOW.
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_ZONES = {
|
|
32
|
+
// =========================================================================
|
|
33
|
+
// GREEN - Read-only, always safe
|
|
34
|
+
// =========================================================================
|
|
35
|
+
navigate: "green",
|
|
36
|
+
screenshot: "green",
|
|
37
|
+
extract: "green",
|
|
38
|
+
status: "green",
|
|
39
|
+
list_sessions: "green",
|
|
40
|
+
list_baselines: "green",
|
|
41
|
+
list_cognitive_personas: "green",
|
|
42
|
+
list_influence_patterns: "green",
|
|
43
|
+
persona_traits_list: "green",
|
|
44
|
+
persona_values_lookup: "green",
|
|
45
|
+
persona_trait_lookup: "green",
|
|
46
|
+
visual_baseline: "green",
|
|
47
|
+
heal_stats: "green",
|
|
48
|
+
stealth_status: "green",
|
|
49
|
+
stealth_check: "green",
|
|
50
|
+
browser_health: "green",
|
|
51
|
+
perf_baseline: "green",
|
|
52
|
+
ab_comparison: "green",
|
|
53
|
+
coverage_map: "green",
|
|
54
|
+
compare_personas_init: "green",
|
|
55
|
+
compare_personas_complete: "green",
|
|
56
|
+
competitive_benchmark: "green",
|
|
57
|
+
cross_browser_diff: "green",
|
|
58
|
+
agent_ready_audit: "green",
|
|
59
|
+
empathy_audit: "green",
|
|
60
|
+
api_key_status: "green",
|
|
61
|
+
get_api_key_prompt: "green",
|
|
62
|
+
marketing_discover_status: "green",
|
|
63
|
+
marketing_personas_list: "green",
|
|
64
|
+
// =========================================================================
|
|
65
|
+
// YELLOW - Interactive but safe
|
|
66
|
+
// =========================================================================
|
|
67
|
+
click: "yellow",
|
|
68
|
+
hover: "yellow",
|
|
69
|
+
scroll: "yellow",
|
|
70
|
+
assert: "yellow",
|
|
71
|
+
analyze_page: "yellow",
|
|
72
|
+
find_element_by_intent: "yellow",
|
|
73
|
+
dismiss_overlay: "yellow",
|
|
74
|
+
compare_personas: "yellow",
|
|
75
|
+
cloudflare_detect: "yellow",
|
|
76
|
+
cloudflare_wait: "yellow",
|
|
77
|
+
persona_category_guidance: "yellow",
|
|
78
|
+
persona_questionnaire_get: "yellow",
|
|
79
|
+
load_session: "yellow",
|
|
80
|
+
visual_regression: "yellow",
|
|
81
|
+
perf_regression: "yellow",
|
|
82
|
+
responsive_test: "yellow",
|
|
83
|
+
cross_browser_test: "yellow",
|
|
84
|
+
// =========================================================================
|
|
85
|
+
// ORANGE - State-modifying
|
|
86
|
+
// =========================================================================
|
|
87
|
+
fill: "orange",
|
|
88
|
+
smart_click: "orange",
|
|
89
|
+
save_session: "orange",
|
|
90
|
+
delete_session: "orange",
|
|
91
|
+
reset_browser: "orange",
|
|
92
|
+
browser_recover: "orange",
|
|
93
|
+
persona_create_start: "orange",
|
|
94
|
+
persona_create_submit_traits: "orange",
|
|
95
|
+
persona_create_from_description: "orange",
|
|
96
|
+
persona_create_questionnaire_start: "orange",
|
|
97
|
+
persona_create_questionnaire_answer: "orange",
|
|
98
|
+
persona_questionnaire_build: "orange",
|
|
99
|
+
persona_create_cancel: "orange",
|
|
100
|
+
cognitive_journey_init: "orange",
|
|
101
|
+
cognitive_journey_update_state: "orange",
|
|
102
|
+
nl_test_inline: "orange",
|
|
103
|
+
nl_test_file: "orange",
|
|
104
|
+
generate_tests: "orange",
|
|
105
|
+
repair_test: "orange",
|
|
106
|
+
detect_flaky_tests: "orange",
|
|
107
|
+
hunt_bugs: "orange",
|
|
108
|
+
marketing_audience_discover: "orange",
|
|
109
|
+
marketing_campaign_create: "orange",
|
|
110
|
+
marketing_campaign_run: "orange",
|
|
111
|
+
marketing_campaign_report_result: "orange",
|
|
112
|
+
marketing_compete: "orange",
|
|
113
|
+
marketing_funnel_analyze: "orange",
|
|
114
|
+
marketing_influence_matrix: "orange",
|
|
115
|
+
marketing_lever_analysis: "orange",
|
|
116
|
+
// =========================================================================
|
|
117
|
+
// RED - Sensitive/Autonomous (requires --force)
|
|
118
|
+
// =========================================================================
|
|
119
|
+
cognitive_journey_autonomous: "red",
|
|
120
|
+
stealth_enable: "red",
|
|
121
|
+
stealth_disable: "red",
|
|
122
|
+
stealth_diagnose: "red",
|
|
123
|
+
chaos_test: "red",
|
|
124
|
+
set_api_key: "red",
|
|
125
|
+
clear_api_key: "red",
|
|
126
|
+
ask_user: "red", // Can be used for social engineering
|
|
127
|
+
};
|
|
128
|
+
// Valid zone values for validation
|
|
129
|
+
const VALID_ZONES = new Set(["green", "yellow", "orange", "red", "black"]);
|
|
130
|
+
// ============================================================================
|
|
131
|
+
// File Path Utilities
|
|
132
|
+
// ============================================================================
|
|
133
|
+
/**
|
|
134
|
+
* Get the path to the tool permissions file.
|
|
135
|
+
*/
|
|
136
|
+
function getPermissionsPath() {
|
|
137
|
+
const dataDir = process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
|
|
138
|
+
return join(dataDir, "tool-permissions.json");
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Ensure the data directory exists.
|
|
142
|
+
*/
|
|
143
|
+
function ensureDataDir() {
|
|
144
|
+
const dataDir = process.env.CBROWSER_DATA_DIR || join(homedir(), ".cbrowser");
|
|
145
|
+
if (!existsSync(dataDir)) {
|
|
146
|
+
mkdirSync(dataDir, { recursive: true });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Configuration Functions
|
|
151
|
+
// ============================================================================
|
|
152
|
+
/**
|
|
153
|
+
* Load tool permissions from file.
|
|
154
|
+
*
|
|
155
|
+
* @returns The permission config, or null if no file exists or file is invalid
|
|
156
|
+
*/
|
|
157
|
+
export function loadToolPermissions() {
|
|
158
|
+
const path = getPermissionsPath();
|
|
159
|
+
if (!existsSync(path)) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
const content = readFileSync(path, "utf-8");
|
|
164
|
+
if (!content.trim()) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const config = JSON.parse(content);
|
|
168
|
+
// Validate the structure
|
|
169
|
+
if (!config.toolPermissions || typeof config.toolPermissions !== "object") {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
return config;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Save tool permissions to file.
|
|
180
|
+
*
|
|
181
|
+
* @param config The permission config to save
|
|
182
|
+
*/
|
|
183
|
+
export function saveToolPermissions(config) {
|
|
184
|
+
ensureDataDir();
|
|
185
|
+
const path = getPermissionsPath();
|
|
186
|
+
writeFileSync(path, JSON.stringify(config, null, 2));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Set the zone for a specific tool.
|
|
190
|
+
* Creates the permission file if it doesn't exist.
|
|
191
|
+
*
|
|
192
|
+
* @param tool The tool name
|
|
193
|
+
* @param zone The zone to assign
|
|
194
|
+
*/
|
|
195
|
+
export function setToolZone(tool, zone) {
|
|
196
|
+
let config = loadToolPermissions();
|
|
197
|
+
if (!config) {
|
|
198
|
+
config = {
|
|
199
|
+
toolPermissions: {},
|
|
200
|
+
lastUpdated: new Date().toISOString(),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
config.toolPermissions[tool] = zone;
|
|
204
|
+
config.lastUpdated = new Date().toISOString();
|
|
205
|
+
saveToolPermissions(config);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Get the zone for a tool.
|
|
209
|
+
* Returns user override if set, otherwise returns default zone.
|
|
210
|
+
* Unknown tools default to YELLOW (conservative).
|
|
211
|
+
*
|
|
212
|
+
* @param tool The tool name
|
|
213
|
+
* @returns The zone classification
|
|
214
|
+
*/
|
|
215
|
+
export function getToolZone(tool) {
|
|
216
|
+
// Check for user override first
|
|
217
|
+
const config = loadToolPermissions();
|
|
218
|
+
if (config?.toolPermissions[tool]) {
|
|
219
|
+
const userZone = config.toolPermissions[tool];
|
|
220
|
+
// Validate the zone is valid
|
|
221
|
+
if (VALID_ZONES.has(userZone)) {
|
|
222
|
+
return userZone;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Fall back to default
|
|
226
|
+
return DEFAULT_ZONES[tool] || "yellow";
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Check if a tool is allowed to execute based on its zone.
|
|
230
|
+
*
|
|
231
|
+
* @param tool The tool name
|
|
232
|
+
* @param forceFlag Whether the --force flag was provided
|
|
233
|
+
* @returns Permission check result
|
|
234
|
+
*/
|
|
235
|
+
export function checkToolPermission(tool, forceFlag = false) {
|
|
236
|
+
const config = loadToolPermissions();
|
|
237
|
+
const hasOverride = config?.toolPermissions[tool] && VALID_ZONES.has(config.toolPermissions[tool]);
|
|
238
|
+
const zone = getToolZone(tool);
|
|
239
|
+
const source = hasOverride ? "user_override" : "default";
|
|
240
|
+
const result = {
|
|
241
|
+
tool,
|
|
242
|
+
zone,
|
|
243
|
+
source,
|
|
244
|
+
allowed: false,
|
|
245
|
+
requiresForce: false,
|
|
246
|
+
};
|
|
247
|
+
switch (zone) {
|
|
248
|
+
case "green":
|
|
249
|
+
// Always allowed, no restrictions
|
|
250
|
+
result.allowed = true;
|
|
251
|
+
result.requiresForce = false;
|
|
252
|
+
break;
|
|
253
|
+
case "yellow":
|
|
254
|
+
// Allowed without confirmation
|
|
255
|
+
result.allowed = true;
|
|
256
|
+
result.requiresForce = false;
|
|
257
|
+
break;
|
|
258
|
+
case "orange":
|
|
259
|
+
// Allowed with warning
|
|
260
|
+
result.allowed = true;
|
|
261
|
+
result.requiresForce = false;
|
|
262
|
+
result.message = `Tool '${tool}' is state-modifying (orange zone). Proceeding with caution.`;
|
|
263
|
+
break;
|
|
264
|
+
case "red":
|
|
265
|
+
// Requires --force flag
|
|
266
|
+
result.requiresForce = true;
|
|
267
|
+
if (forceFlag) {
|
|
268
|
+
result.allowed = true;
|
|
269
|
+
result.message = `Tool '${tool}' is sensitive (red zone). Executing with --force override.`;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
result.allowed = false;
|
|
273
|
+
result.message = `Tool '${tool}' is classified as RED (sensitive/autonomous). Use --force flag to execute.`;
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
case "black":
|
|
277
|
+
// Always blocked, even with --force
|
|
278
|
+
result.allowed = false;
|
|
279
|
+
result.requiresForce = false;
|
|
280
|
+
result.message = `Tool '${tool}' is prohibited (black zone). This action is not allowed.`;
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
return result;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* List all tool zones (both defaults and overrides).
|
|
287
|
+
*
|
|
288
|
+
* @returns Map of tool names to zone info
|
|
289
|
+
*/
|
|
290
|
+
export function listToolZones() {
|
|
291
|
+
const result = {};
|
|
292
|
+
// Add all default zones
|
|
293
|
+
for (const [tool, zone] of Object.entries(DEFAULT_ZONES)) {
|
|
294
|
+
result[tool] = { zone, source: "default" };
|
|
295
|
+
}
|
|
296
|
+
// Overlay user overrides
|
|
297
|
+
const config = loadToolPermissions();
|
|
298
|
+
if (config?.toolPermissions) {
|
|
299
|
+
for (const [tool, zone] of Object.entries(config.toolPermissions)) {
|
|
300
|
+
if (VALID_ZONES.has(zone)) {
|
|
301
|
+
result[tool] = { zone, source: "user_override" };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Reset all tool zones to defaults.
|
|
309
|
+
* Removes the permission file entirely.
|
|
310
|
+
*/
|
|
311
|
+
export function resetToolZones() {
|
|
312
|
+
const path = getPermissionsPath();
|
|
313
|
+
if (existsSync(path)) {
|
|
314
|
+
rmSync(path);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
//# sourceMappingURL=tool-permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../../src/security/tool-permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBrowser - Cognitive Browser Automation
|
|
3
|
+
* Copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com
|
|
4
|
+
* Learn more at https://cbrowser.ai - MIT License
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A tool definition for pinning purposes.
|
|
8
|
+
* Extracted from MCP server tool registration.
|
|
9
|
+
*/
|
|
10
|
+
export interface ToolDefinition {
|
|
11
|
+
/** Tool name (unique identifier) */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Tool description */
|
|
14
|
+
description: string;
|
|
15
|
+
/** Tool input schema (Zod schema converted to JSON Schema) */
|
|
16
|
+
schema: unknown;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Entry for a single pinned tool in the manifest.
|
|
20
|
+
*/
|
|
21
|
+
export interface ToolPinEntry {
|
|
22
|
+
/** SHA-256 hash of name + description + JSON.stringify(schema) */
|
|
23
|
+
hash: string;
|
|
24
|
+
/** Length of description (for quick diff detection) */
|
|
25
|
+
descriptionLength: number;
|
|
26
|
+
/** Number of parameters in schema (for quick diff detection) */
|
|
27
|
+
parameterCount: number;
|
|
28
|
+
/** ISO timestamp when this tool was pinned */
|
|
29
|
+
pinnedAt: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The complete tool manifest stored on disk.
|
|
33
|
+
*/
|
|
34
|
+
export interface ToolManifest {
|
|
35
|
+
/** Server identifier */
|
|
36
|
+
server: string;
|
|
37
|
+
/** CBrowser version that created this manifest */
|
|
38
|
+
version: string;
|
|
39
|
+
/** ISO timestamp when manifest was created */
|
|
40
|
+
pinnedAt: string;
|
|
41
|
+
/** Map of tool name -> pin entry */
|
|
42
|
+
tools: Record<string, ToolPinEntry>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Result of verifying tool definitions against the manifest.
|
|
46
|
+
*/
|
|
47
|
+
export interface PinningResult {
|
|
48
|
+
/** Overall status */
|
|
49
|
+
status: "created" | "verified" | "changed" | "error";
|
|
50
|
+
/** Tools that have different hashes than pinned */
|
|
51
|
+
changedTools?: string[];
|
|
52
|
+
/** Tools present in definitions but not in manifest */
|
|
53
|
+
newTools?: string[];
|
|
54
|
+
/** Tools in manifest but not in definitions */
|
|
55
|
+
removedTools?: string[];
|
|
56
|
+
/** Human-readable message */
|
|
57
|
+
message: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the path to the tool manifest file.
|
|
61
|
+
* Uses ~/.cbrowser/tool-manifest.json by default.
|
|
62
|
+
*/
|
|
63
|
+
export declare function getManifestPath(): string;
|
|
64
|
+
/**
|
|
65
|
+
* Create a SHA-256 hash of a tool definition.
|
|
66
|
+
*
|
|
67
|
+
* The hash includes:
|
|
68
|
+
* - Tool name
|
|
69
|
+
* - Tool description
|
|
70
|
+
* - JSON-stringified schema (sorted keys for consistency)
|
|
71
|
+
*
|
|
72
|
+
* @param name - Tool name
|
|
73
|
+
* @param description - Tool description
|
|
74
|
+
* @param schema - Tool schema object
|
|
75
|
+
* @returns 64-character hex SHA-256 hash
|
|
76
|
+
*/
|
|
77
|
+
export declare function hashToolDefinition(name: string, description: string, schema: unknown): string;
|
|
78
|
+
/**
|
|
79
|
+
* Create a new tool manifest from a list of tool definitions.
|
|
80
|
+
*
|
|
81
|
+
* @param tools - Array of tool definitions
|
|
82
|
+
* @returns Complete manifest ready for saving
|
|
83
|
+
*/
|
|
84
|
+
export declare function createToolManifest(tools: ToolDefinition[]): ToolManifest;
|
|
85
|
+
/**
|
|
86
|
+
* Load the tool manifest from disk.
|
|
87
|
+
*
|
|
88
|
+
* @returns Manifest if it exists and is valid, null otherwise
|
|
89
|
+
*/
|
|
90
|
+
export declare function loadToolManifest(): ToolManifest | null;
|
|
91
|
+
/**
|
|
92
|
+
* Save a tool manifest to disk.
|
|
93
|
+
* Creates the directory if it doesn't exist.
|
|
94
|
+
*
|
|
95
|
+
* @param manifest - The manifest to save
|
|
96
|
+
*/
|
|
97
|
+
export declare function saveToolManifest(manifest: ToolManifest): void;
|
|
98
|
+
/**
|
|
99
|
+
* Verify tool definitions against the pinned manifest.
|
|
100
|
+
*
|
|
101
|
+
* Behavior:
|
|
102
|
+
* - If no manifest exists: Creates one and returns status "created"
|
|
103
|
+
* - If all hashes match: Returns status "verified"
|
|
104
|
+
* - If any differences: Returns status "changed" with details
|
|
105
|
+
*
|
|
106
|
+
* @param tools - Current tool definitions from MCP server
|
|
107
|
+
* @returns Verification result
|
|
108
|
+
*/
|
|
109
|
+
export declare function verifyToolDefinitions(tools: ToolDefinition[]): PinningResult;
|
|
110
|
+
/**
|
|
111
|
+
* Approve a tool change by updating its hash in the manifest.
|
|
112
|
+
* Used to re-approve a tool after intentional modification.
|
|
113
|
+
*
|
|
114
|
+
* @param toolName - Name of the tool to approve
|
|
115
|
+
* @param tool - Current tool definition
|
|
116
|
+
* @throws Error if no manifest exists
|
|
117
|
+
*/
|
|
118
|
+
export declare function approveToolChange(toolName: string, tool: ToolDefinition): void;
|
|
119
|
+
/**
|
|
120
|
+
* Remove a tool from the manifest.
|
|
121
|
+
* Used when a tool is intentionally removed.
|
|
122
|
+
*
|
|
123
|
+
* @param toolName - Name of the tool to remove
|
|
124
|
+
* @throws Error if no manifest exists
|
|
125
|
+
*/
|
|
126
|
+
export declare function removeToolFromManifest(toolName: string): void;
|
|
127
|
+
/**
|
|
128
|
+
* Approve all current tools, replacing the entire manifest.
|
|
129
|
+
* Use with caution - this trusts the current state completely.
|
|
130
|
+
*
|
|
131
|
+
* @param tools - Current tool definitions
|
|
132
|
+
*/
|
|
133
|
+
export declare function approveAllTools(tools: ToolDefinition[]): void;
|
|
134
|
+
/**
|
|
135
|
+
* Get a summary of the current manifest for status display.
|
|
136
|
+
*/
|
|
137
|
+
export declare function getManifestSummary(): {
|
|
138
|
+
exists: boolean;
|
|
139
|
+
toolCount: number;
|
|
140
|
+
version: string | null;
|
|
141
|
+
pinnedAt: string | null;
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=tool-pinning.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-pinning.d.ts","sourceRoot":"","sources":["../../src/security/tool-pinning.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmCH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;IACrD,mDAAmD;IACnD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,MAAM,CASR;AAiCD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,YAAY,CAmBxE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,GAAG,IAAI,CAsBtD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAU7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,aAAa,CA0E5E;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAiB9E;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAW7D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAG7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAkBA"}
|