← Back to Plugins
Tools

Witness

cheenu1092-oss By cheenu1092-oss 👁 30 views ▲ 0 votes

Tamper-evident audit trails for OpenClaw agents. Lightweight HITL plugin with hash-chained logging.

GitHub

Install

npm install
npm

Configuration Example

# In your OpenClaw config (clawdbot.json or plugin config):
plugins:
  witness:
    mode: audit              # audit | gate-writes | gate-all
    db_path: witness.db      # SQLite database path
    ttl_minutes: 30          # auto-expire pending approvals
    auto_approve_threshold: 10  # approvals before auto-approve
    risk_overrides:          # override default risk levels
      exec: critical
      Read: low

README

# Witness ๐Ÿ‘๏ธ

**Tamper-evident audit trails for OpenClaw agents.**

Witness is an OpenClaw plugin that records every tool call your AI agent makes into a hash-chained, queryable SQLite log. No friction by default โ€” it just watches. When you're ready, opt into approval gates for high-risk actions.

## Why

You gave your AI agent access to your email, files, calendar, maybe your bank. It's doing things on your behalf 24/7. But:

- **What did it actually do at 3 AM?** You have no idea.
- **Can you prove it didn't send that email?** Not without structured logs.
- **Can you gradually trust it with more?** Not without a trust ramp.

Witness solves this. Every tool call โ†’ structured event โ†’ hash-chained log โ†’ queryable audit trail.

## How It Works

```
Agent calls tool โ†’ OpenClaw hook fires โ†’ Witness logs/gates โ†’ Tool executes (or blocks)
```

### Three Modes

| Mode | Behavior | Default risk blocked |
|------|----------|---------------------|
| `audit` (default) | Log everything, block nothing | None |
| `gate-writes` | Block high-risk + critical | `exec`, `process`, `rm -rf`, `.env` writes |
| `gate-all` | Block medium and above | Above + `Write`, `Edit`, `message.send`, `browser.navigate` |

### Risk Assessment Engine

Static risk levels per tool name + param-aware escalation:

| Risk Level | Tools | Param Escalation |
|-----------|-------|-----------------|
| ๐ŸŸข Low | `Read`, `web_search`, `memory_search`, `session_status` | โ€” |
| ๐ŸŸก Medium | `Write`, `Edit`, `message`, `browser` | `message.send` โ†’ medium |
| ๐ŸŸ  High | `exec`, `process` | `sudo`, `elevated: true` โ†’ high |
| ๐Ÿ”ด Critical | โ€” | `rm -rf`, `.env`/`.pem`/`.ssh` writes โ†’ critical |

## Install

```bash
# From ClawHub (when published):
openclaw skill install witness

# For development:
git clone https://github.com/cheenu1092-oss/witness.git
cd witness
npm install
npm run build
```

### OpenClaw Plugin Config

```yaml
# In your OpenClaw config (clawdbot.json or plugin config):
plugins:
  witness:
    mode: audit              # audit | gate-writes | gate-all
    db_path: witness.db      # SQLite database path
    ttl_minutes: 30          # auto-expire pending approvals
    auto_approve_threshold: 10  # approvals before auto-approve
    risk_overrides:          # override default risk levels
      exec: critical
      Read: low
```

## Usage

Once installed, Witness runs automatically. Every tool call is logged.

### Query Commands

```
/witness              โ€” Show recent events (last 20)
/witness recent 50    โ€” Show last 50 events
/witness search exec  โ€” Search by tool name, params, or result
/witness stats        โ€” Tool counts, costs, errors, risk breakdown
/witness verify       โ€” Verify hash chain integrity (tamper detection)
/witness mode         โ€” Show current operating mode
/witness export       โ€” Export info (file export coming soon)
/witness help         โ€” Full command list
```

### Approval Commands (gate modes only)

```
/witness pending                   โ€” Show pending work orders
/witness approve wo_01HXYZ...     โ€” Approve a blocked action
/witness approve wo_01HXYZ... Looks safe  โ€” Approve with note
/witness reject wo_01HXYZ...      โ€” Reject a blocked action
/witness trust exec               โ€” Show trust history for a tool
```

### Approval Flow

```
1. Agent calls exec({command: "rm -rf /tmp/old"})
2. Witness: ๐Ÿ›‘ BLOCKED โ€” critical risk (destructive command)
3. Agent tells user: "Blocked by Witness. Approve with /witness approve wo_xxx"
4. User: /witness approve wo_xxx
5. Witness: โœ… Approved โ†’ system event โ†’ agent re-executes
```

## Architecture

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ OpenClaw Gateway                                     โ”‚
โ”‚                                                      โ”‚
โ”‚  Agent โ”€โ”€โ†’ before_tool_call โ”€โ”€โ†’ Witness Gate         โ”‚
โ”‚                                    โ”‚                 โ”‚
โ”‚                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”          โ”‚
โ”‚                          ALLOW         BLOCK         โ”‚
โ”‚                              โ”‚           โ”‚           โ”‚
โ”‚                         Tool runs   Work order       โ”‚
โ”‚                              โ”‚      created          โ”‚
โ”‚                              โ–ผ           โ”‚           โ”‚
โ”‚  Agent โ†โ”€โ”€ after_tool_call โ†โ”€โ”˜    /witness approve   โ”‚
โ”‚                โ”‚                       โ”‚             โ”‚
โ”‚           Witness Log            System event        โ”‚
โ”‚                โ”‚                  โ†’ re-execute       โ”‚
โ”‚                โ–ผ                                     โ”‚
โ”‚         SQLite (WAL)                                 โ”‚
โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                            โ”‚
โ”‚    โ”‚ events (hash-chain)โ”‚  โ† append-only, immutable  โ”‚
โ”‚    โ”‚ work_orders        โ”‚  โ† mutable state machine   โ”‚
โ”‚    โ”‚ trust_ledger       โ”‚  โ† auto-approval tracking  โ”‚
โ”‚    โ”‚ config             โ”‚  โ† runtime settings        โ”‚
โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

### Key Design Decisions

1. **Events are immutable + hash-chained.** Work orders are mutable. They're in separate tables to preserve the append-only invariant.
2. **Hash chain = tamper detection, not prevention.** If someone owns your machine, they can rewrite the DB. But the chain will break, and `/witness verify` will catch it.
3. **`after_tool_call` is async.** It fires after tool execution completes โ€” zero latency overhead on the tool call itself.
4. **`before_tool_call` blocks synchronously.** In gate modes, the tool call is blocked before execution. The agent receives an error with the block reason.
5. **Re-execution uses system events.** After approval, a system event is enqueued. The agent sees it at the start of the next turn and can re-execute the tool.
6. **SQLite WAL mode.** ~66ฮผs per insert. Handles 500 rapid sequential appends without corruption. Chain survives process restart.

## Database Schema

Four tables:

| Table | Rows Grow? | Mutable? | Hash-chained? | Purpose |
|-------|-----------|----------|---------------|---------|
| `events` | Yes (append-only) | No | Yes | Audit log of every tool call |
| `work_orders` | Yes (per block) | Yes | No | Approval queue state machine |
| `trust_ledger` | Yes (per tool) | Yes | No | Auto-approval ramp tracking |
| `config` | Rarely | Yes | No | Runtime key-value settings |

### Event Schema

```sql
events (
  id TEXT PRIMARY KEY,           -- evt_<ulid>
  seq INTEGER UNIQUE,            -- monotonic sequence
  timestamp TEXT,                -- ISO 8601 UTC
  session_key TEXT,              -- OpenClaw session
  agent_id TEXT,                 -- agent that made the call
  tool_name TEXT,                -- e.g. 'exec', 'Read'
  params_json TEXT,              -- JSON tool params
  result_ok INTEGER,             -- 1=success, 0=error
  result_summary TEXT,           -- truncated result (max 1KB)
  duration_ms INTEGER,           -- execution time
  risk_level TEXT,               -- unknown|low|medium|high|critical
  risk_reasons TEXT,             -- JSON array of reasons
  action TEXT,                   -- logged|blocked|auto_approved
  cost_usd REAL,                -- estimated cost
  prev_hash TEXT,                -- SHA-256 of previous event
  hash TEXT                      -- SHA-256(prev_hash+id+timestamp+tool_name+params_json)
)
```

## Project Status

| Component | Status | Tests |
|-----------|--------|-------|
| Audit store (events, hash chain) | โœ… Complete | 8 tests |
| Work orders (create, resolve, sweep) | โœ… Complete | 9 tests |
| Trust ledger (approve/reject tracking) | โœ… Complete | 6 tests |
| Concurrency (WAL, rapid inserts) | โœ… Validated | 5 tests |
| Risk assessment engine | โœ… Complete | 20 tests |
| Plugin integration (register, hooks, commands) | โœ… Complete | 30+ tests |
| Edge cases (unicode, nulls, empty DB) | โœ… Complete | 4 tests |
| **Total** | | **80+ tests** |

### Phase Roadmap

| Phase | Scope | Lines | Status |
|-------|-------|-------|--------|
| Phase 1 | Audit-only (log every tool call, hash chain, /witness commands) | ~800 | โœ… Built |
| Phase 2 | Approval gates (before_tool_call, work orders, approve/reject flow) | +600 | โœ… Built |
| Phase 3 | Trust ramp (auto-approve, trust ledger UI, export) | +400 | โœ… Built |
| **Total** | | **~1,800** | |

### MVP (Phase 1 ship criteria)

- [x] `register(api)` plugin entry point
- [x] `after_tool_call` hook logs every tool call
- [x] SHA-256 hash chain on all events
- [x] `/witness` command with 11 subcommands
- [x] SQLite WAL mode, <100ฮผs per insert
- [x] 80+ tests passing
- [x] Plugin manifest (`openclaw.plugin.json`)
- [x] SKILL.md for ClawHub
- [ ] npm publish (`openclaw-witness`)
- [ ] GitHub repo creation
- [ ] Real-world testing on live OpenClaw instance

## Development

```bash
npm install          # install deps
npm test             # run vitest
npm run build        # compile TypeScript
npm run dev          # watch mode
```

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

MIT

## Credits

Built by [cheenu1092-oss](https://github.com/cheenu1092-oss) as an OpenClaw community plugin.

Research informed by analysis of [Ruflo](https://github.com/ruvnet/ruflo) (MIT), [Temporal](https://temporal.io), and the [OpenClaw plugin system](https://github.com/openclaw/openclaw).
tools

Comments

Sign in to leave a comment

Loading comments...