clawedr/
├── builder/ # THE FORGE — private build tools
│ ├── threat_aggregator.py # Fetches ClawSec advisory feed
│ ├── compiler.py # Compiles rules into kernel policies
│ ├── master_rules.yaml # Manual overrides (source of truth, Rule IDs)
│ ├── config.yaml # Forge environment config (VM host, etc.)
│ └── tests/
│ ├── test_mac_sb.py # macOS Seatbelt enforcement tests
│ └── test_linux_bpf.py # Linux eBPF tests via OrbStack VM
│
├── deploy/ # THE REGISTRY — public artifacts
│ ├── install.sh # One-liner OS-detecting dispatcher
│ ├── compiled_policy.json # Universal policy (Rule IDs for both OSes)
│ ├── linux/
│ │ ├── bpf_hooks.c # eBPF tracepoint hooks (execve interception)
│ │ ├── monitor.py # Shield daemon — hot-reloads BPF maps
│ │ └── shield_linux.sh # Linux setup script (systemd integration)
│ ├── macos/
│ │ ├── clawedr.sb # Compiled Seatbelt LISP profile
│ │ ├── log_tailer.py # Sandbox log monitor + alert dispatcher
│ │ ├── apply_macos_policy.py # Runtime Seatbelt generator (applies exemptions)
│ │ └── shield_mac.sh # macOS setup script
│ ├── shared/
│ │ ├── user_rules.py # Reads/writes ~/.clawedr/user_rules.yaml
│ │ └── alert_dispatcher.py # Pushes alerts to OpenClaw chat
│ └── dashboard/
│ ├── app.py # FastAPI backend (alerts, rules, exemptions)
│ └── templates/index.html # Browser-based dashboard UI
│
├── main.py # Forge CLI (sync / compile / test / publish)
├── requirements-dev.txt # Forge-only Python dependencies
└── .github/workflows/ci.yml # CI validation on push
The Forge runs on the developer's machine. It fetches threat intelligence, compiles kernel policies, validates them, and publishes to the Registry.
sync pulls the ClawSec advisory feed, extracts affected_skills, malicious_hashes, and blocked_domains, and merges them with manual overrides in builder/master_rules.yaml. The result is cached at builder/.merged_rules.json.
compile reads the merged rules and produces:
deploy/compiled_policy.json— universal policy consumed by both platforms at runtimedeploy/macos/clawedr.sb— Seatbelt LISP profile withdenyrules for every blocked path/executable
test runs pytest builder/tests/ covering Seatbelt syntax validation, runtime enforcement, and Linux eBPF policy loading.
publish stages deploy/, commits, and pushes to GitHub.
Public artifacts served over HTTPS from GitHub. End-users pull these via install.sh.
Kernel-level enforcement daemon installed on end-user machines.
ClawSec Feed (community) master_rules.yaml (manual)
├── affected_skills + ├── blocked_paths
├── malicious_hashes + ├── blocked_domains
└── blocked_domains + ├── blocked_executables
└── custom_deny_rules
↓
.merged_rules.json
↓
┌──────────────┴──────────────┐
│ │
compiled_policy.json clawedr.sb
(Linux) (macOS)
Feed entries add to manual rules, never replace them.
The Shield runs as a background daemon (monitor.py) that:
- Loads
compiled_policy.jsoninto eBPF hash maps - Auto-detects OpenClaw processes (gateway, agent, node) and tracks their entire process tree via BPF
fork/exithooks — only these processes are subject to policy enforcement - Hooks
execve()via BPF tracepoints — blocked executables spawned by OpenClaw receiveSIGKILL - Polls for policy file changes and hot-reloads BPF maps without restarting
Logs are written to both /var/log/clawedr_monitor.log and journalctl -u clawedr-monitor.
eBPF LSM socket_connect blocks connections at the kernel level (returns -EPERM). Requires CONFIG_BPF_LSM=y and lsm=...,bpf in the kernel cmdline. Falls back to tracepoint + SIGKILL if unavailable.
ClawEDR only monitors OpenClaw (gateway, agent, node) and their descendants. Non-OpenClaw processes are never tracked. The install script sets tools.exec.host=gateway and agents.defaults.sandbox.mode=off in ~/.openclaw/openclaw.json so that agent exec runs on the gateway host and is subject to blocking. Restart the gateway after install for the config to take effect.
Deny rules (LIN-030, LIN-031) block kill/pkill/systemctl stop clawedr when run by an OpenClaw descendant. They do not affect admin operations from a normal shell.
openclawwrapper runs the agent undersandbox-exec -f clawedr.sb- The
.sbprofile denies file reads/writes to sensitive paths (~/.ssh,~/.gnupg,~/.aws,~/Library/Keychains) log_tailer.pymonitors sandbox violation events and dispatches alerts
Seatbelt profiles bind at process start and cannot be hot-reloaded. Logs appear in Console.app (subsystem com.clawedr.shield) or /tmp/clawedr_log_tailer.log.
macOS note: Ensure /usr/local/bin comes before /opt/homebrew/bin in PATH. Verify with: sandbox-exec -f /usr/local/share/clawedr/clawedr.sb -- nc -h (should fail with "Operation not permitted").
Web UI on port 8477, auto-installed as a system service on both platforms.
- Alerts — Real-time blocked actions with Rule IDs. Click "Exempt" to bypass a rule.
- Policy Rules — Browse all active rules by category. Toggle exemptions inline. Add/edit/delete custom rules.
- Platform filtering — Auto-detects OS, pill bar to switch views.
- Sessions — Active OpenClaw instances being monitored.
- Settings — Auto-update toggle, manual update check.
- Rule updates — Hourly registry checks. Linux: auto-enforced via hot-reload. macOS: banner prompts restart.
| Method | Path | Description |
|---|---|---|
GET |
/api/status |
Shield health: OS, policy state, OpenClaw availability |
GET |
/api/alerts |
Recent blocked actions parsed from logs |
GET |
/api/rules |
Full compiled policy with Rule IDs |
GET |
/api/user-rules |
Current user exemptions and custom rules |
POST |
/api/user-rules |
Update exemptions (preserves custom rules) |
GET |
/api/custom-rules |
List all user-defined custom rules |
POST |
/api/custom-rules |
Add a custom rule ({"type": "domain", "value": "evil.com", "platform": "both"}) |
PUT |
/api/custom-rules/{id} |
Update a custom rule |
DELETE |
/api/custom-rules/{id} |
Delete a custom rule |
GET |
/api/sessions |
Active OpenClaw sessions |
GET |
/api/settings |
Dashboard settings |
POST |
/api/settings |
Update settings |
GET |
/api/updates |
Check for rule updates from registry |
POST |
/api/updates/apply |
Download and apply updates |
# macOS
sudo launchctl unload /Library/LaunchDaemons/com.clawedr.dashboard.plist # stop
sudo launchctl load -w /Library/LaunchDaemons/com.clawedr.dashboard.plist # start
cat /tmp/clawedr_dashboard.log
# Linux
sudo systemctl stop clawedr-dashboard
sudo systemctl start clawedr-dashboard
sudo journalctl -u clawedr-dashboard -fAll customizations in ~/.clawedr/user_rules.yaml survive system updates.
exempted_rule_ids:
- "BIN-001" # Allow nc
- "LIN-004" # Allow stratum+tcpcustom_rules:
- id: USR-BIN-001
type: executable
value: terraform
- id: USR-DOM-001
type: domain
value: evil.com
- id: USR-HASH-001
type: hash
value: "sha256:a1b2c3d4e5f6..."
- id: USR-PATH-001
type: path
value: /var/secrets
platform: linux
- id: USR-ARG-001
type: argument
value: "--password"| Type | Blocks | Validation |
|---|---|---|
executable |
Binary by name | No paths, no protected binaries |
domain |
Domain name or IP | RFC-compliant, rejects URLs |
hash |
SHA-256 file hash | 64 hex chars, optional sha256: prefix |
path |
File/directory access | Absolute or ~/, cannot be root |
argument |
Command-line args (regex) | Must be valid regex |
Linux: Custom rules merge into BPF maps on every policy reload (hot-reloaded).
macOS: apply_macos_policy.py rebuilds clawedr.sb including custom rules. Requires agent restart.
| Test | Platform | Validates |
|---|---|---|
| Profile syntax | macOS | .sb file has valid Seatbelt directives |
| Blocked path enforcement | macOS | sandbox-exec denies reads to ~/.ssh |
| Allowed commands | macOS | Benign commands work under sandbox |
| VM SSH connectivity | Linux | SSH to the test VM works |
| BCC availability | Linux | Python BCC bindings importable |
| Policy loading | Linux | compiled_policy.json parses correctly |
| Blocked executable | Linux | nc appears in blocked list |
Configure the Linux test VM in builder/config.yaml:
linux_vm:
host: "orb"
user: "ubuntu"GitHub Actions (.github/workflows/ci.yml) runs on every push to main:
- Installs Python dependencies
- Compiles policies from
master_rules.yaml - Verifies
deploy/artifacts exist - Runs unit tests (skips platform-specific enforcement tests)