feat: add tool allow/deny profiles with per-agent and per-provider filtering
Implements configurable tool filtering with four built-in profiles (minimal, messaging, coding, full), global and per-agent/per-provider allow/deny lists with glob pattern support, and defense-in-depth enforcement at both tool listing and execution time. New: src/tools/policy.ts (ToolPolicy engine), src/tools/policy.test.ts (37 tests) Modified: config schema, tool registry, tool executor, NativeAgent, AgentOrchestrator, daemon wiring, gateway tool handler, test mocks
This commit is contained in:
+15
-1
@@ -1,6 +1,7 @@
|
||||
import type { ToolResult } from './types.js';
|
||||
import type { ToolRegistry } from './registry.js';
|
||||
import type { HookEngine } from '../hooks/engine.js';
|
||||
import type { ToolPolicyContext } from './policy.js';
|
||||
|
||||
export interface ToolExecutorConfig {
|
||||
defaultTimeoutMs?: number;
|
||||
@@ -20,12 +21,25 @@ export class ToolExecutor {
|
||||
this.maxOutputBytes = config?.maxOutputBytes ?? 51_200;
|
||||
}
|
||||
|
||||
async execute(toolName: string, args: unknown): Promise<ToolResult> {
|
||||
async execute(toolName: string, args: unknown, context?: ToolPolicyContext): Promise<ToolResult> {
|
||||
const tool = this.registry.get(toolName);
|
||||
if (!tool) {
|
||||
return { success: false, output: '', error: `Tool '${toolName}' not found` };
|
||||
}
|
||||
|
||||
// Policy check (defense in depth — tools should also be filtered at listing time)
|
||||
const policy = this.registry.getPolicy();
|
||||
if (policy) {
|
||||
const allNames = this.registry.list().map(t => t.name);
|
||||
if (!policy.isAllowed(toolName, allNames, context)) {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: `Tool '${toolName}' is not allowed by tool policy`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Check hooks
|
||||
const action = this.hooks.getAction(toolName);
|
||||
if (action === 'confirm') {
|
||||
|
||||
Reference in New Issue
Block a user