If you are googling “OpenClaw Ishi control agent setup for supervised AI operations,” you probably already run an OpenClaw agent in prod or are about to. This guide shows exactly how to strap Ishi — an independent “AI CISO” — onto that agent so every outbound tool call, browser action, or shell command is vetted before it happens.

Why Put an Agent in Charge of an Agent?

OpenClaw is powerful: 800+ integrations via Composio, direct shell access, browser automation, memory that never forgets. Power and danger scale together. Most organizations handle risk with static allow-lists, but once you give an LLM an interactive shell the blast radius grows faster than your YAML files.

Ishi is a separate OpenClaw process that does nothing except watch. Think runtime security meets policy-as-code. Every action from the primary agent is routed to Ishi first. Ishi replies allow, deny, or escalate. If it panics or stalls, the main agent times out and aborts. In other words you get:

  • Dynamic decision making — not just regex path filters.
  • A kill switch that even root-shell prompts cannot override.
  • Audit logs readable by both humans and SIEMs.

High-Level Architecture of a Supervised OpenClaw

The moving pieces are small:

  1. Main OpenClaw gateway (the usual Node.js 22+ process).
  2. Background daemon (also normal).
  3. Ishi controller — another OpenClaw instance started with a special --role=ishi flag.
  4. A tiny sidecar written in 60 lines of TypeScript (hooks/ishi-middleware.ts) that intercepts every tool call.

Traffic flow:

  1. User asks main agent to “download quarterly P&L from Drive and append to internal wiki.”
  2. Main agent forms a drive.download tool call.
  3. Middleware sends the proposed JSON payload to Ishi over gRPC.
  4. Ishi runs its policy chain — OpenAI, internal heuristics, and any custom JS files — then replies.
  5. If allow, main agent proceeds; if deny it aborts; if escalate, fallback human approval webhook fires.

Prerequisites

  • Node.js 22.2 or newer (Ishi uses Intl.DurationFormat which landed in v22)
  • OpenClaw ≥ 3.7.0 (released last week; adds preToolCall hook)
  • NPM or PNPM; I’ll use PNPM because it does not wreck my package-lock.json
  • A Postgres 16 database if you want long-term audit persistence (optional)

Installing Ishi and Bootstrapping the Project

1 – Create a workspace

I like separate repos so the security layer can be audited in isolation:

mkdir openclaw-supervised && cd openclaw-supervised pnpm init -y

2 – Install OpenClaw twice

Yes, twice. One for the primary agent, one for Ishi. Two package.json files keep dependencies explicit.

# main agent pnpm add openclaw@3.7.0 # ishi controller in a subdir mkdir ishi && cd ishi && pnpm init -y && pnpm add openclaw@3.7.0

3 – Generate skeleton configs

# root dir (main agent) npx claw init --name "RevenueBot" --preset minimal # inside ishi directory npx claw init --name "Ishi" --preset minimal --role=ishi

The --role=ishi flag flips three defaults:

  • Disables all external integrations except the policy engine.
  • Enables strict JSON-only mode for inputs and outputs (less prompt injection surface).
  • Turns on failClosed=true; any crash means deny.

Wiring Middleware: Routing Tool Calls Through Ishi

4 – Create the hook file

// hooks/ishi-middleware.ts import { ToolCallHook } from 'openclaw/types'; import { IshiClient } from './lib/ishi-client'; const client = new IshiClient('localhost:7007'); export const preToolCall: ToolCallHook = async (context) => { const decision = await client.evaluate({ tool: context.tool.name, args: context.args, memory: context.memory.snapshot(), userId: context.user.id }); if (decision === 'allow') return; if (decision === 'escalate') throw new Error('ESCALATE_ISHI'); throw new Error('DENY_ISHI'); };

Then register it inside claw.config.js:

module.exports = { hooks: ['./hooks/ishi-middleware.ts'] };

5 – Ishi gRPC server

// ishi/src/server.ts import { serve, allow, deny, escalate } from 'openclaw/ishi'; import rules from './rules'; serve(7007, async (payload) => { for (const rule of rules) { const res = await rule(payload); if (res) return res; // first match wins } return deny('No matching rule'); });

Writing Policies: Allow / Deny / Escalate

Ishi policies are just async functions that return one of three helpers. You can keep them in ishi/src/rules.ts.

import { allow, deny, escalate } from 'openclaw/ishi'; export default [ // 1. Disallow destructive shell commands ({ tool, args }) => { if (tool === 'shell.exec' && /rm -rf|shutdown/.test(args.command)) { return deny('Potentially destructive command'); } }, // 2. Enforce least privilege on Gmail ({ tool, args, userId }) => { if (tool === 'gmail.send' && !userId.startsWith('corp-')) { return escalate('Unprivileged user attempted email send'); } }, // 3. Allow everything else for now () => allow() ];

A couple of real-world snippets I shipped last week:

  • Regex denying anything that looks like aws_secret_access_key in outbound HTTP.
  • Time-based rules (deny() outside 06:00-22:00 UTC unless a PagerDuty incident is active).
  • Escalation that posts to Slack channel #ai-ops-review and waits for a slash-command ACK.

Testing the Allow/Deny Path

6 – Spin it all up locally

# Start Ishi cd ishi && pnpm ts-node src/server.ts # In another terminal run the main agent ts-node index.ts # or npx claw dev

7 – Trigger a benign action

Ask the agent:

user> list my Dropbox files

Logs should show:

Ishi ➜ allow dropbox.list OK

8 – Trigger a denial

user> run `rm -rf /`

Main agent throws DENY_ISHI; in the gateway you see an error toast rather than a system meltdown. Good.

9 – Escalation flow

user> email the CFO my ssh key

Ishi returns escalate; the Slack webhook fires. After a human reviewer hits /ishi-approve 123, a Redis lock is released and the original tool call retries.

Wiring a Hardware Kill Switch (Optional but Popular)

Several community members wired Ishi’s deny signal to a GPIO pin on a Raspberry Pi. I wanted something faster for prod, so I used AWS Systems Manager:

// ishi/src/rules/kill-switch.ts import { deny } from 'openclaw/ishi'; import { SSM } from '@aws-sdk/client-ssm'; const ssm = new SSM(); export default async () => { const { Parameter } = await ssm.getParameter({ Name: '/openclaw/kill' }); if (Parameter?.Value === 'true') { return deny('Hardware kill switch active'); } };

Flip the switch by running:

aws ssm put-parameter --name /openclaw/kill --value true --type String --overwrite

The next tool call denies instantly; long-running tasks poll every 30 seconds and self-abort.

When Do You Actually Need This Level of Supervision?

You probably don’t need Ishi for your weekend side project that emails you weather updates. Ishi makes sense once any of these are true:

  • You grant shell or database credentials.
  • The agent can spend real money (cloud APIs, Stripe, advertising).
  • You operate under SOC 2, ISO 27001, or upcoming EU AI Act requirements.
  • Multiple humans rely on the agent and auditability is non-negotiable.

I’ve seen teams hit “stage two panic” after a demo triggers a runaway Slack DM storm. Retrofitting security afterwards is harder than spending the extra hour to deploy Ishi first.

Operational Tips from Running Ishi in Production

  • Set ISHI_TIMEOUT_MS to something realistic (default 500 ms). If your LLM is slow, you’ll suffer false denies.
  • Log decisionId in both main and Ishi logs so you can correlate later.
  • Write unit tests for rules; they’re just functions. Jest + 30 fixtures = sleep at night.
  • If you run on ClawCloud, you can deploy Ishi as a separate project and point the middleware at wss://ishi-prod.claw.cloud. Works out of the box; no extra charge.

Next Step: Ship It

Ship your supervised stack by committing the two repos and adding a CI gate that refuses to deploy if pnpm test fails or policy coverage drops below 90%. After that, push both containers to your registry, set the ISHI_ENDPOINT env var in the main agent, and enjoy an AI system that still scares you — but only in the good ways.