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:
William Valentin
2026-02-06 15:30:34 -08:00
parent 8238d3e981
commit ee0af0cc06
13 changed files with 794 additions and 8 deletions
+14 -1
View File
@@ -5,7 +5,7 @@ import type { ModelClient, RetryConfig } from '../models/index.js';
import { AgentOrchestrator, type DelegationConfig } from '../backends/index.js';
import { SessionStore, SessionManager } from '../session/index.js';
import { HookEngine } from '../hooks/index.js';
import { ToolRegistry, ToolExecutor, allBuiltinTools, createWebSearchTools, createProcessTools, ProcessManager } from '../tools/index.js';
import { ToolRegistry, ToolExecutor, ToolPolicy, allBuiltinTools, createWebSearchTools, createProcessTools, ProcessManager } from '../tools/index.js';
import { MemoryStore } from '../memory/index.js';
import { createMemoryTools } from '../tools/builtin/index.js';
import { GatewayServer } from '../gateway/index.js';
@@ -197,6 +197,10 @@ function createMessageRouter(deps: {
modelName: deps.config.models.default.model,
contextWindow: deps.config.models.default.context_window,
memoryStore: deps.memoryStore,
toolPolicyContext: {
agent: deps.config.agents.primary_tier ?? 'default',
provider: deps.config.models.default.provider,
},
});
agents.set(sessionId, agent);
}
@@ -338,6 +342,15 @@ export async function startDaemon(config: Config): Promise<DaemonContext> {
const toolExecutor = new ToolExecutor(toolRegistry, hookEngine);
// Initialize tool policy from config
const toolPolicy = new ToolPolicy(config.tools);
toolRegistry.setPolicy(toolPolicy);
const effectiveProfile = toolPolicy.getEffectiveProfile();
if (effectiveProfile !== 'full') {
console.log(`Tool policy: profile=${effectiveProfile}, deny=[${config.tools.deny.join(', ')}]`);
}
// Initialize MCP manager and start configured servers
const mcpManager = new McpManager(toolRegistry);