Tools
Claw Guardrails
This is an OpenClaw plugin that enforces multi-layer permission checks before potentially destructive actions.
Install
openclaw plugins install @eveiljuice/claw-guardrails
Configuration Example
{
"plugins": {
"load": {
"paths": ["/path/to/claw-plugin"]
},
"entries": {
"claw-guardrails": {
"enabled": true
}
}
}
}
README
# ClawGuardrails 🦞
OpenClaw plugin that enforces a **4-stage permission pipeline** before any potentially destructive agent action. The agent can only execute shell commands, send channel messages, or trigger external APIs through controlled wrapper tools (`safe_exec`, `safe_send`, `safe_action`) — every call is risk-classified, policy-matched, and optionally routed through a human approval queue.
---
## Architecture
```mermaid
flowchart TD
A([Agent]) -->|calls| T["safe_exec / safe_send / safe_action"]
T --> R["🔒 Permission Resolver"]
R --> C1["1️⃣ Context Matcher\nsender · channel · time window · agent"]
C1 --> C2["2️⃣ Tool Checker\ncmd allow/deny · cwd scope · arg flags"]
C2 --> C3["3️⃣ Resource Checker\nfs · network · database · channels"]
C3 --> C4["4️⃣ Policy Engine\nrisk classify → first-match rule"]
C4 -->|ALLOW| OK["✅ Execute via runtime"]
C4 -->|DENY| NO["❌ Return denial + reason code"]
C4 -->|REQUIRE_APPROVAL| Q["⏳ Approval Queue\n/approve · /deny · RPC · timeout"]
Q -->|approved| OK
Q -->|denied / expired| NO
OK -.->|writes| L[("📄 Audit JSONL")]
NO -.->|writes| L
Q -.->|writes| L
style R fill:#1e3a5f,color:#fff,stroke:#4a90d9
style OK fill:#1a4731,color:#fff,stroke:#2ecc71
style NO fill:#4a1a1a,color:#fff,stroke:#e74c3c
style Q fill:#3d2b00,color:#fff,stroke:#f39c12
style L fill:#2d2d2d,color:#ccc,stroke:#666
```
**Default behaviour (out of the box):**
- LOW risk → allowed
- MEDIUM / HIGH risk → requires human approval
- CRITICAL risk → denied immediately
- Channel writes → always require approval
---
## Installation on production OpenClaw
### Option 1 — install from npm registry (production)
```bash
openclaw plugins install @eveiljuice/claw-guardrails --pin
```
### Option 2 — `--link` (recommended for local path)
```bash
openclaw plugins install --link /path/to/claw-plugin
```
This registers the folder as a plugin without copying it. Restart the Gateway after.
### Option 3 — Copy to workspace extensions
```bash
cp -r /path/to/claw-plugin ~/.openclaw/extensions/claw-guardrails
```
OpenClaw auto-discovers plugins from `~/.openclaw/extensions/*/index.ts`.
### Option 4 — `plugins.load.paths` in config
Add to `~/.openclaw/openclaw.json`:
```json
{
"plugins": {
"load": {
"paths": ["/path/to/claw-plugin"]
},
"entries": {
"claw-guardrails": {
"enabled": true
}
}
}
}
```
---
## Publish and update flow
```bash
npm run release:patch
```
Alternative:
```bash
npm run release:minor
npm run release:major
```
Then update OpenClaw hosts:
```bash
openclaw plugins update claw-guardrails
openclaw plugins update --all
```
---
## Required: deny raw dangerous tools
After installing the plugin, block the raw tools so the agent can **only** reach them through the guardrails wrappers:
```json
{
"tools": {
"deny": ["exec", "gateway", "cron", "sessions_spawn", "sessions_send"]
}
}
```
Add to `~/.openclaw/openclaw.json` alongside the plugin config.
---
## Configuration
All options go under `plugins.entries.claw-guardrails.config`:
```jsonc
{
"plugins": {
"entries": {
"claw-guardrails": {
"enabled": true,
"config": {
"defaultAction": "deny", // allow | deny | require_approval
"approvalTimeout": 300, // seconds to wait for human approval
"approvalFallback": "deny", // what to do on timeout
"auditLog": true,
"auditLogPath": "~/.openclaw/guardrails/audit.jsonl",
"policies": [
{ "id": "allow-reads", "match": { "riskLevel": ["LOW"] }, "action": "allow" },
{ "id": "block-critical", "match": { "riskLevel": ["CRITICAL"] }, "action": "deny" },
{ "id": "approve-medium-high", "match": { "riskLevel": ["MEDIUM", "HIGH"] }, "action": "require_approval" }
],
"resources": {
"exec": {
"allow": ["git *", "npm *", "node *", "ls", "cat", "rg *"],
"deny": ["rm -rf *", "sudo *", "chmod 777 *", "curl * | bash"],
"cwdAllow": ["~/.openclaw/workspace/**"]
},
"filesystem": {
"writeDeny": ["~/.ssh/**", "~/.openclaw/credentials/**"]
},
"channels": {
"writeAllow": [] // empty = all channel writes require approval
}
}
}
}
}
}
}
```
### Policy match fields
| Field | Description |
|---|---|
| `riskLevel` | `LOW`, `MEDIUM`, `HIGH`, `CRITICAL` |
| `tools` | glob patterns on tool name (`safe_exec`, `safe_send`, `safe_action`) |
| `commands` | glob patterns on full command string |
| `resources` | glob on `kind:value` (e.g. `channel_write:*`) |
| `senders` | glob on sender id |
| `channels` | glob on channel id |
| `agents` | glob on agent id |
---
## Verification checklist
### 1. Plugin loaded
```bash
openclaw plugins list
# should show: claw-guardrails enabled
```
```bash
openclaw plugins doctor
# should pass with no errors for claw-guardrails
```
### 2. Low-risk command passes without approval
Ask the agent in chat:
> Use `safe_exec` to run `git status` in the workspace.
Expected: command runs immediately, result returned, audit log entry written.
### 3. Dangerous command is blocked
Ask:
> Use `safe_exec` to run `sudo rm -rf /tmp/test`.
Expected: immediate `deny` with code `TOOL_EXEC_DENYLIST_MATCH`.
### 4. Medium-risk triggers approval
Ask:
> Use `safe_exec` to run `git commit -am "test"`.
Expected: response with `require_approval` and an approval `id`. Then:
```
/approve <id>
```
After approval → command executes.
Or deny with:
```
/deny <id>
```
### 5. Check approval queue
```
/perms
```
Shows current queue state, active policies, and timeout settings.
### 6. CLI status
```bash
openclaw guardrails status # queue counters
openclaw guardrails audit # audit log path + enabled flag
openclaw guardrails policy # active rules
```
### 7. Audit log
```bash
tail -f ~/.openclaw/guardrails/audit.jsonl | jq .
```
Every decision (allow/deny/require_approval) produces one JSONL line with full request, stage trace, and risk assessment.
---
## Risk levels
| Level | Examples | Default action |
|---|---|---|
| LOW | `ls`, `cat`, `git status`, `rg` | allow |
| MEDIUM | `git commit`, `npm install`, file writes | require_approval |
| HIGH | `rm`, `git push --force`, channel posts, `npm publish` | require_approval |
| CRITICAL | `sudo`, `rm -rf`, email delete, `curl \| bash`, DB drop | deny |
---
## Slash commands
| Command | Description |
|---|---|
| `/perms` | Show config summary and approval queue counters |
| `/approve <id>` | Approve a pending request |
| `/deny <id>` | Deny a pending request |
---
## Gateway RPC (Control UI)
| Method | Payload | Description |
|---|---|---|
| `guardrails.pending` | — | List pending approval entries |
| `guardrails.approve` | `{ id }` | Approve by id |
| `guardrails.deny` | `{ id }` | Deny by id |
| `guardrails.status` | — | Queue summary + current config |
---
## Approval queue persistence
Pending approvals survive Gateway restarts. They are stored at:
```
~/.openclaw/guardrails/pending.json
```
Entries expire after `approvalTimeout` seconds (default 5 min). The background service checks every 5 s and marks expired entries automatically.
---
## Dependencies
| Package | Purpose |
|---|---|
| `@sinclair/typebox` | JSON Schema / TypeBox config schema |
| `minimatch` | Glob matching for commands, paths, channels |
| `date-fns` | Time window evaluation (ISO parse + comparison) |
tools
Comments
Sign in to leave a comment