How It Works

Interception mechanism

The Faramesh plugin uses OpenClaw's before_tool_call hook to intercept every tool call before execution.

Hook registration

api.on("before_tool_call", async (event, ctx) => {
  // event.toolName — the tool being called
  // event.params — the parameters
  // ctx.agentId — the agent making the call
  // ctx.sessionKey — the session key

  const result = await checkFaramesh(event.toolName, event.params, ctx);

  if (result.blocked) {
    return { block: true, blockReason: result.reason };
  }
  return undefined; // allow
}, { priority: 1000 });
api.on("before_tool_call", async (event, ctx) => {
  // event.toolName — the tool being called
  // event.params — the parameters
  // ctx.agentId — the agent making the call
  // ctx.sessionKey — the session key

  const result = await checkFaramesh(event.toolName, event.params, ctx);

  if (result.blocked) {
    return { block: true, blockReason: result.reason };
  }
  return undefined; // allow
}, { priority: 1000 });
api.on("before_tool_call", async (event, ctx) => {
  // event.toolName — the tool being called
  // event.params — the parameters
  // ctx.agentId — the agent making the call
  // ctx.sessionKey — the session key

  const result = await checkFaramesh(event.toolName, event.params, ctx);

  if (result.blocked) {
    return { block: true, blockReason: result.reason };
  }
  return undefined; // allow
}, { priority: 1000 });

The hook runs at priority 1000 — the highest priority, ensuring it runs before any other hooks.

Gateway bypass fix

OpenClaw has two tool execution paths:

  1. Agent-initiated: Tools called by the AI agent go through runBeforeToolCallHook → hooks run → tool executes.

  2. HTTP gateway: Tools called via the HTTP API (/tools/invoke) previously bypassed the hook system.

The Faramesh integration includes a fix that ensures the HTTP gateway also calls runBeforeToolCallHook (see tools-invoke-http.ts), so no tool call can bypass governance—whether from the agent or from direct HTTP invoke. Every action appears in the dashboard (Allowed / Denied / Pending) with full provenance. The integration is covered by a full E2E test suite, and the plugin implements retry behavior when the Faramesh server is temporarily unavailable (configurable).

Decision flow




Category resolution

Each tool is mapped to a category for simple policy evaluation:

Tool name

Category

bash, shell, exec, terminal

bash

read, write, edit, glob, grep

filesystem

browser, browser_navigate, browser_click

browser

web_fetch, web_search, http, curl

network

canvas, notebook

canvas

Everything else

other

The mapping happens both on the plugin side and the server side, using the same logic.

Fail-closed vs fail-open

Mode

When Faramesh is unreachable

fail-closed (default)

Tool call is blocked

fail-open

Tool call is allowed

Set fail_closed: false in the plugin configuration to use fail-open mode.

Data sent to Faramesh

Each tool call sends:

{
  "agent_id": "openclaw",
  "tool": "bash",
  "operation": "run",
  "params": { "command": "ls -la" },
  "context": {
    "session_key": "abc123",
    "source": "openclaw",
    "category": "bash",
    "runtime_id": "user@hostname"
  }
}
{
  "agent_id": "openclaw",
  "tool": "bash",
  "operation": "run",
  "params": { "command": "ls -la" },
  "context": {
    "session_key": "abc123",
    "source": "openclaw",
    "category": "bash",
    "runtime_id": "user@hostname"
  }
}
{
  "agent_id": "openclaw",
  "tool": "bash",
  "operation": "run",
  "params": { "command": "ls -la" },
  "context": {
    "session_key": "abc123",
    "source": "openclaw",
    "category": "bash",
    "runtime_id": "user@hostname"
  }
}

The runtime_id is automatically set to the current hostname, enabling fleet management across multiple machines.

Response handling

The plugin checks the response for three possible outcomes:

  • status: allowed or decision: allow or outcome: EXECUTE → tool runs

  • status: pending_approval or decision: require_approval or outcome: ABSTAIN → tool blocked, waiting for approval

  • status: denied or decision: deny or outcome: HALT → tool blocked permanently

Was this helpful?

Was this helpful?

Was this helpful?

Previous

More

Previous

More

Previous

More

Next

More

Next

More

Next

More

Table of content

Table of content

Table of content

How It Works

How It Works