Back to skills
SkillHub ClubShip Full StackFull Stack

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.

Stars
3,111
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
C65.6

Install command

npx @skill-hub/cli install openclaw-skills-clauditor

Repository

openclaw/skills

Skill path: skills/apollostreetcompany/clauditor

Tamper-resistant audit watchdog for Clawdbot agents. Detects and logs suspicious filesystem activity with HMAC-chained evidence.

Open repository

Best 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

Claude CodeCodex CLIGemini CLIOpenCode

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"
    }
  ]
}

```

clauditor | SkillHub