clawdbot-workspace/fix-clawdbot-permissions.sh
2026-01-28 23:00:58 -05:00

302 lines
9.5 KiB
Bash
Executable File

#!/bin/bash
#
# ClawdBot Permission Hardening Script
# Generated: 2026-01-27
# Purpose: Fix file permissions in ~/.clawdbot for security hardening
#
# Permission Guidelines:
# - Directories: 700 (owner only)
# - Databases (.sqlite): 600 (owner read/write only)
# - Config files with secrets: 600
# - Scripts (.sh): 700 (owner execute only)
# - General files: 600 (no world-readable)
# - All files owned by jakeshore:staff
#
set -e
CLAWDBOT_DIR="$HOME/.clawdbot"
LOG_FILE="$CLAWDBOT_DIR/workspace/permission-fix-$(date +%Y%m%d-%H%M%S).log"
echo "ClawdBot Permission Hardening Script"
echo "====================================="
echo "Logging to: $LOG_FILE"
echo ""
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
fix_ownership() {
local path="$1"
local current_owner=$(stat -f "%Su:%Sg" "$path" 2>/dev/null)
if [ "$current_owner" != "jakeshore:staff" ]; then
log "FIXING OWNERSHIP: $path ($current_owner -> jakeshore:staff)"
chown jakeshore:staff "$path"
fi
}
fix_permission() {
local path="$1"
local desired_perm="$2"
local current_perm=$(stat -f "%OLp" "$path" 2>/dev/null)
if [ "$current_perm" != "$desired_perm" ]; then
log "FIXING PERMISSION: $path ($current_perm -> $desired_perm)"
chmod "$desired_perm" "$path"
fi
}
echo "========================================"
echo "PHASE 1: Fix file ownership (wheel -> staff)"
echo "========================================"
# Fix clawdbot.json which has wheel group
log "Checking for files with incorrect group ownership..."
fix_ownership "$CLAWDBOT_DIR/clawdbot.json"
echo ""
echo "========================================"
echo "PHASE 2: Harden top-level directory"
echo "========================================"
# Root clawdbot directory should be 700
fix_permission "$CLAWDBOT_DIR" "700"
echo ""
echo "========================================"
echo "PHASE 3: Harden sensitive directories"
echo "========================================"
# These directories contain sensitive data - should be 700
SENSITIVE_DIRS=(
"$CLAWDBOT_DIR/agents"
"$CLAWDBOT_DIR/agents/main"
"$CLAWDBOT_DIR/agents/main/agent"
"$CLAWDBOT_DIR/agents/main/sessions"
"$CLAWDBOT_DIR/agents/imessage"
"$CLAWDBOT_DIR/agents/imessage/agent"
"$CLAWDBOT_DIR/agents/imessage/sessions"
"$CLAWDBOT_DIR/identity"
"$CLAWDBOT_DIR/memory"
"$CLAWDBOT_DIR/devices"
"$CLAWDBOT_DIR/subagents"
"$CLAWDBOT_DIR/tools"
"$CLAWDBOT_DIR/logs"
"$CLAWDBOT_DIR/cron"
"$CLAWDBOT_DIR/cron/runs"
"$CLAWDBOT_DIR/nodes"
"$CLAWDBOT_DIR/skills"
"$CLAWDBOT_DIR/browser"
"$CLAWDBOT_DIR/browser/clawd"
"$CLAWDBOT_DIR/browser/clawd/user-data"
"$CLAWDBOT_DIR/backups"
"$CLAWDBOT_DIR/lib"
"$CLAWDBOT_DIR/media"
"$CLAWDBOT_DIR/workspace"
)
for dir in "${SENSITIVE_DIRS[@]}"; do
if [ -d "$dir" ]; then
fix_permission "$dir" "700"
fi
done
echo ""
echo "========================================"
echo "PHASE 4: Harden databases (600)"
echo "========================================"
# SQLite databases - must be 600
while IFS= read -r -d '' dbfile; do
fix_permission "$dbfile" "600"
done < <(find "$CLAWDBOT_DIR" -type f \( -name "*.sqlite" -o -name "*.sqlite3" -o -name "*.db" \) -print0 2>/dev/null)
echo ""
echo "========================================"
echo "PHASE 5: Harden sensitive config files (600)"
echo "========================================"
# Sensitive config files that may contain secrets/tokens
SENSITIVE_FILES=(
"$CLAWDBOT_DIR/clawdbot.json"
"$CLAWDBOT_DIR/clawdbot.json.bak"
"$CLAWDBOT_DIR/clawdbot.json.bak.1"
"$CLAWDBOT_DIR/clawdbot.json.bak.2"
"$CLAWDBOT_DIR/clawdbot.json.bak.3"
"$CLAWDBOT_DIR/clawdbot.json.bak.4"
"$CLAWDBOT_DIR/clawdbot.json.backup-20260113-102502"
"$CLAWDBOT_DIR/clawdbot.json.backup-20260114-192759"
"$CLAWDBOT_DIR/clawdbot.json.backup-20260125-012611"
"$CLAWDBOT_DIR/identity/device.json"
"$CLAWDBOT_DIR/identity/device-auth.json"
"$CLAWDBOT_DIR/devices/paired.json"
"$CLAWDBOT_DIR/devices/pending.json"
"$CLAWDBOT_DIR/subagents/runs.json"
"$CLAWDBOT_DIR/nodes/paired.json"
"$CLAWDBOT_DIR/nodes/pending.json"
"$CLAWDBOT_DIR/cron/jobs.json"
"$CLAWDBOT_DIR/cron/jobs.json.bak"
"$CLAWDBOT_DIR/update-check.json"
"$CLAWDBOT_DIR/gateway.25337ee8.lock"
)
for file in "${SENSITIVE_FILES[@]}"; do
if [ -f "$file" ]; then
fix_permission "$file" "600"
fi
done
# Auth profile files in agents directories
while IFS= read -r -d '' authfile; do
fix_permission "$authfile" "600"
done < <(find "$CLAWDBOT_DIR/agents" -type f -name "auth-profiles.json" -print0 2>/dev/null)
# Session index files
while IFS= read -r -d '' sessfile; do
fix_permission "$sessfile" "600"
done < <(find "$CLAWDBOT_DIR/agents" -type f -name "sessions.json" -print0 2>/dev/null)
echo ""
echo "========================================"
echo "PHASE 6: Harden session logs (600)"
echo "========================================"
# Session log files may contain sensitive conversation data
while IFS= read -r -d '' sesslog; do
fix_permission "$sesslog" "600"
done < <(find "$CLAWDBOT_DIR/agents" -type f -name "*.jsonl" -print0 2>/dev/null)
while IFS= read -r -d '' sesslog; do
fix_permission "$sesslog" "600"
done < <(find "$CLAWDBOT_DIR/agents" -type f -name "*.jsonl.deleted.*" -print0 2>/dev/null)
# Cron run logs
while IFS= read -r -d '' cronlog; do
fix_permission "$cronlog" "600"
done < <(find "$CLAWDBOT_DIR/cron/runs" -type f -name "*.jsonl" -print0 2>/dev/null)
echo ""
echo "========================================"
echo "PHASE 7: Harden log files (600)"
echo "========================================"
while IFS= read -r -d '' logfile; do
fix_permission "$logfile" "600"
done < <(find "$CLAWDBOT_DIR/logs" -type f -print0 2>/dev/null)
echo ""
echo "========================================"
echo "PHASE 8: Harden shell scripts (700)"
echo "========================================"
# Shell scripts should be 700 (owner execute only)
SCRIPTS=(
"$CLAWDBOT_DIR/backup-to-icloud.sh"
)
for script in "${SCRIPTS[@]}"; do
if [ -f "$script" ]; then
fix_permission "$script" "700"
fi
done
echo ""
echo "========================================"
echo "PHASE 9: Harden backup directories"
echo "========================================"
# Recursively fix backup directory
while IFS= read -r -d '' backupdir; do
fix_permission "$backupdir" "700"
done < <(find "$CLAWDBOT_DIR/backups" -type d -print0 2>/dev/null)
while IFS= read -r -d '' backupfile; do
fix_permission "$backupfile" "600"
done < <(find "$CLAWDBOT_DIR/backups" -type f -print0 2>/dev/null)
echo ""
echo "========================================"
echo "PHASE 10: Verify symlinks"
echo "========================================"
log "Checking symlinks for potential security issues..."
# Check skills symlinks - they point to ../../.agents which is outside clawdbot
# This is a potential concern as it points to user home directory
SYMLINKS_OUTSIDE=(
"$CLAWDBOT_DIR/skills/remotion-best-practices"
"$CLAWDBOT_DIR/skills/threejs-animation"
"$CLAWDBOT_DIR/skills/threejs-fundamentals"
"$CLAWDBOT_DIR/skills/threejs-geometry"
"$CLAWDBOT_DIR/skills/threejs-interaction"
"$CLAWDBOT_DIR/skills/threejs-lighting"
)
log ""
log "WARNING: The following symlinks point outside ~/.clawdbot:"
for link in "${SYMLINKS_OUTSIDE[@]}"; do
if [ -L "$link" ]; then
target=$(readlink "$link")
resolved=$(cd "$(dirname "$link")" && cd "$(dirname "$target")" 2>/dev/null && pwd)/$(basename "$target")
log " $link -> $target"
log " Resolves to: $resolved"
fi
done
log ""
log "RECOMMENDATION: Consider copying these files into ~/.clawdbot/skills/ instead of symlinks"
log "to contain all sensitive data within the protected directory structure."
# Check node symlink (internal, acceptable)
if [ -L "$CLAWDBOT_DIR/tools/node" ]; then
target=$(readlink "$CLAWDBOT_DIR/tools/node")
log "OK: tools/node symlink is internal -> $target"
fi
echo ""
echo "========================================"
echo "PHASE 11: Final verification"
echo "========================================"
log ""
log "Checking for any remaining world-readable files..."
world_readable=$(find "$CLAWDBOT_DIR" -maxdepth 3 -type f -perm -004 2>/dev/null | grep -v node_modules | head -20)
if [ -n "$world_readable" ]; then
log "WARNING: These files are still world-readable:"
echo "$world_readable" | while read -r f; do
log " $f"
done
else
log "OK: No world-readable files found in top 3 levels (excluding node_modules)"
fi
log ""
log "Checking for any remaining world-executable directories..."
world_exec=$(find "$CLAWDBOT_DIR" -maxdepth 3 -type d -perm -005 2>/dev/null | grep -v node_modules | head -20)
if [ -n "$world_exec" ]; then
log "WARNING: These directories are still world-accessible:"
echo "$world_exec" | while read -r d; do
log " $d"
done
else
log "OK: No world-accessible directories found in top 3 levels (excluding node_modules)"
fi
echo ""
echo "========================================"
echo "SUMMARY"
echo "========================================"
log ""
log "Permission hardening complete!"
log "Log file: $LOG_FILE"
log ""
log "Post-hardening checklist:"
log " 1. Verify clawdbot still functions correctly"
log " 2. Consider replacing symlinks with actual files"
log " 3. Review any .env or credentials files in workspace/"
log " 4. Ensure backups are stored securely"
log ""
log "Run 'cat $LOG_FILE' to see all changes made."
echo ""
echo "Done!"