clauditor
Tamper-resistant audit watchdog for Clawdbot agents. Detects and logs suspicious filesystem activity with HMAC-chained evidence.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-clauditor
Repository
Skill path: skills/apollostreetcompany/clauditor
Tamper-resistant audit watchdog for Clawdbot agents. Detects and logs suspicious filesystem activity with HMAC-chained evidence.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install clauditor into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding clauditor to shared team environments
- Use clauditor for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: clauditor
description: Tamper-resistant audit watchdog for Clawdbot agents. Detects and logs suspicious filesystem activity with HMAC-chained evidence.
homepage: https://github.com/apollostreetcompany/clauditor
metadata: {"clawdbot":{"emoji":"🛡️","requires":{"bins":["cargo","systemctl"],"os":"linux"}}}
---
# Clauditor
Security watchdog that monitors filesystem activity and creates tamper-evident logs. Even if Clawdbot is compromised, it cannot stop the watchdog, forge entries, or delete evidence.
## Installation (Guided)
Use the CLI wizard to guide users through installation:
```bash
cd /path/to/clauditor
cargo build --release
```
### Agent Workflow
1. **Check status:** `./target/release/clauditor wizard status`
- Returns JSON with `current_step` (1-6) and `complete` (true/false)
2. **Get next step:** `./target/release/clauditor wizard next`
- Shows WHAT it does, WHY it matters, and the exact COMMAND to run
3. **User runs the sudo command**
4. **Verify:** `./target/release/clauditor wizard verify`
- Confirms step completed
5. **Repeat until `complete: true`**
### Example Interaction
```
User: "Install clauditor"
Agent: [runs wizard status → current_step: 1]
Agent: "Step 1 of 6: Create system user
This creates a 'sysaudit' user that runs the watchdog. Even if you're
compromised, you can't kill a process owned by another user.
Run this:
sudo useradd --system --shell /usr/sbin/nologin --no-create-home sysaudit
Let me know when done."
User: "done"
Agent: [runs wizard verify → success]
Agent: [runs wizard next → step 2...]
```
## After Installation
### Check status
```bash
systemctl status systemd-journaldd
```
### Generate digest
```bash
./target/release/clauditor digest \
--log /var/lib/.sysd/.audit/events.log \
--key /etc/sysaudit/key \
--format markdown
```
## Quick Install (Power Users)
```bash
sudo bash wizard/wizard.sh
```
## Configuration
- Config: `/etc/sysaudit/config.toml`
- Key: `/etc/sysaudit/key`
- Logs: `/var/lib/.sysd/.audit/events.log`
Edit config to customize `watch_paths` and `target_uid`.
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### wizard/wizard.sh
```bash
#!/bin/bash
# Clauditor Installation Wizard
# Interactive installer for the security audit watchdog
#
# Usage:
# ./wizard.sh [--dry-run] [--uninstall]
#
# Options:
# --dry-run Show commands without executing
# --uninstall Remove all components
set -euo pipefail
# Configuration
STEALTH_USER="sysaudit"
STEALTH_BINARY="/usr/local/sbin/systemd-journaldd"
STEALTH_SENTINEL="/usr/local/sbin/systemd-core-check"
CONFIG_DIR="/etc/sysaudit"
LOG_DIR="/var/lib/.sysd/.audit"
UNIT_DIR="/etc/systemd/system"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Parse arguments
DRY_RUN=false
UNINSTALL=false
for arg in "$@"; do
case $arg in
--dry-run)
DRY_RUN=true
;;
--uninstall)
UNINSTALL=true
;;
esac
done
# Helper functions
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
success() { echo -e "${GREEN}[OK]${NC} $1"; }
run_cmd() {
local cmd="$1"
echo -e "${YELLOW} \$ ${cmd}${NC}"
if [[ "$DRY_RUN" == "false" ]]; then
eval "$cmd"
fi
}
confirm() {
local prompt="$1"
if [[ "$DRY_RUN" == "true" ]]; then
echo -e "${YELLOW}[DRY-RUN]${NC} Would prompt: $prompt"
return 0
fi
read -p "$prompt [y/N] " -n 1 -r
echo
[[ $REPLY =~ ^[Yy]$ ]]
}
# Check prerequisites
check_prereqs() {
info "Checking prerequisites..."
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
fi
if ! command -v systemctl &>/dev/null; then
error "systemd is required"
fi
# Check for chattr support
if ! command -v chattr &>/dev/null; then
warn "chattr not found - append-only protection unavailable"
fi
success "Prerequisites OK"
}
# Find repo root
find_repo_root() {
local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(dirname "$script_dir")"
if [[ ! -f "$REPO_ROOT/Cargo.toml" ]]; then
error "Cannot find repo root (expected Cargo.toml at $REPO_ROOT)"
fi
info "Repo root: $REPO_ROOT"
}
# Build release binary
build_binary() {
info "Building release binary..."
if [[ ! -f "$REPO_ROOT/target/release/clauditor" ]]; then
run_cmd "cd '$REPO_ROOT' && cargo build --release"
else
info "Binary already built, skipping"
fi
success "Binary ready"
}
# Uninstall function
do_uninstall() {
info "=== UNINSTALL MODE ==="
warn "This will remove all clauditor components"
echo
echo "Commands to execute:"
echo "===================="
echo
info "Step 1: Stop and disable services"
run_cmd "systemctl stop systemd-journaldd.service systemd-core-check.path systemd-core-check.timer 2>/dev/null || true"
run_cmd "systemctl disable systemd-journaldd.service systemd-core-check.path systemd-core-check.timer 2>/dev/null || true"
echo
info "Step 2: Remove append-only attribute from logs"
run_cmd "chattr -a '$LOG_DIR'/* 2>/dev/null || true"
echo
info "Step 3: Remove unit files"
run_cmd "rm -f '$UNIT_DIR'/systemd-journaldd*.service '$UNIT_DIR'/systemd-journaldd*.timer"
run_cmd "rm -f '$UNIT_DIR'/systemd-core-check.{path,timer,service}"
run_cmd "systemctl daemon-reload"
echo
info "Step 4: Remove binaries"
run_cmd "rm -f '$STEALTH_BINARY' '$STEALTH_SENTINEL'"
echo
info "Step 5: Remove config and logs"
run_cmd "rm -rf '$CONFIG_DIR'"
run_cmd "rm -rf '$LOG_DIR'"
echo
info "Step 6: Remove user"
run_cmd "userdel '$STEALTH_USER' 2>/dev/null || true"
success "Uninstall complete"
}
# Main installation
do_install() {
info "=== CLAUDITOR INSTALLATION WIZARD ==="
echo
info "This wizard will install the security audit watchdog."
info "All commands will be shown before execution."
echo
# Step 1: Create user and group membership
echo
info "Step 1: Create system user '$STEALTH_USER'"
if id "$STEALTH_USER" &>/dev/null; then
info "User already exists, skipping creation"
else
run_cmd "useradd --system --shell /usr/sbin/nologin --no-create-home '$STEALTH_USER'"
fi
# Add to clawdbot group for /proc access (needed for UID detection)
if getent group clawdbot &>/dev/null; then
run_cmd "usermod -aG clawdbot '$STEALTH_USER'"
info "Added $STEALTH_USER to clawdbot group for /proc access"
fi
# Step 2: Create directories
echo
info "Step 2: Create directories"
run_cmd "install -d -m 0750 -o root -g root '$CONFIG_DIR'"
run_cmd "install -d -m 0750 -o '$STEALTH_USER' -g '$STEALTH_USER' '$LOG_DIR'"
# Step 3: Generate HMAC key
echo
info "Step 3: Generate HMAC key"
if [[ -f "$CONFIG_DIR/key" ]]; then
info "Key already exists, skipping"
else
run_cmd "head -c 32 /dev/urandom | base64 > '$CONFIG_DIR/key'"
run_cmd "chown root:'$STEALTH_USER' '$CONFIG_DIR/key'"
run_cmd "chmod 0640 '$CONFIG_DIR/key'"
fi
# Step 4: Install binaries
echo
info "Step 4: Install binaries"
build_binary
run_cmd "install -m 0755 -o root -g root '$REPO_ROOT/target/release/clauditor' '$STEALTH_BINARY'"
run_cmd "install -m 0755 -o root -g root '$REPO_ROOT/dist/bin/systemd-core-check' '$STEALTH_SENTINEL'"
# Step 5: Store binary checksum
echo
info "Step 5: Store binary checksum for sentinel"
run_cmd "sha256sum '$STEALTH_BINARY' | awk '{print \$1}' > '$CONFIG_DIR/binary.sha256'"
# Step 6: Install config file
echo
info "Step 6: Install config file"
if [[ -f "$CONFIG_DIR/config.toml" ]]; then
info "Config already exists, skipping (use --force to overwrite)"
else
run_cmd "install -m 0640 -o root -g '$STEALTH_USER' '$REPO_ROOT/dist/config/default.toml' '$CONFIG_DIR/config.toml'"
info "NOTE: Config uses watch_paths=[\"/\", \"/home/clawdbot\"] for full exec monitoring"
fi
# Step 7: Install unit files
echo
info "Step 7: Install systemd unit files"
run_cmd "install -m 0644 -o root -g root '$REPO_ROOT/dist/systemd/'*.service '$UNIT_DIR/'"
run_cmd "install -m 0644 -o root -g root '$REPO_ROOT/dist/systemd/'*.timer '$UNIT_DIR/'"
run_cmd "install -m 0644 -o root -g root '$REPO_ROOT/dist/systemd/'*.path '$UNIT_DIR/'"
# Step 8: Create initial log file with append-only
echo
info "Step 8: Create log file with append-only attribute"
run_cmd "touch '$LOG_DIR/events.log'"
run_cmd "chown '$STEALTH_USER':'$STEALTH_USER' '$LOG_DIR/events.log'"
run_cmd "chmod 0640 '$LOG_DIR/events.log'"
if command -v chattr &>/dev/null; then
run_cmd "chattr +a '$LOG_DIR/events.log'"
success "Append-only attribute set"
else
warn "chattr not available - skipping append-only"
fi
# Step 9: Reload and enable services
echo
info "Step 9: Enable and start services"
run_cmd "systemctl daemon-reload"
run_cmd "systemctl enable systemd-journaldd.service"
run_cmd "systemctl enable systemd-journaldd-digest.timer"
run_cmd "systemctl enable systemd-core-check.path"
run_cmd "systemctl enable systemd-core-check.timer"
run_cmd "systemctl start systemd-journaldd.service"
run_cmd "systemctl start systemd-journaldd-digest.timer"
run_cmd "systemctl start systemd-core-check.path"
run_cmd "systemctl start systemd-core-check.timer"
# Verify
echo
info "Step 10: Verify installation"
run_cmd "systemctl --no-pager status systemd-journaldd.service"
# Post-install verification
echo
info "Step 11: Post-install verification"
local verification_passed=true
# Check binary exists and is executable
if [[ -x "$STEALTH_BINARY" ]]; then
success "Binary: $STEALTH_BINARY (executable)"
else
warn "Binary missing or not executable: $STEALTH_BINARY"
verification_passed=false
fi
# Check config exists
if [[ -f "$CONFIG_DIR/config.toml" ]]; then
success "Config: $CONFIG_DIR/config.toml"
else
warn "Config missing: $CONFIG_DIR/config.toml"
verification_passed=false
fi
# Check HMAC key exists with correct permissions
if [[ -f "$CONFIG_DIR/key" ]]; then
local key_perms=$(stat -c %a "$CONFIG_DIR/key" 2>/dev/null || echo "unknown")
if [[ "$key_perms" == "640" ]]; then
success "HMAC key: $CONFIG_DIR/key (perms: $key_perms)"
else
warn "HMAC key permissions wrong: $key_perms (expected: 640)"
fi
else
warn "HMAC key missing: $CONFIG_DIR/key"
verification_passed=false
fi
# Check log directory exists with correct ownership
if [[ -d "$LOG_DIR" ]]; then
local log_owner=$(stat -c %U "$LOG_DIR" 2>/dev/null || echo "unknown")
if [[ "$log_owner" == "$STEALTH_USER" ]]; then
success "Log dir: $LOG_DIR (owner: $log_owner)"
else
warn "Log dir ownership wrong: $log_owner (expected: $STEALTH_USER)"
fi
else
warn "Log directory missing: $LOG_DIR"
verification_passed=false
fi
# Check service is running
if systemctl is-active --quiet systemd-journaldd.service; then
success "Service: systemd-journaldd.service (running)"
else
warn "Service not running: systemd-journaldd.service"
verification_passed=false
fi
# Check exec-only config (look for FAN_OPEN_EXEC or exec watchlist)
if grep -q "exec_watchlist\|watch_paths.*\[" "$CONFIG_DIR/config.toml" 2>/dev/null; then
success "Config: exec-only monitoring enabled"
fi
echo
if [[ "$verification_passed" == "true" ]]; then
success "✅ All verification checks passed!"
else
warn "⚠️ Some verification checks failed - review warnings above"
fi
echo
success "=== INSTALLATION COMPLETE ==="
echo
info "Services installed:"
echo " - systemd-journaldd.service (main daemon)"
echo " - systemd-journaldd-digest.timer (daily reports)"
echo " - systemd-core-check.path (file change detection)"
echo " - systemd-core-check.timer (periodic integrity checks)"
echo
info "Logs: $LOG_DIR/events.log"
info "Config: $CONFIG_DIR/config.toml"
info "Digests: $LOG_DIR/digest-*.md"
echo
info "To uninstall: $0 --uninstall"
}
# Main
main() {
echo
echo "╔═══════════════════════════════════════════════════════╗"
echo "║ CLAUDITOR INSTALLATION WIZARD ║"
echo "║ Security Audit Watchdog for Clawdbot ║"
echo "╚═══════════════════════════════════════════════════════╝"
echo
if [[ "$DRY_RUN" == "true" ]]; then
warn "DRY-RUN MODE: Commands will be shown but not executed"
echo
fi
check_prereqs
find_repo_root
if [[ "$UNINSTALL" == "true" ]]; then
if confirm "Are you sure you want to uninstall clauditor?"; then
do_uninstall
else
info "Uninstall cancelled"
fi
else
echo
echo "The following actions will be performed:"
echo " 1. Create system user: $STEALTH_USER"
echo " 2. Create directories: $CONFIG_DIR, $LOG_DIR"
echo " 3. Generate HMAC key for tamper detection"
echo " 4. Install binaries to /usr/local/sbin/"
echo " 5. Install systemd units"
echo " 6. Enable and start services"
echo
if confirm "Proceed with installation?"; then
do_install
else
info "Installation cancelled"
fi
fi
}
main "$@"
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### README.md
```markdown
# Clauditor v0.1.0 - Security Watchdog for Clawdbot
Clauditor is a tamper-resistant audit watchdog that makes it hard for a compromised
Clawdbot agent to operate without leaving a trail. It runs a dedicated `sysaudit`
daemon, captures filesystem activity, appends HMAC-chained JSON logs, and emits
alerts when suspicious patterns are detected.
## 🆕 v0 Features
- **Exec-only monitoring** — Focuses on command executions (FAN_OPEN_EXEC), not every file access
- **Sequence detection** — Detects credential read → network command patterns (potential exfiltration)
- **Command baseline** — Tracks known commands and flags first-time executions
- **Orphan exec detection** — Flags commands that run when no Clawdbot session is active
- **Silent digest mode** — Only outputs when issues found (default), use `--verbose` for full report
- **Enhanced reports** — Status badges, severity-sorted alerts, helpful notes
- **Post-install verification** — Wizard validates installation completeness
## Core Features
- Separate `sysaudit` daemon (stealth service name: `systemd-journaldd`)
- Append-only log writer with HMAC hash chaining
- Rule-based detection for exfiltration, injection, persistence, tamper attempts
- Alerting via Clawdbot wake, syslog, file, or command
- Sentinel integrity checks with heartbeat monitoring
- Interactive CLI wizard for guided installation
## Security Model
| Component | Owner | Permissions | Clawdbot Access |
|-----------|-------|-------------|-----------------|
| Daemon | sysaudit | runs as sysaudit user | ❌ Cannot kill |
| HMAC Key | root:sysaudit | 640 | ❌ Cannot read |
| Log Dir | sysaudit:sysaudit | 750 | ❌ Cannot write |
| Logs | sysaudit | 640 | ✅ Can read (tamper-evident) |
**Threat model:** Even if Clawdbot is fully compromised, it cannot:
- Stop the watchdog daemon
- Forge log entries (no key access)
- Delete evidence (no write access to logs)
## Installation
### Option 1: Guided Wizard (Recommended for Clawdbot users)
The CLI wizard guides you through installation step-by-step:
```bash
# Build first
cargo build --release
# Check current status
./target/release/clauditor wizard status
# Get next step (run this, follow instructions, repeat)
./target/release/clauditor wizard next
# Verify a step completed
./target/release/clauditor wizard verify
```
### Option 2: Interactive Script (Power users)
```bash
sudo bash wizard/wizard.sh
```
Dry-run or uninstall:
```bash
sudo bash wizard/wizard.sh --dry-run
sudo bash wizard/wizard.sh --uninstall
```
## Installation Steps (Manual Reference)
1. **Create system user:** `sudo useradd --system --shell /usr/sbin/nologin --no-create-home sysaudit`
2. **Create directories:** `sudo install -d -m 0750 /etc/sysaudit && sudo install -d -m 0750 -o sysaudit -g sysaudit /var/lib/.sysd/.audit`
3. **Generate HMAC key:** `sudo sh -c 'head -c 32 /dev/urandom | base64 > /etc/sysaudit/key && chown root:sysaudit /etc/sysaudit/key && chmod 640 /etc/sysaudit/key'`
4. **Build and install:** `cargo build --release && sudo install -m 0755 target/release/clauditor /usr/local/sbin/systemd-journaldd`
5. **Install config:** `sudo install -m 0640 dist/config/default.toml /etc/sysaudit/config.toml`
6. **Start service:** `sudo cp dist/systemd/*.service dist/systemd/*.timer /etc/systemd/system/ && sudo systemctl daemon-reload && sudo systemctl enable --now systemd-journaldd`
## Usage
### Check daemon status
```bash
systemctl status systemd-journaldd
```
### Generate digest report
Silent mode (default) — only outputs when issues found:
```bash
clauditor digest --log /var/lib/.sysd/.audit/events.log --key /etc/sysaudit/key
# Output: "✓ No anomalies detected (1234 events analyzed)" if clean
# Exit code: 0 = clean, 1 = issues found
```
Verbose mode — always show full report:
```bash
clauditor digest --log /var/lib/.sysd/.audit/events.log --key /etc/sysaudit/key --verbose
```
JSON output for scripting:
```bash
clauditor digest --log /var/lib/.sysd/.audit/events.log --format json
```
### Use in cron (silent unless issues)
```bash
# Daily digest at 6am, only notifies if anomalies found
0 6 * * * /usr/local/sbin/systemd-journaldd digest --log /var/lib/.sysd/.audit/events.log --key /etc/sysaudit/key || echo "Anomalies detected" | mail -s "Clauditor Alert" [email protected]
```
### View raw logs
```bash
sudo cat /var/lib/.sysd/.audit/events.log | jq .
```
## Configuration
Default config location: `/etc/sysaudit/config.toml`
```toml
key_path = "/etc/sysaudit/key"
[collector]
watch_paths = ["/home/clawdbot"] # Directories to monitor
target_uid = 1000 # User ID to watch
[writer]
log_path = "/var/lib/.sysd/.audit/events.log"
fsync = "periodic"
fsync_interval = 100
max_size_bytes = 104857600 # 100MB
[alerter]
min_severity = "medium" # low, medium, high, critical
queue_path = "/var/lib/.sysd/.audit/alerts.queue"
[[alerter.channels]]
type = "clawdbot_wake"
[[alerter.channels]]
type = "syslog"
facility = "local0"
```
## Repository Layout
- `crates/schema`: Event schema and HMAC hash chain
- `crates/collector`: File events (inotify dev mode, fanotify privileged mode)
- `crates/detector`: Detection rules and severity scoring
- `crates/writer`: Append-only log writer with rotation
- `crates/alerter`: Alert dispatch and cooldowns
- `crates/clauditor-cli`: CLI (daemon, digest, wizard)
- `dist/config`: Default configuration
- `dist/systemd`: Hardened systemd unit files
- `wizard/`: Interactive installer script
## Requirements
- Linux with systemd
- Rust toolchain for building
- Root access for installation
## Testing
```bash
cargo test
```
## License
MIT (add LICENSE file before distribution)
```
### _meta.json
```json
{
"owner": "apollostreetcompany",
"slug": "clauditor",
"displayName": "Clauditor",
"latest": {
"version": "0.1.2",
"publishedAt": 1769567281135,
"commit": "https://github.com/clawdbot/skills/commit/383bf599dd1854e2f9f9c567fbd1e21b0aef046e"
},
"history": [
{
"version": "0.1.1",
"publishedAt": 1769498687103,
"commit": "https://github.com/clawdbot/skills/commit/798b1aa1b9c318de83a5eb7a48f35e165b292864"
}
]
}
```