-
-
Notifications
You must be signed in to change notification settings - Fork 39.7k
Description
Feature Request: Tool Execution Hook Events
Repository: https://github.com/openclaw/openclaw
Date: 2026-02-02
Author: Eric (@er587)
Summary
Add tool:before and tool:after hook events to enable audit logging, guardrails, and monitoring of tool executions — especially the exec tool which runs shell commands.
Motivation
Currently, OpenClaw hooks can listen to command events (/new, /reset, /stop) and lifecycle events (gateway:startup, agent:bootstrap), but there's no way to hook into tool executions.
This is a security gap for users who want to:
- Audit logging — Log all shell commands executed by the AI for compliance, debugging, or forensics
- Guardrails — Block or require approval for dangerous commands before execution
- Monitoring — Alert on suspicious patterns (e.g.,
rm -rf,curl | bash, credential access) - Rate limiting — Prevent runaway tool calls
Current Workarounds
| Approach | Limitation |
|---|---|
| Parse session transcripts | Post-hoc only, not real-time |
| Debug logs | Show tool=exec but not the command string |
tool_result_persist plugin |
Synchronous, meant for transform not logging, after-the-fact |
None of these enable real-time interception or logging of tool calls.
Proposed Solution
New Hook Events
tool:before — Fires before a tool executes
tool:after — Fires after a tool completes
Or more granular:
tool:exec:before — Before exec tool specifically
tool:exec:after — After exec tool
tool:read:before — Before file read
tool:write:before — Before file write
tool:message:before — Before sending messages
Event Payload
interface ToolEvent {
type: 'tool';
action: 'before' | 'after';
tool: string; // 'exec', 'read', 'write', 'message', etc.
toolCallId: string;
sessionKey: string;
timestamp: Date;
// Tool-specific payload
arguments: {
command?: string; // For exec
path?: string; // For read/write
// ... other tool args
};
// For 'after' events
result?: {
success: boolean;
output?: string;
error?: string;
durationMs: number;
};
// For guardrails (before events only)
abort?: () => void; // Call to prevent execution
messages: string[]; // Push messages to user
}Example Use Cases
1. Exec Audit Logger
const handler: HookHandler = async (event) => {
if (event.type !== 'tool' || event.tool !== 'exec') return;
const logEntry = {
timestamp: event.timestamp.toISOString(),
sessionKey: event.sessionKey,
command: event.arguments.command,
phase: event.action,
...(event.action === 'after' && {
success: event.result?.success,
durationMs: event.result?.durationMs,
}),
};
await fs.appendFile(
'~/.openclaw/logs/exec-audit.log',
JSON.stringify(logEntry) + '\n'
);
};2. Dangerous Command Guardrail
const DANGEROUS_PATTERNS = [
/rm\s+(-rf?|--recursive)/i,
/curl.*\|\s*(bash|sh)/i,
/>\s*\/etc\//,
/chmod\s+777/,
];
const handler: HookHandler = async (event) => {
if (event.type !== 'tool' || event.tool !== 'exec' || event.action !== 'before') return;
const cmd = event.arguments.command || '';
for (const pattern of DANGEROUS_PATTERNS) {
if (pattern.test(cmd)) {
event.abort?.();
event.messages.push(`⚠️ Blocked dangerous command: ${cmd.slice(0, 50)}...`);
console.warn(`[guardrail] Blocked: ${cmd}`);
return;
}
}
};3. Real-time SIEM Integration
const handler: HookHandler = async (event) => {
if (event.type !== 'tool') return;
// Forward to Security Onion / Splunk / etc.
await fetch(process.env.SIEM_WEBHOOK, {
method: 'POST',
body: JSON.stringify({
event_type: 'openclaw_tool_exec',
tool: event.tool,
command: event.arguments.command,
session: event.sessionKey,
timestamp: event.timestamp.toISOString(),
}),
});
};Implementation Notes
The infrastructure already exists:
- Debug logs already capture
tool=execwithtoolCallIdandrunId - Session transcripts already store full tool call details
- The hook system already supports async handlers with event context
The main work would be:
- Emit events from the tool execution path (likely in
agent/embeddedor tool dispatcher) - Add event types to the hook type definitions
- Document the new events
Alternatives Considered
- Plugin
tool_result_persisthook — Only fires after, synchronous, meant for data transformation not logging - Middleware pattern — More invasive, hooks are cleaner
- External log parsing — Not real-time, misses blocked commands
Priority
High for security-conscious deployments. This enables:
- SOC 2 / compliance audit trails
- Defense-in-depth for self-hosted AI
- Prompt injection mitigation (block suspicious commands)
Would be happy to contribute a PR if the maintainers agree on the approach.