Skip to main content

Behavioral monitoring for OpenClaw AI agents — research prototype

Project description

WatchClaw

Zeek for the AI Agent era — behavioral monitoring for OpenClaw agents.

AI agents have full system access: file I/O, shell commands, HTTP requests. When an agent is hijacked via prompt injection, it looks like normal operation — network-layer tools can't see the difference. WatchClaw monitors agent behavior at the semantic level: it learns baselines, tracks data sensitivity, and detects attack chains that traditional security tools miss entirely.


The Problem

A prompt injection attack can silently redirect an agent's power.

Example attack chain: A malicious webpage injects instructions into an agent's context. The agent reads ~/.ssh/id_rsa and .env, then curls the contents to an attacker-controlled domain. The entire chain looks like normal tool usage — no malware binary, no exploit payload, no anomalous network signature.

Traditional security tools fail here:

  • Suricata/Zeek see a normal HTTPS POST — nothing to flag
  • EDR sees a legitimate process reading a file — nothing unusual
  • In-agent guardrails run inside the hijacked agent's own LLM — a compromised agent ignores its own constraints

The attack is invisible at every layer except one: the semantic sequence of agent actions.


How WatchClaw Works

                 ┌─────────────────────────────┐
                 │     Event Ingestion          │
                 │  OpenClaw logs / filesystem  │
                 └─────────────┬───────────────┘
                               │
                 ┌─────────────▼───────────────┐
                 │  Layer 1: Hard Rules         │  ← instant
                 │  Obfuscation, credential     │
                 │  sweeps, known-bad patterns  │
                 └─────────────┬───────────────┘
                               │
                 ┌─────────────▼───────────────┐
                 │  Layer 2: Behavior Engine    │  ← per event
                 │  6-signal anomaly scoring    │
                 │  Taint tracking + sequences  │
                 │  Per-agent baseline learning │
                 └─────────────┬───────────────┘
                               │
                 ┌─────────────▼───────────────┐
                 │  Output: action.log │ alerts │
                 │  Discord │ report            │
                 └─────────────────────────────┘

Demo

WatchClaw simulate — detecting data exfiltration and cognitive injection

Normal agents perform routine operations — git, pytest, file writes. The rogue_agent reads credentials.json and id_ed25519, tainting those reads. When it later requests evil-exfil.com/upload, WatchClaw detects the read-then-exfiltrate sequence and marks it CRITICAL. It also catches the agent writing to SOUL.md after fetching external instructions — a cognitive injection attack.

watchclaw simulate --duration 25 --attack-ratio 0.2

Key Features

Behavioral Baselines

WatchClaw learns each agent's normal patterns — when they're active, which files they touch, which domains they request. A dev agent reading source files at 2pm is normal. The same agent reading .env at 3am after hours of user inactivity scores very differently.

6-Signal Anomaly Scoring

Every action is scored against 6 independent signals: time anomaly, user idle time, rate bursts, resource sensitivity, destination novelty, and taint flow. Each agent learns its own behavioral baseline over time — signals are weighted against per-agent historical norms, not global averages.

Taint Tracking with Exponential Decay

When an agent reads .env, that data is "tainted." The taint decays exponentially (5-minute half-life) — a curl 30 seconds later is highly suspicious, but the same curl 20 minutes later barely registers. If the user explicitly approves a transfer, the taint is sanitized and the alert is suppressed.

Sequence Pattern Detection

Single actions are ambiguous. Sequences tell the story. WatchClaw detects multi-step attack chains:

Pattern Trigger
read_then_exfil Sensitive file read → external request within 120s
config_then_escalate Config/identity file write → privileged exec within 60s
external_trigger_chain External fetch → write to SOUL.md / MEMORY.md within 30s

Hard Rules

Zero-tolerance rules for known-bad patterns: obfuscated execution (base64 -d | bash), bulk credential sweeps, SSH key access, cognitive file tampering. Rules are defined in configs/default-rules.yaml and fully customizable.

Independent Observer

WatchClaw runs as a separate process. The monitored agent's LLM cannot influence WatchClaw's detection logic directly. Note: a compromised agent that executes pkill watchclaw via shell can terminate the monitor — process supervision (e.g., systemd, launchd) is recommended in production deployments.


vs Existing Tools

Capability WatchClaw In-agent guardrails Suricata/Zeek EDR
Independent of agent process Yes No (runs inside agent) Yes Yes
Behavioral baseline per agent Yes No No No
Sequence pattern detection Yes No Partial No
Taint tracking with decay Yes No No No
Semantic-level visibility Partial (exec layer) Partial No No
Resistant to prompt injection Yes No (can be hijacked) N/A N/A

Architecture

src/watchclaw/
├── parser.py        # OpenClaw JSONL log parser + exec command semantic extraction
│                    # cat/head/curl commands → file_read/web_fetch with path/URL
├── taint.py         # Sensitivity propagation with exponential decay (half-life 300s)
│                    # Sanitization via user approval keywords
├── scorer.py        # 6-signal anomaly scoring + per-agent baseline learning
├── sequence.py      # Multi-step attack pattern detection (sliding window)
├── engine.py        # Orchestration
├── rules.py         # Hard rules (obfuscation, harvesting, cognitive injection)
├── alerter.py       # Discord webhook + structured action log
└── cli.py           # CLI entry points
tests/               # 307 tests

Installation

Requires Python 3.11+. macOS ships with Python 3.9 — install a newer version first if needed.

# macOS with Homebrew:
brew install python@3.13
pip3.13 install watchclaw

# Linux / other:
python3 -m pip install watchclaw

Usage

# Start continuous monitoring (reads OpenClaw logs in real time)
watchclaw start

# 24-hour summary: total events, alerts, top agents, rules triggered
watchclaw report

# View specific alerts
watchclaw logs --level ALERT             # all alerts
watchclaw logs --level CRITICAL          # critical only
watchclaw logs --level ALERT --agent melody   # filter by agent
watchclaw logs --tail 50                 # last 50 events

# Per-agent behavioral baseline
watchclaw profile

# Test detection with synthetic attack scenarios
watchclaw simulate

# List all active detection rules
watchclaw rules

Configuration

configs/default-config.yaml:

log_dir: /tmp/openclaw              # OpenClaw log directory
action_log: /tmp/watchclaw/action.log
watch_dirs:
  - ~/.openclaw/workspace-*
poll_interval: 2.0
taint_half_life: 300.0              # 5-minute decay
discord_webhook_url: null           # Set for real-time alerts

thresholds:
  normal: 0.3
  notice: 0.5
  alert: 0.7                        # ≥ 0.7 = CRITICAL

Limitations

OpenClaw Does Not Log Tool Arguments (v0.1 constraint)

OpenClaw logs that a tool was called, not its arguments:

# Logged:   "tool=Read"
# Missing:  "tool=Read path=/Users/andy/.ssh/id_rsa"

WatchClaw v0.1 works around this by extracting file paths and URLs from exec shell commands. Native Read and web_fetch tool calls are detected as events but without path/URL context.

Alert-Only

WatchClaw observes and alerts. It does not block. This is intentional — false-positive blocking in an AI agent monitoring tool causes more harm than it prevents.

Behavioral Profiles Are Not Persisted

Per-agent behavioral baselines are held in memory and reset when WatchClaw restarts. After a restart, each agent re-enters a cold-start period (approximately the first 20 minutes) where anomaly scoring is dampened. This creates a detection gap: an attacker who terminates and restarts WatchClaw before executing an attack can operate during the cold-start window with reduced detection probability. Process supervision (systemd, launchd) is recommended to minimize restart windows.


Roadmap

v0.2 — OpenClaw Plugin

The correct long-term architecture is a native OpenClaw plugin using the before_tool_call hook (verified in OpenClaw's plugin-sdk/plugins/types.d.ts):

api.registerHook("before_tool_call", async (event, ctx) => {
    // Full parameter visibility:
    // Read      → event.params.path
    // web_fetch → event.params.url
    // exec      → event.params.command

    await watchclaw.analyze(event.toolName, event.params, ctx.agentId);
    return undefined;  // Pure monitoring — never blocks
});

This eliminates the log-argument blindspot. The Python detection engine is ready to be called from a TypeScript hook handler.

Further Directions

  • Upstream: contribute sanitized tool argument logging to OpenClaw
  • Per-agent policy profiles
  • True Origin Tracing (correlate LLM context with tool calls)
  • Evaluation benchmark for AI agent behavioral monitoring

Defense-in-Depth Positioning

Per the OWASP Gen AI Security Project, WatchClaw is one layer in a defense-in-depth stack:

Layer 1 │ Architecture & Permissions (least privilege, sandboxing, HITL)
Layer 2 │ Prompt Engineering (input delimiters, post-prompting)
Layer 3 │ Behavioral Monitoring  ◄── WatchClaw
        │ Exec-layer taint tracking, sequence detection, anomaly scoring

Contributing

Issues and PRs welcome. The most impactful contribution is the v0.2 OpenClaw plugin — the detection engine is ready to be called from a TypeScript before_tool_call handler.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

watchclaw-0.1.6.tar.gz (74.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

watchclaw-0.1.6-py3-none-any.whl (48.1 kB view details)

Uploaded Python 3

File details

Details for the file watchclaw-0.1.6.tar.gz.

File metadata

  • Download URL: watchclaw-0.1.6.tar.gz
  • Upload date:
  • Size: 74.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for watchclaw-0.1.6.tar.gz
Algorithm Hash digest
SHA256 859a5450755286775934d36fd101cdf9ed25b2d0671abec93df4d2c2ae2c4e2f
MD5 39fa68f2d8f68bd796e2b33ffa7986fe
BLAKE2b-256 07178dc6a2b989b1c23ff8a31ab3072c39edd2f80d5b717af0e4c465677ca887

See more details on using hashes here.

File details

Details for the file watchclaw-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: watchclaw-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 48.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for watchclaw-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 85c32d0004e7ccc1c862921eba6a013e1500ebcd370ae30415e263039386bcf7
MD5 ab56a08676398d3e1cf70b8e294b183b
BLAKE2b-256 fe8c6479f9bdf164c495f00df35c9ce8664c76707f0bcbdbba7538106e599418

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page