{"id":44426633,"url":"https://github.com/seyz/clawbands","last_synced_at":"2026-02-15T13:01:13.029Z","repository":{"id":337424628,"uuid":"1152869559","full_name":"SeyZ/clawbands","owner":"SeyZ","description":"ClawBands is a security middleware for OpenClaw AI agents.","archived":false,"fork":false,"pushed_at":"2026-02-09T12:54:39.000Z","size":362,"stargazers_count":79,"open_issues_count":0,"forks_count":6,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T17:57:18.718Z","etag":null,"topics":["ai","openclaw","security"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SeyZ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-08T15:07:45.000Z","updated_at":"2026-02-13T16:29:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SeyZ/clawbands","commit_stats":null,"previous_names":["seyz/clawbands"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/SeyZ/clawbands","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeyZ%2Fclawbands","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeyZ%2Fclawbands/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeyZ%2Fclawbands/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeyZ%2Fclawbands/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SeyZ","download_url":"https://codeload.github.com/SeyZ/clawbands/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeyZ%2Fclawbands/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29443468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T10:51:12.367Z","status":"ssl_error","status_checked_at":"2026-02-14T10:50:52.088Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","openclaw","security"],"created_at":"2026-02-12T10:35:07.195Z","updated_at":"2026-02-14T12:01:13.214Z","avatar_url":"https://github.com/SeyZ.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🦞 + 🪢 ClawBands\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.png\" alt=\"ClawBands Logo\" width=\"300\"/\u003e\n\u003c/p\u003e\n\n**Put safety bands on [OpenClaw](https://github.com/openclaw/openclaw)**\n\nClawBands is a security middleware for [OpenClaw](https://github.com/openclaw/openclaw) AI agents. It hooks into OpenClaw's plugin system to intercept every tool execution (file writes, shell commands, network requests) and enforces human-in-the-loop approval before dangerous actions execute.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%23007ACC.svg)](http://www.typescriptlang.org/)\n[![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)\n\n## Why?\n\nOpenClaw can execute shell commands, modify files, and access your APIs. OS-level isolation (containers, VMs) protects your **host machine**, but it doesn't protect the **services your agent has access to**.\n\nClawBands solves this by hooking into OpenClaw's `before_tool_call` plugin event. Before any dangerous action executes (writes, deletes, shell commands, API calls), the agent pauses and waits for your decision. In a terminal, you get an interactive prompt. On messaging channels (WhatsApp, Telegram), the agent asks you YES/NO and relays your answer via a dedicated `clawbands_respond` tool. Every choice is logged to an immutable audit trail. Think of it as `sudo` for your AI agent: nothing happens without your explicit permission.\n\n## Features\n\n- 🔒 **Synchronous Blocking** - Agent pauses until you approve\n- ⚙️ **Granular Control** - Allow reads, ask on writes, deny deletes\n- 💬 **Channel Support** - Works in terminal, WhatsApp, Telegram via `clawbands_respond` tool\n- 📊 **Full Audit Trail** - Every decision logged (JSON Lines format)\n- ⚡ **Zero Latency** - Runs in-process, no API calls\n\n## Quick Start\n\n### Prerequisites\n- Node.js \u003e= 18.0.0\n- OpenClaw installed\n\n### Installation\n\n```bash\n# Install globally\nnpm install -g clawbands\n\n# Run interactive setup\nclawbands init\n\n# Restart OpenClaw\nopenclaw restart\n```\n\nDone! ClawBands is now protecting your OpenClaw instance.\n\n## How It Works\n\n### Terminal Mode (TTY)\n\n```\nAgent calls tool: write('/etc/passwd', 'hacked')\n  → before_tool_call hook fires\n  → ClawBands checks policy: write = ASK\n  → Interactive prompt:\n    ┌─────────────────────────────────────┐\n    │ 🦞 CLAWBANDS SECURITY ALERT         │\n    │                                     │\n    │ Module: FileSystem                  │\n    │ Method: write                       │\n    │ Args: [\"/etc/passwd\", \"hacked\"]     │\n    │                                     │\n    │ ❯ ✓ Approve                         │\n    │   ✗ Reject                          │\n    └─────────────────────────────────────┘\n  → You reject → { block: true }\n  → Decision logged to audit trail\n```\n\n### Channel Mode (WhatsApp / Telegram)\n\n```\nAgent calls tool: bash('rm -rf /tmp/data')\n  → before_tool_call → policy = ASK → blocked (pending approval)\n  → Agent asks: \"ClawBands requires approval. YES or NO?\"\n\nUser replies YES:\n  → Agent calls clawbands_respond({ decision: \"yes\" })\n  → before_tool_call intercepts → approves pending entry\n  → Agent retries bash('rm -rf /tmp/data') → approved ✓\n\nUser replies NO:\n  → Agent calls clawbands_respond({ decision: \"no\" })\n  → before_tool_call intercepts → denies pending entry\n  → Agent does NOT retry → cancelled ✓\n```\n\nThe `clawbands_respond` tool is registered automatically via `api.registerTool()` when the gateway supports it.\n\n## Security Policies\n\nClawBands uses three decision types:\n\n| Policy | Behavior |\n|--------|----------|\n| **ALLOW** | Execute immediately (e.g., file reads) |\n| **ASK** | Prompt for approval (e.g., file writes) |\n| **DENY** | Block automatically (e.g., file deletes) |\n\nDefault policy (Balanced):\n- FileSystem: read=ALLOW, write=ASK, delete=DENY\n- Shell: bash=ASK, exec=ASK\n- Network: fetch=ASK, request=ASK\n- Everything else: ASK (fail-secure default)\n\n## CLI Commands\n\n```bash\nclawbands init        # Interactive setup wizard\nclawbands policy      # Manage security policies\nclawbands stats       # View statistics\nclawbands audit       # View decision history\nclawbands reset       # Reset statistics\nclawbands disable     # Temporarily disable\nclawbands enable      # Re-enable\n```\n\n## Example: View Audit Trail\n\n```bash\n$ clawbands audit --lines 5\n\n16:05:00 | FileSystem.read              | ALLOWED    |   0.0s\n16:06:00 | FileSystem.write             | APPROVED   |   3.5s (human)\n16:07:00 | Shell.bash                   | REJECTED   |   1.2s (human)\n16:08:00 | FileSystem.delete            | BLOCKED    |   0.0s - Policy: DENY\n```\n\n## Example: View Statistics\n\n```bash\n$ clawbands stats\n\n📊 ClawBands Statistics\n\nTotal Calls:    142\n\nDecisions:\n  ✅ Allowed:      35 (24.6%)\n  ✅ Approved:     89 (62.7%) - by user\n  ❌ Rejected:     12 (8.5%)  - by user\n  🚫 Blocked:       6 (4.2%)  - by policy\n\nAverage Decision Time: 2.8s\n```\n\n## Data Storage\n\nAll data stored in `~/.openclaw/clawbands/`:\n\n```\n~/.openclaw/clawbands/\n├── policy.json       # Your security rules\n├── decisions.jsonl   # Audit trail (append-only)\n├── stats.json        # Statistics\n└── clawbands.log     # Application logs\n```\n\n## Use as a Library\n\n```typescript\nimport { Interceptor, createToolCallHook } from 'clawbands';\n\n// Create interceptor with default policy\nconst interceptor = new Interceptor();\n\n// Create a hook handler for OpenClaw's before_tool_call event\nconst hook = createToolCallHook(interceptor);\n\n// Register with the OpenClaw plugin API\napi.on('before_tool_call', hook);\n```\n\n## Protected Tools\n\nClawBands intercepts every tool mapped in `TOOL_TO_MODULE`:\n- **FileSystem**: read, write, edit, glob\n- **Shell**: bash, exec\n- **Browser**: navigate, screenshot, click, type, evaluate\n- **Network**: fetch, request, webhook, download\n- **Gateway**: listSessions, listNodes, sendMessage\n\nAny unmapped tool falls through to `defaultAction` (ASK by default).\n\n## Architecture\n\n```\nsrc/\n├── core/\n│   ├── Interceptor.ts    # Policy evaluation engine\n│   ├── Arbitrator.ts     # Human-in-the-loop (TTY prompt / channel queue)\n│   ├── ApprovalQueue.ts  # In-memory approval state for channel mode\n│   └── Logger.ts         # Winston-based logging\n├── plugin/\n│   ├── index.ts              # Plugin entry point (hook + tool registration)\n│   ├── tool-interceptor.ts   # before_tool_call handler + clawbands_respond intercept\n│   └── config-manager.ts     # OpenClaw config management (register/unregister)\n├── storage/        # Persistence (PolicyStore, DecisionLog, StatsTracker)\n├── cli/            # Command-line interface\n├── types.ts        # TypeScript definitions\n└── config.ts       # Default policies\n```\n\n## Development\n\n```bash\n# Clone repo\ngit clone https://github.com/SeyZ/clawbands.git\ncd clawbands\n\n# Install dependencies\nnpm install\n\n# Build\nnpm run build\n\n# Test CLI locally\nnode dist/cli/index.js init\n\n# Link for global testing\nnpm link\nclawbands --help\n```\n\n## Security Guarantees\n\n✅ **Zero Trust** - Every action evaluated\n✅ **Synchronous Blocking** - Agent waits for approval\n✅ **No Bypass** - Plugin hooks intercept all tool calls\n✅ **Immutable Audit** - JSON Lines append-only format\n✅ **Human Authority** - Critical decisions need approval\n✅ **Fail Secure** - Unknown actions default to ASK/DENY\n\n## Contributing\n\nWe believe in safe AI. PRs welcome!\n\n1. Fork the repo\n2. Create your feature branch: `git checkout -b feature/amazing`\n3. Commit changes: `git commit -m 'Add amazing feature'`\n4. Push: `git push origin feature/amazing`\n5. Open a Pull Request\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n## License\n\nMIT - See [LICENSE](LICENSE) for details.\n\n## Acknowledgments\n\n- Built for [OpenClaw](https://github.com/openclaw) agents\n- Inspired by the need for human oversight in AI systems\n- Thanks to the AI safety community\n\n---\n\n**Built with ❤️ for a safer AI future.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseyz%2Fclawbands","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseyz%2Fclawbands","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseyz%2Fclawbands/lists"}