# Security Middleware ## Scope This middleware provides a first-pass hardening layer for agent-executed shell commands and MCP tool usage. ## Components - `src/security/shell-parser.ts` - Uses async `sh-syntax` (mvdan/sh parser) as a hard parser gate before validation. - Performs fail-closed token-level command extraction and blocks unsupported expansions/subshell constructs. - `src/security/schemas.ts` - Zod schemas for shell policies, tool clearance policies, execution env policy, and security violation handling mode. - `src/security/rules-engine.ts` - Enforces: - binary allowlist - cwd boundary (`AGENT_WORKTREE_ROOT`) - argument path boundary and `../` traversal rejection - protected path blocking (`AGENT_STATE_ROOT`, `AGENT_PROJECT_CONTEXT_PATH`) - unified tool allowlist/banlist checks - `src/security/executor.ts` - Runs commands via `child_process.spawn` using explicit env construction (no implicit full parent env inheritance). - Supports timeout enforcement, optional uid/gid drop, and stdout/stderr stream callbacks. - `src/security/audit-log.ts` - File-backed audit sink (`ndjson`) for profiling emitted shell commands and tool access decisions. ## Pipeline behavior `SecurityViolationError` is treated as a first-class error type by `PipelineExecutor`: - `hard_abort` (default): fail fast and stop the pipeline. - `validation_fail`: map violation to retry-unrolled behavior so the actor can attempt a compliant alternative. ## MCP integration `McpRegistry.resolveServerWithHandler(...)` now accepts optional tool clearance and applies it to resolved Codex MCP tool lists (`enabled_tools`, `disabled_tools`). `ActorExecutionInput` now carries an `mcp` execution context with: - `registry`: resolved runtime `McpRegistry` - `resolveConfig(...)`: centralized MCP config resolution with persona tool-clearance applied - `createClaudeCanUseTool()`: helper for Claude SDK `canUseTool` callback so each tool invocation is allowlist/banlist-enforced before execution - Tool matching is case-insensitive at invocation time to handle provider-emitted names like `Bash` versus allowlist entries like `bash`. ## Known limits and TODOs - AST validation is token-based and does not yet model full shell evaluation semantics (e.g. runtime-generated paths from env expansion). - Audit output remains line-oriented file logging; runtime events now mirror security decisions for side-channel analytics and alerting. - Deno sandbox mode is not enforced yet. A future executor mode can wrap shell runs via `deno run` with strict `--allow-read/--allow-run` flags.