How the Security Executor Ensures Safe Tool Execution in CyberStrikeAI
The Security Executor in CyberStrikeAI guarantees safe tool execution through a defense-in-depth strategy combining configuration-driven whitelisting, strict argument validation, isolated internal-tool dispatch, and secure shell command handling.
The Security Executor is the central enforcement component in the Ed1s0nZ/CyberStrikeAI repository that mediates all security tool execution within the AI-driven platform. Located in internal/security/executor.go, this component ensures that only explicitly enabled tools run, validates every command argument, and isolates internal logic from external system calls.
Configuration-Driven Tool Whitelisting
The executor builds a strict whitelist during initialization to prevent unauthorized tool execution. In NewExecutor, the buildToolIndex function constructs a toolIndex map that provides O(1) lookup for tool configurations. Only tools with Enabled set to true in the security configuration are indexed; disabled or unknown tools are permanently excluded from execution according to the source code in internal/security/executor.go.
Explicit Lookup and Validation
Before any execution, the ExecuteTool method validates tool existence by checking toolConfig, exists := e.toolIndex[toolName]. If the tool is missing from the index, the function returns an error immediately without invoking any command, ensuring that unknown or disabled tools never reach the execution stage.
Isolated System Command Handling
The executor treats raw shell access as a special case to prevent arbitrary command injection. Only the dedicated "exec" tool name routes to executeSystemCommand, preventing arbitrary tools from spawning unrestricted shells. This explicit routing in ExecuteTool ensures that system-level access requires intentional configuration and cannot be triggered by standard security tools.
Command Validation and Audit Logging
The executeSystemCommand function validates that the required command field is present and non-empty. It logs every raw command at the warning level, recording the chosen shell and working directory to create a complete audit trail before execution begins. Missing or empty commands are rejected early in the validation pipeline.
Secure Background Process Detection
To prevent accidental background execution of multi-command pipelines, the isBackgroundCommand function parses command strings to verify that a trailing & is truly a background operator and not part of a quoted argument. This blocks dangerous patterns like cmd1 & cmd2 while allowing legitimate single-command background execution.
Robust PID Extraction for Background Tasks
When background execution is detected, executeSystemCommand wraps the command with cmd & pid=$!; echo $pid to reliably capture the child process ID. If PID extraction fails, the system falls back safely to prevent zombie processes and ensure the executor returns a usable process identifier for process management.
Strict Exit Code Enforcement
After running any external binary, the executor validates the exit code against the AllowedExitCodes list defined in the tool configuration. Only explicitly permitted exit codes are treated as successful execution, preventing tools from silently failing while reporting success to the AI system.
Internal Tool Sandbox
Commands prefixed with internal: are dispatched to executeInternalTool instead of a shell. This keeps logic such as query_execution_result completely in-process, eliminating OS-level execution risks for sensitive operations. These internal tools interact only with the ResultStorage interface set via SetResultStorage, never touching the raw filesystem directly.
Security Executor Implementation Examples
Running Whitelisted Security Tools
To execute a tool like nmap, the executor must be initialized with a valid configuration and registered with the MCP server:
cfg, _ := config.LoadConfig("config.yaml") // loads SecurityConfig
mcpSrv := mcp.NewServer()
logger, _ := zap.NewProduction()
exec := security.NewExecutor(&cfg.Security, mcpSrv, logger)
// Register the tools with the MCP server (makes them callable via AI)
exec.RegisterTools(mcpSrv)
// Example: run nmap with custom arguments (tool must be enabled in config)
result, err := exec.ExecuteTool(context.Background(),
"nmap", map[string]interface{}{
"target": "192.168.1.0/24",
"ports": "80,443",
})
The executor looks up nmap in its toolIndex, builds command arguments via buildCommandArgs, and only launches the process if it passes all validation checks.
Controlled Shell Command Execution
For raw system commands, use the dedicated exec tool which routes through executeSystemCommand:
res, err := exec.ExecuteTool(context.Background(),
"exec", map[string]interface{}{
"command": "ls -l /tmp",
"shell": "bash",
"workdir": "/tmp",
})
This logs the command at warning level, checks for background operators using isBackgroundCommand, and returns combined stdout/stderr. If the command ends with &, the executor captures the spawned PID and returns it in the result.
In-Process Internal Tools
Internal tools run without shell invocation, providing safe access to execution history through the ResultStorage abstraction:
res, err := exec.ExecuteTool(context.Background(),
"query_execution_result", map[string]interface{}{
"execution_id": "abc123",
"page": 1,
"limit": 50,
})
Because the tool name resolves to internal:query_execution_result, the executor calls executeQueryExecutionResult directly, interacting only with the ResultStorage interface and never invoking an external command.
Summary
- The Security Executor maintains an O(1) lookup whitelist in
toolIndexthat excludes any disabled tool from execution. - All tool invocations pass through
ExecuteTool, which validates existence in the index before routing to specialized handlers. - System commands are isolated to the
"exec"tool, withexecuteSystemCommandproviding audit logging, background detection, and secure PID extraction. - Internal tools prefixed with
internal:execute in-process viaexecuteInternalTool, eliminating shell risks and enforcing storage layer isolation. - Exit codes are strictly validated against
AllowedExitCodesto prevent false success reporting. - The architecture implements defense-in-depth: configuration whitelisting → argument validation → execution isolation → result verification.
Frequently Asked Questions
What prevents arbitrary command execution in the Security Executor?
The executor uses a configuration-driven whitelist built by buildToolIndex in internal/security/executor.go. Only tools explicitly enabled in the security configuration are indexed; ExecuteTool checks this index before any execution and returns an error for unknown tools. Additionally, raw shell access is restricted to the dedicated "exec" tool, preventing other tools from spawning arbitrary system commands.
How does the Security Executor handle background processes safely?
The isBackgroundCommand function parses command strings to ensure a trailing & is a true background operator, not part of a quoted argument. For legitimate background commands, executeSystemCommand wraps the execution with cmd & pid=$!; echo $pid to reliably capture the child PID, with safe fallback mechanisms if extraction fails to prevent zombie processes.
What is the difference between external tools and internal tools in CyberStrikeAI?
External tools are compiled binaries or scripts configured in SecurityConfig and executed via shell commands with validated arguments and exit codes. Internal tools are Go functions (like query_execution_result) prefixed with internal: that execute in-process via executeInternalTool, interacting only with the ResultStorage interface and never invoking the operating system shell.
How does the Security Executor prevent tools from failing silently?
After executing any external binary, the executor checks the process exit code against the AllowedExitCodes list defined in the tool's configuration. Only exit codes explicitly defined as successful are treated as passing results; all others trigger error handling, ensuring that tool failures are reported accurately to the AI system.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →