Skip to content

OpenClaw Integration Guide

Integrate munio with OpenClaw for fine-grained tool call verification.

OpenClaw’s tool policy system handles which tools are allowed (coarse-grained allow/deny). munio complements it with what arguments are safe (fine-grained runtime verification).

Tool call → OpenClaw policy check → munio constraint check → Execute
(allow/deny tool) (verify arguments)
Terminal window
pip install "munio[server]"
munio serve --pack openclaw --port 8080
Terminal window
cp -r examples/openclaw-plugin /path/to/openclaw/plugins/munio

Add to your openclaw.json:

{
"plugins": {
"entries": {
"munio": {
"config": {
"apiUrl": "http://localhost:8080",
"timeoutMs": 5000,
"failClosed": true
}
}
}
}
}
Terminal window
# Health check
curl http://localhost:8080/v1/health
# Test a blocked command
curl -X POST http://localhost:8080/v1/openclaw/before-tool-call \
-H "Content-Type: application/json" \
-d '{"event":{"toolName":"exec","params":{"command":"rm -rf /"}},"ctx":{"toolName":"exec"}}'
# → {"block":true,"blockReason":"Field 'command' matched denied pattern..."}

The openclaw constraint pack covers these tools:

ToolConstraintWhat it checks
execopenclaw-exec-command-denylistBlocks rm -rf, curl|sh, chmod 777, etc.
execopenclaw-exec-no-elevatedBlocks elevated: true (root execution)
execopenclaw-exec-timeout-limitCaps timeout at 300 seconds
web_fetchopenclaw-web-fetch-url-denylistBlocks internal IPs, metadata endpoints, file://
web_fetchopenclaw-web-fetch-url-schemeRequires HTTPS
browseropenclaw-browser-url-denylistBlocks internal URLs
writeopenclaw-write-path-traversalBlocks ../, absolute paths, ~/
editopenclaw-edit-path-traversalBlocks ../, absolute paths, ~/
readopenclaw-read-path-traversalBlocks ../, absolute paths, ~/
readopenclaw-read-path-denylistBlocks /etc/shadow, .ssh/, .env, .aws/, .kube/, .docker/
web_searchopenclaw-web-search-injectionDetects prompt injection patterns (warn)

munio detects and blocks Safety Control Tampering — attacks that programmatically disable safety controls before executing malicious commands. This was motivated by CVE-2026-25253 (OpenClaw 1-click RCE, CVSS 8.8), a 7-step attack chain where an attacker:

  1. Overrides the gateway URL to a malicious WebSocket server
  2. Sends crafted instructions via the hijacked connection
  3. Disables approval requirements (exec.approvals.set({ask: "off"}))
  4. Escapes sandbox to host (config.patch({tools.exec.host: "gateway"}))
  5. Executes arbitrary commands on the host

Steps 5-6 are SCT primitives. munio blocks them with 4 OpenClaw-specific constraints:

ConstraintCVE StepWhat it blocks
openclaw-safety-disable-approvalsStep 5Disabling execution approval requirements
openclaw-safety-disable-security-modeStep 5Weakening security approval mode
openclaw-gateway-url-overrideStep 1Gateway URL redirect to attacker server
openclaw-sandbox-escape-host-modeStep 6Container escape to host execution
Terminal window
# Step 5 of the attack chain — munio blocks it
curl -X POST http://localhost:8080/v1/openclaw/before-tool-call \
-H "Content-Type: application/json" \
-d '{
"event": {
"toolName": "exec.approvals.set",
"params": {"ask": "off", "security": "full"}
},
"ctx": {"toolName": "exec.approvals.set"}
}'
# → {"block":true,"blockReason":"Field 'ask' matched denied value: off"}
# Step 6 of the attack chain — munio blocks it
curl -X POST http://localhost:8080/v1/openclaw/before-tool-call \
-H "Content-Type: application/json" \
-d '{
"event": {
"toolName": "config.patch",
"params": {"patch": "tools.exec.host: gateway"}
},
"ctx": {"toolName": "config.patch"}
}'
# → {"block":true,"blockReason":"Field matched denied pattern: host mode execution"}

The constraints are in constraints/openclaw/asi03-privilege-abuse/. Load them with:

Terminal window
munio serve --pack openclaw --port 8080

For broader SCT coverage across any MCP server, the generic pack includes 3 additional constraints that use wildcard action patterns to catch safety-disabling tool calls regardless of the server implementation. See Constraints Reference for the full list.

Add your own constraints for OpenClaw tools:

Terminal window
mkdir -p constraints/openclaw/custom/

Create a YAML file (e.g., constraints/openclaw/custom/my-rule.yaml):

name: my-custom-exec-rule
description: "Block npm publish commands"
category: ASI02
tier: 1
action: exec
check:
type: regex_deny
field: command
patterns:
- "npm\\s+publish"
case_sensitive: false
on_violation: block
severity: high

Restart the server to pick up new constraints.

The integration has two critical safety boundaries:

If the plugin handler throws an error, OpenClaw catches it, logs a warning, and allows the tool call. This is why the plugin wraps everything in try/catch.

On ANY error (network timeout, HTTP 500, DNS failure), the plugin returns {block: true}. Set failClosed: false only for testing/shadow mode.

Test constraints without blocking:

Terminal window
# Server-side shadow mode
munio serve --pack openclaw --mode shadow
# Or client-side (failClosed: false in openclaw.json)

In shadow mode, violations are logged but all tool calls are allowed.

  • Check openclaw.plugin.json exists in the plugin directory
  • Verify plugin is listed in openclaw.jsonplugins.entries
  • Check server health: curl http://localhost:8080/v1/health
  • Verify constraints load: munio audit -d constraints -p openclaw
  • Try shadow mode to see violations without blocking
  • munio Tier 1 checks run in <1ms
  • Network overhead depends on deployment (localhost ≈ 0.1ms, remote ≈ 1-10ms)
  • Adjust timeoutMs if needed (default 5s is conservative)