diff --git a/skills/claw-release/SKILL.md b/skills/claw-release/SKILL.md index 0045681..8b3aed3 100644 --- a/skills/claw-release/SKILL.md +++ b/skills/claw-release/SKILL.md @@ -1,7 +1,7 @@ --- name: claw-release version: 0.0.1 -description: Release automation for Claw skills and website. Guides through version bumping, tagging, and release verification. +description: Release automation for Claw skills and website. Guides through version bumping, tagging, and release verification. Use when releasing a skill, publishing a new version, deploying to production, cutting a release, shipping a build, or creating a changelog. homepage: https://clawsec.prompt.security metadata: {"openclaw":{"emoji":"🚀","category":"utility","internal":true}} clawdis: diff --git a/skills/clawsec-clawhub-checker/SKILL.md b/skills/clawsec-clawhub-checker/SKILL.md index a208eb1..1a81390 100644 --- a/skills/clawsec-clawhub-checker/SKILL.md +++ b/skills/clawsec-clawhub-checker/SKILL.md @@ -1,7 +1,7 @@ --- name: clawsec-clawhub-checker version: 0.0.1 -description: ClawHub reputation checker for ClawSec suite. Enhances guarded skill installer with VirusTotal Code Insight reputation scores and additional safety checks. +description: ClawHub reputation checker for ClawSec suite. Queries VirusTotal Code Insight scores and additional safety signals before allowing skill installation. Use when installing skills, checking skill safety, verifying reputation scores, running a security scan, or when asked whether a skill is trustworthy or safe. homepage: https://clawsec.prompt.security clawdis: emoji: "🛡️" @@ -14,13 +14,7 @@ clawdis: Enhances the ClawSec suite's guarded skill installer with ClawHub reputation checks. Adds a second layer of security by checking VirusTotal Code Insight scores and other reputation signals before allowing skill installation. -## What It Does - -1. **Wraps `clawhub install`** - Intercepts skill installation requests -2. **Checks VirusTotal reputation** - Uses ClawHub's built-in VirusTotal Code Insight -3. **Adds double confirmation** - For suspicious skills (reputation score below threshold) -4. **Integrates with advisory feed** - Works alongside existing clawsec-suite advisories -5. **Provides detailed reports** - Shows why a skill is flagged as suspicious +Wraps `clawhub install` to intercept skill installation requests, check VirusTotal reputation and advisory feeds, and require double confirmation for suspicious skills before proceeding. ## Installation @@ -117,25 +111,8 @@ node scripts/guarded_skill_install_wrapper.mjs --skill suspicious-skill --versio ## Current Limitations -### Missing OpenClaw Internal Check Data -ClawHub shows two security badges on skill pages: -1. **VirusTotal Code Insight** - ✅ Our checker catches these flags -2. **OpenClaw internal check** - ❌ Not exposed via API (only on website) - -Example from `clawsec-suite` page: -- VirusTotal: "Benign" ✓ -- OpenClaw internal check: "The package is internally consistent with a feed-monitoring / advisory-guardian purpose, but a few operational details and optional bypasses deserve attention before installing." - -**Our checker cannot access OpenClaw internal check warnings** as they're not exposed via `clawhub` CLI or API. - -### Recommendation for ClawHub -To enable complete reputation checking, ClawHub should expose internal check results via: -- `clawhub inspect --json` endpoint -- Additional API field for security tools -- Or include in `clawhub install` warning output - -### Workaround -Our heuristic checks (skill age, author reputation, downloads, updates) provide similar risk assessment but miss specific operational warnings about bypasses, missing signatures, etc. Always check the ClawHub website for complete security assessment. +- **OpenClaw internal check data** is not exposed via `clawhub` CLI or API, so this checker cannot access those warnings. Only VirusTotal Code Insight flags are caught. +- Heuristic checks (skill age, author reputation, downloads) provide similar risk assessment but miss specific operational warnings. Always check the ClawHub website for complete security assessment. ## Development diff --git a/skills/clawsec-feed/SKILL.md b/skills/clawsec-feed/SKILL.md index 421f773..3e12dba 100644 --- a/skills/clawsec-feed/SKILL.md +++ b/skills/clawsec-feed/SKILL.md @@ -1,7 +1,7 @@ --- name: clawsec-feed version: 0.0.5 -description: Security advisory feed with automated NVD CVE polling for OpenClaw-related vulnerabilities. Updated daily. +description: Security advisory feed with automated NVD CVE polling for OpenClaw-related vulnerabilities. Use when checking for security advisories, looking up CVEs, monitoring vulnerability feeds, or verifying whether installed skills have known security issues. homepage: https://clawsec.prompt.security metadata: {"openclaw":{"emoji":"📡","category":"security"}} clawdis: @@ -20,41 +20,12 @@ This feed is automatically updated daily with CVEs related to OpenClaw, clawdbot --- -## Installation Options +## Installation -You can get clawsec-feed in two ways: +**Bundled with ClawSec Suite:** If you installed clawsec-suite, clawsec-feed is already included at `~/.openclaw/skills/clawsec-feed/`. -### Option A: Bundled with ClawSec Suite (Recommended) +**Standalone installation:** Follow the steps below if you only need the advisory feed. -**If you've installed clawsec-suite, you may already have this!** - -ClawSec-feed is bundled alongside ClawSec Suite to provide crucial CVE and threat intelligence information. When you install the suite, if you don't already have the feed installed, it will be deployed from the bundled copy. - -**Advantages:** -- Convenient - no separate download needed -- Standard location - installed to `~/.openclaw/skills/clawsec-feed/` -- Preserved - if you already have feed installed, it won't be overwritten -- Single verification - integrity checked as part of suite package - -### Option B: Standalone Installation (This Page) - -Install clawsec-feed independently without the full suite. - -**When to use standalone:** -- You only need the advisory feed (not other suite components) -- You want to install before installing the suite -- You prefer explicit control over feed installation - -**Advantages:** -- Lighter weight installation -- Independent from suite -- Direct control over installation process - -Continue below for standalone installation instructions. - ---- - -Installation Steps: Agents should review scripts before execution! @@ -277,21 +248,6 @@ ClawSec Feed deployed successfully. I will now: --- -## What ClawSec Feed Does - -### Advisory Feed Monitoring - -Subscribes to the community advisory feed for: - -- **Known malicious skills/plugins** - Skills that have been identified as harmful -- **Prompt injection patterns** - Attack patterns observed in the wild -- **Vulnerable skill versions** - Skills with known security flaws -- **Security best practice updates** - New recommendations for agent safety - -When a relevant advisory is published, your agent will notify you. - ---- - ## Checking the Advisory Feed ```bash @@ -330,61 +286,18 @@ curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" ## Parsing the Feed -### Get advisory count +All examples below assume `$FEED` contains the fetched JSON (see "Checking the Advisory Feed" above). ```bash -# Use environment variable if set, otherwise use raw GitHub feed (always up-to-date) -DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json" -FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}" - -TEMP_FEED=$(mktemp) -trap "rm -f '$TEMP_FEED'" EXIT - -if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then - echo "Error: Failed to fetch advisory feed" - exit 1 -fi - -# Validate JSON before parsing -if ! jq empty "$TEMP_FEED" 2>/dev/null; then - echo "Error: Invalid JSON in feed" - exit 1 -fi - -FEED=$(cat "$TEMP_FEED") - -# Get advisory count with error handling -COUNT=$(echo "$FEED" | jq '.advisories | length') -if [ $? -ne 0 ]; then - echo "Error: Failed to parse advisories" - exit 1 -fi -echo "Advisory count: $COUNT" -``` +# Advisory count +echo "$FEED" | jq '.advisories | length' -### Get critical advisories +# Critical advisories only +echo "$FEED" | jq '.advisories[] | select(.severity == "critical")' -```bash -# Parse critical advisories with jq error handling -CRITICAL=$(echo "$FEED" | jq '.advisories[] | select(.severity == "critical")') -if [ $? -ne 0 ]; then - echo "Error: Failed to filter critical advisories" - exit 1 -fi -echo "$CRITICAL" -``` - -### Get advisories from the last 7 days - -```bash -# Use UTC timezone for consistent date handling +# Advisories from the last 7 days WEEK_AGO=$(TZ=UTC date -v-7d +%Y-%m-%dT00:00:00Z 2>/dev/null || TZ=UTC date -d '7 days ago' +%Y-%m-%dT00:00:00Z) -RECENT=$(echo "$FEED" | jq --arg since "$WEEK_AGO" '.advisories[] | select(.published > $since)') -if [ $? -ne 0 ]; then - echo "Error: Failed to filter recent advisories" - exit 1 -fi -echo "$RECENT" +echo "$FEED" | jq --arg since "$WEEK_AGO" '.advisories[] | select(.published > $since)' ``` ### Filter by exploitability score @@ -429,65 +342,24 @@ echo "$FEED" | jq '[.advisories[] | select(.exploitability_score != null)] | Check if any of your installed skills are affected by advisories: +Assumes `$FEED` is already fetched (see "Checking the Advisory Feed"). + ```bash -# List your installed skills (adjust path for your platform) INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills}" - -# Use environment variable if set, otherwise use raw GitHub feed (always up-to-date) -DEFAULT_FEED_URL="https://raw.githubusercontent.com/prompt-security/ClawSec/main/advisories/feed.json" -FEED_URL="${CLAWSEC_FEED_URL:-$DEFAULT_FEED_URL}" - -TEMP_FEED=$(mktemp) -trap "rm -f '$TEMP_FEED'" EXIT - -if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$FEED_URL" -o "$TEMP_FEED"; then - echo "Error: Failed to fetch advisory feed" - exit 1 -fi - -# Validate and parse feed -if ! jq empty "$TEMP_FEED" 2>/dev/null; then - echo "Error: Invalid JSON in feed" - exit 1 -fi - -FEED=$(cat "$TEMP_FEED") AFFECTED=$(echo "$FEED" | jq -r '.advisories[].affected[]?' 2>/dev/null | sort -u) -if [ $? -ne 0 ]; then - echo "Error: Failed to parse affected skills from feed" - exit 1 -fi -# Safely validate all installed skills before processing -# This prevents shell injection via malicious filenames -VALIDATED_SKILLS=() +# Validate skill names to prevent shell injection while IFS= read -r -d '' skill_path; do skill=$(basename "$skill_path") - - # Validate skill name BEFORE adding to array (prevents injection) - if [[ "$skill" =~ ^[a-zA-Z0-9_-]+$ ]]; then - VALIDATED_SKILLS+=("$skill") - else - echo "Warning: Skipping invalid skill name: $skill" >&2 - fi -done < <(find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null) - -# Check each validated skill against affected list -# Use grep -qF for fixed string matching (prevents regex injection) -for skill in "${VALIDATED_SKILLS[@]}"; do - # At this point, $skill is guaranteed to match ^[a-zA-Z0-9_-]+$ + [[ "$skill" =~ ^[a-zA-Z0-9_-]+$ ]] || continue if echo "$AFFECTED" | grep -qF "$skill"; then echo "WARNING: Installed skill '$skill' has a security advisory!" - # Get advisory details for this skill echo "$FEED" | jq --arg s "$skill" '.advisories[] | select(.affected[] | contains($s))' fi -done +done < <(find "$INSTALL_DIR" -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null) ``` -**If you find affected skills:** -1. Check the advisory for details and severity -2. Notify your user immediately for critical/high severity -3. Include the recommended action from the advisory +If affected skills are found, notify the user immediately for critical/high severity and include the recommended action. --- @@ -503,110 +375,44 @@ done --- -## Severity Levels +## Severity and Exploitability -| Severity | Action Required | -|----------|-----------------| -| `critical` | Notify user immediately, take action | -| `high` | Notify user soon, plan remediation | -| `medium` | Notify at next interaction | -| `low` | Log for reference | - ---- +| Severity | Action | | Exploitability | Meaning | +|----------|--------|-|----------------|---------| +| `critical` | Notify immediately, take action | | `high` | Trivially exploitable with public tooling | +| `high` | Notify soon, plan remediation | | `medium` | Requires specific conditions | +| `medium` | Notify at next interaction | | `low` | Difficult to exploit or theoretical | +| `low` | Log for reference | | | | -## Prioritizing High-Exploitability Threats +Always prioritize by **both** severity and exploitability. A HIGH severity + HIGH exploitability CVE is more urgent than CRITICAL + LOW exploitability. -**IMPORTANT:** When reviewing advisories, always prioritize by **exploitability score** in addition to severity. The exploitability score indicates how easily a vulnerability can be exploited in practice, helping you focus on the most actionable threats. - -### Exploitability Priority Levels - -| Exploitability | Meaning | Action Priority | -|----------------|---------|-----------------| -| `high` | Trivially or easily exploitable with public tooling | **Immediate notification** | -| `medium` | Exploitable but requires specific conditions | **Standard notification** | -| `low` | Difficult to exploit or theoretical | **Low priority notification** | - -### How to Use Exploitability in Notifications - -1. **Filter for high-exploitability first:** - ```bash - # Get high exploitability advisories - echo "$FEED" | jq '.advisories[] | select(.exploitability_score == "high")' - ``` - -2. **Include exploitability in notifications:** - ``` - 📡 ClawSec Feed: High-exploitability alert - - CRITICAL - CVE-2026-27488 (Exploitability: HIGH) - → Trivially exploitable RCE in skill-loader v2.1.0 - → Public exploit code available - → Recommended action: Immediate removal or upgrade to v2.1.1 - ``` - -3. **Prioritize by both severity AND exploitability:** - - A HIGH severity + HIGH exploitability CVE is more urgent than a CRITICAL severity + LOW exploitability CVE - - Focus user attention on threats that are both severe and easily exploitable - - Include the exploitability rationale to help users understand the risk context - -### Example Notification Priority Order - -When multiple advisories exist, present them in this order: -1. **Critical severity + High exploitability** - most urgent -2. **High severity + High exploitability** -3. **Critical severity + Medium/Low exploitability** -4. **High severity + Medium/Low exploitability** -5. **Medium/Low severity** (any exploitability) - -This ensures you alert users to the most actionable, immediately dangerous threats first. - ---- - -## When to Notify Your User - -**Notify Immediately (Critical):** -- New critical advisory affecting an installed skill -- Active exploitation detected -- **High exploitability score** (regardless of severity) - -**Notify Soon (High):** -- New high-severity advisory affecting installed skills -- Failed to fetch advisory feed (network issue?) -- Medium exploitability with high severity - -**Notify at Next Interaction (Medium):** -- New medium-severity advisories -- General security updates -- Low exploitability advisories - -**Log Only (Low/Info):** -- Low-severity advisories (mention if user asks) -- Feed checked, no new advisories -- Theoretical vulnerabilities (low exploitability, low severity) +```bash +# Sort advisories by exploitability (critical → high → medium → low) +echo "$FEED" | jq '[.advisories[] | select(.exploitability_score != null)] | + sort_by( + if .exploitability_score == "critical" then 0 + elif .exploitability_score == "high" then 1 + elif .exploitability_score == "medium" then 2 + elif .exploitability_score == "low" then 3 + else 4 end + )' +``` --- ## Response Format -### If there are new advisories: - ``` 📡 ClawSec Feed: 2 new advisories since last check CRITICAL - GA-2026-015: Malicious prompt pattern "ignore-all" (Exploitability: HIGH) - → Detected prompt injection technique. Update your system prompt defenses. - → Exploitability: Easily exploitable with publicly documented techniques. + → Action: Update your system prompt defenses. HIGH - GA-2026-016: Vulnerable skill "data-helper" v1.2.0 (Exploitability: MEDIUM) - → You have this installed! Recommended action: Update to v1.2.1 or remove. - → Exploitability: Requires specific configuration; not trivially exploitable. + → Action: Update to v1.2.1 or remove. ``` -### If nothing new: - -``` -FEED_OK - Advisory feed checked, no new alerts. 📡 -``` +If nothing new: `FEED_OK - Advisory feed checked, no new alerts. 📡` --- @@ -629,43 +435,25 @@ Save to: `~/.openclaw/clawsec-feed-state.json` ```bash STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json" +DEFAULT_STATE='{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' -# Create state file with secure permissions if it doesn't exist -if [ ! -f "$STATE_FILE" ]; then - echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE" +# Initialize if missing or corrupted +if [ ! -f "$STATE_FILE" ] || ! jq -e '.schema_version' "$STATE_FILE" >/dev/null 2>&1; then + [ -f "$STATE_FILE" ] && cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)" + echo "$DEFAULT_STATE" > "$STATE_FILE" chmod 600 "$STATE_FILE" fi -# Validate state file before reading -if ! jq -e '.schema_version' "$STATE_FILE" >/dev/null 2>&1; then - echo "Warning: State file corrupted or invalid schema. Creating backup and resetting." - cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)" - echo '{"schema_version":"1.0","last_feed_check":null,"last_feed_updated":null,"known_advisories":[]}' > "$STATE_FILE" - chmod 600 "$STATE_FILE" -fi - -# Check for major version compatibility -SCHEMA_VER=$(jq -r '.schema_version // "0"' "$STATE_FILE") -if [[ "${SCHEMA_VER%%.*}" != "1" ]]; then - echo "Warning: State file schema version $SCHEMA_VER may not be compatible with this version" -fi - # Update last check time (always use UTC) -TEMP_STATE=$(mktemp) -if jq --arg t "$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)" '.last_feed_check = $t' "$STATE_FILE" > "$TEMP_STATE"; then - mv "$TEMP_STATE" "$STATE_FILE" - chmod 600 "$STATE_FILE" -else - echo "Error: Failed to update state file" - rm -f "$TEMP_STATE" -fi +jq --arg t "$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)" '.last_feed_check = $t' "$STATE_FILE" | \ + sponge "$STATE_FILE" || echo "Error: Failed to update state file" ``` --- ## Rate Limiting -**Important:** To avoid excessive requests to the feed server, follow these guidelines: +To avoid excessive requests to the feed server, respect these minimum intervals: | Check Type | Recommended Interval | Minimum Interval | |------------|---------------------|------------------| @@ -673,20 +461,7 @@ fi | Full feed refresh | Every 1-4 hours | 30 minutes | | Cross-reference scan | Once per session | 5 minutes | -```bash -# Check if enough time has passed since last check -STATE_FILE="$HOME/.openclaw/clawsec-feed-state.json" -MIN_INTERVAL_SECONDS=300 # 5 minutes - -LAST_CHECK=$(jq -r '.last_feed_check // "1970-01-01T00:00:00Z"' "$STATE_FILE" 2>/dev/null) -LAST_EPOCH=$(TZ=UTC date -j -f "%Y-%m-%dT%H:%M:%SZ" "$LAST_CHECK" +%s 2>/dev/null || date -d "$LAST_CHECK" +%s 2>/dev/null || echo 0) -NOW_EPOCH=$(TZ=UTC date +%s) - -if [ $((NOW_EPOCH - LAST_EPOCH)) -lt $MIN_INTERVAL_SECONDS ]; then - echo "Rate limit: Last check was less than 5 minutes ago. Skipping." - exit 0 -fi -``` +Compare `last_feed_check` from the state file against the current time before fetching. --- @@ -701,57 +476,16 @@ fi ## Updating ClawSec Feed -Check for and install newer versions: - ```bash -# Check current installed version INSTALL_DIR="${CLAWSEC_INSTALL_DIR:-$HOME/.openclaw/skills/clawsec-feed}" -CURRENT_VERSION=$(jq -r '.version' "$INSTALL_DIR/skill.json" 2>/dev/null || echo "unknown") -echo "Installed version: $CURRENT_VERSION" - -# Check latest available version -LATEST_URL="https://api.github.com/repos/prompt-security/ClawSec/releases" -LATEST_VERSION=$(curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$LATEST_URL" 2>/dev/null | \ +CURRENT=$(jq -r '.version' "$INSTALL_DIR/skill.json" 2>/dev/null || echo "unknown") +LATEST=$(curl -sSL https://api.github.com/repos/prompt-security/ClawSec/releases | \ jq -r '[.[] | select(.tag_name | startswith("clawsec-feed-v"))][0].tag_name // empty' | \ sed 's/clawsec-feed-v//') - -if [ -z "$LATEST_VERSION" ]; then - echo "Warning: Could not determine latest version" -else - echo "Latest version: $LATEST_VERSION" - - if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then - echo "Update available! Run the deployment steps with the new version." - else - echo "You are running the latest version." - fi -fi -``` - ---- - -## Initial Download Integrity - -**Bootstrap Trust Problem:** The initial download of this skill cannot be verified by the skill itself. To establish trust: - -1. **Verify the source URL** - Ensure you are downloading from `https://clawsec.prompt.security` -2. **Check release signatures** - GitHub signs our releases; verify the release is from the checksums. -3. **Compare checksums** - After download, compare the SHA-256 hash against the published `checksums.json`: - -```bash -# After downloading SKILL.md, verify its integrity -EXPECTED_HASH="" -ACTUAL_HASH=$(shasum -a 256 SKILL.md | cut -d' ' -f1) - -if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then - echo "ERROR: Skill file integrity check failed!" - echo "This file may have been tampered with. Do not proceed." - exit 1 -fi +echo "Installed: $CURRENT | Latest: $LATEST" +[ "$CURRENT" != "$LATEST" ] && echo "Update available! Re-run deployment steps." ``` -**Note:** For maximum security, verify checksums.json via a separate trusted channel (e.g., direct from GitHub release page UI, not via curl). - --- ## Related Skills diff --git a/skills/clawsec-nanoclaw/SKILL.md b/skills/clawsec-nanoclaw/SKILL.md index a0cd185..d61066c 100644 --- a/skills/clawsec-nanoclaw/SKILL.md +++ b/skills/clawsec-nanoclaw/SKILL.md @@ -1,7 +1,7 @@ --- name: clawsec-nanoclaw version: 0.0.3 -description: Use when checking for security vulnerabilities in NanoClaw skills, before installing new skills, or when asked about security advisories affecting the bot +description: Scans NanoClaw skills for known vulnerabilities, validates safety before installation, and checks security advisories affecting the bot. Use when checking for security vulnerabilities in NanoClaw skills, before installing new skills, or when asked about security advisories. --- # ClawSec for NanoClaw @@ -148,16 +148,14 @@ const safety = await tools.clawsec_check_skill_safety({ if (safety.safe) await installSkill('untrusted-skill'); ``` -### ❌ Ignoring exploitability context +### ❌ Using severity alone without exploitability ```typescript -// DON'T: Use severity only -if (advisory.severity === 'high') { - notifyNow(advisory); -} +// DON'T: Use only severity or only exploitability +if (advisory.severity === 'critical') alert(); ``` ```typescript -// DO: Use exploitability + severity +// DO: Prioritize exploitability and severity together if ( advisory.exploitability_score === 'high' || advisory.severity === 'critical' @@ -166,19 +164,6 @@ if ( } ``` -### ❌ Skipping critical severity -```typescript -// DON'T: Ignore high exploitability in medium severity advisories -if (advisory.severity === 'critical') alert(); -``` - -```typescript -// DO: Prioritize exploitability and severity together -if (advisory.exploitability_score === 'high' || advisory.severity === 'critical') { - // Alert immediately -} -``` - ## Implementation Details **Feed Source**: https://clawsec.prompt.security/advisories/feed.json @@ -191,10 +176,3 @@ if (advisory.exploitability_score === 'high' || advisory.severity === 'critical' **Cache Location**: `/workspace/project/data/clawsec-advisory-cache.json` See [INSTALL.md](./INSTALL.md) for setup and [docs/](./docs/) for advanced usage. - -## Real-World Impact - -- Prevents installation of skills with known RCE vulnerabilities -- Alerts to supply chain attacks in dependencies -- Provides actionable remediation steps -- Zero false positives (curated feed only) diff --git a/skills/clawsec-scanner/SKILL.md b/skills/clawsec-scanner/SKILL.md index afc49d5..8920b19 100644 --- a/skills/clawsec-scanner/SKILL.md +++ b/skills/clawsec-scanner/SKILL.md @@ -1,7 +1,7 @@ --- name: clawsec-scanner version: 0.0.2 -description: Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and agent-specific DAST hook execution testing for OpenClaw hooks. +description: Automated vulnerability scanner for agent platforms. Performs dependency scanning (npm audit, pip-audit), multi-database CVE lookup (OSV, NVD, GitHub Advisory), SAST analysis (Semgrep, Bandit), and agent-specific DAST hook execution testing. Use when running security scans, checking for vulnerabilities, auditing dependencies, or finding security issues in agent platforms. homepage: https://clawsec.prompt.security clawdis: emoji: "🔍" @@ -20,34 +20,7 @@ Comprehensive security scanner for agent platforms that automates vulnerability - **Unified Reporting**: Consolidated vulnerability reports with severity classification and remediation guidance - **Continuous Monitoring**: OpenClaw hook integration for automated periodic scanning -## Features - -### Multi-Engine Scanning - -The scanner orchestrates four complementary scan types to provide comprehensive vulnerability coverage: - -1. **Dependency Scanning** - - Executes `npm audit --json` and `pip-audit -f json` as subprocesses - - Parses structured output to extract CVE IDs, severity, affected versions - - Handles edge cases: missing package-lock.json, zero vulnerabilities, malformed JSON - -2. **CVE Database Queries** - - **OSV API** (primary): Free, no authentication, broad ecosystem support (npm, PyPI, Go, Maven) - - **NVD 2.0** (optional): Requires API key to avoid 6-second rate limiting - - **GitHub Advisory Database** (optional): GraphQL API with OAuth token - - Normalizes all API responses to unified `Vulnerability` schema - -3. **Static Analysis (SAST)** - - **Semgrep** for JavaScript/TypeScript: Detects security issues using `--config auto` or `--config p/security-audit` - - **Bandit** for Python: Leverages existing `pyproject.toml` configuration - - Identifies: hardcoded secrets (API keys, tokens), command injection (`eval`, `exec`), path traversal, unsafe deserialization - -4. **Dynamic Analysis (DAST)** - - Real hook execution harness for OpenClaw hook handlers discovered from `HOOK.md` metadata - - Verifies: malicious input resilience, timeout behavior, output amplification bounds, and core event mutation safety - - Note: Traditional web DAST tools (ZAP, Burp) do not apply to agent platforms - this provides agent-specific testing - -### Unified Reporting +## Unified Reporting All scan types emit a consistent `ScanReport` JSON schema: @@ -67,18 +40,6 @@ All scan types emit a consistent `ScanReport` JSON schema: } ``` -Each `Vulnerability` object includes: -- `id`: CVE-2023-12345 or GHSA-xxxx-yyyy-zzzz -- `source`: npm-audit | pip-audit | osv | nvd | github | sast | dast -- `severity`: critical | high | medium | low | info -- `package`: Package name (or 'N/A' for SAST/DAST) -- `version`: Affected version -- `fixed_version`: First version with fix (if available) -- `title`: Short description -- `description`: Full advisory text -- `references`: URLs for more info -- `discovered_at`: ISO 8601 timestamp - ### OpenClaw Integration Automated continuous monitoring via hook: @@ -263,155 +224,16 @@ hooks/clawsec-scanner-hook/ ### Fail-Open Philosophy -The scanner prioritizes availability over strict failure propagation: - -- Network failures → emit partial results, log warnings -- Missing tools → skip that scan type, continue with others -- Malformed JSON → parse what's valid, log errors -- API rate limits → implement exponential backoff, fallback to other sources -- Zero vulnerabilities → emit success report with empty array - -**Critical failures** that exit immediately: -- Target path does not exist -- No scanning tools available (all bins missing) -- Concurrent scan detected (lockfile present) - -### Subprocess Execution Pattern - -All external tools run as subprocesses with structured JSON output: - -```javascript -import { spawn } from 'node:child_process'; - -// Example: npm audit execution -const proc = spawn('npm', ['audit', '--json'], { - cwd: targetPath, - stdio: ['ignore', 'pipe', 'pipe'] -}); - -// Handle non-zero exit codes gracefully -// npm audit exits 1 when vulnerabilities found (not an error!) -proc.on('close', code => { - if (code !== 0 && stderr.includes('ERR!')) { - // Actual error - reject(new Error(stderr)); - } else { - // Vulnerabilities found or success - resolve(JSON.parse(stdout)); - } -}); -``` +The scanner follows a fail-open philosophy: network failures, missing tools, or malformed JSON produce partial results with warnings rather than hard failures. Critical failures (target path missing, no scanning tools available, concurrent scan detected) exit immediately. ## Troubleshooting -### Common Issues - -**"Missing package-lock.json" warning** -- `npm audit` requires lockfile to run -- Run `npm install` in target directory to generate -- Scanner continues with other scan types if npm audit fails - -**"NVD API rate limit exceeded"** -- Set `CLAWSEC_NVD_API_KEY` environment variable -- Without API key: 6-second delays enforced between requests -- OSV API used as primary source (no rate limits) - -**"pip-audit not found"** -- Install: `uv pip install pip-audit` or `pip install pip-audit` -- Verify: `which pip-audit` -- Add to PATH if installed in non-standard location - -**"Semgrep binary missing"** -- Install: `pip install semgrep` OR `brew install semgrep` -- Requires Python 3.8+ runtime -- Alternative: use Docker image `returntocorp/semgrep` - -**"TypeScript hook not executable in DAST harness"** -- The DAST harness executes real hook handlers and transpiles `handler.ts` files when a TypeScript compiler is available -- Install TypeScript in the scanner environment: `npm install -D typescript` (or provide `handler.js`/`handler.mjs`) -- Without a compiler, scanner reports an `info`-level coverage finding instead of a high-severity vulnerability - -**"Concurrent scan detected"** -- Lockfile exists: `/tmp/clawsec-scanner.lock` -- Wait for running scan to complete or manually remove lockfile -- Prevents overlapping scans that could produce inconsistent results - -### Verification - -Check scanner is working correctly: - -```bash -# Verify required binaries -./scripts/runner.sh --check - -# Run unit tests -node test/dependency_scanner.test.mjs -node test/cve_integration.test.mjs -node test/sast_engine.test.mjs -node test/dast_harness.test.mjs - -# Validate skill structure -python ../../utils/validate_skill.py . - -# Scan test fixtures (should detect known vulnerabilities) -./scripts/runner.sh --target test/fixtures/ --format text -``` - -## Development - -### Running Tests - -```bash -# All tests (vanilla Node.js, no framework) -for test in test/*.test.mjs; do - node "$test" || exit 1 -done - -# Individual test suites -node test/dependency_scanner.test.mjs # Dependency scanning -node test/cve_integration.test.mjs # CVE database APIs -node test/sast_engine.test.mjs # Static analysis -node test/dast_harness.test.mjs # DAST harness execution -``` - -### Linting - -```bash -# JavaScript/TypeScript -npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0 - -# Python (Bandit already configured in pyproject.toml) -ruff check . -bandit -r . -ll - -# Shell scripts -shellcheck scripts/*.sh -``` - -### Adding Custom Semgrep Rules - -Create custom rules in `.semgrep/rules/`: - -```yaml -rules: - - id: custom-security-rule - pattern: dangerous_function($ARG) - message: Avoid dangerous_function - use safe_alternative instead - severity: WARNING - languages: [javascript, typescript] -``` - -Update `scripts/sast_analyzer.mjs` to include custom rules: - -```javascript -const proc = spawn('semgrep', [ - 'scan', - '--config', 'auto', - '--config', '.semgrep/rules/', // Add custom rules - '--json', - targetPath -]); -``` +- **"Missing package-lock.json"**: Run `npm install` in target directory to generate lockfile. Scanner continues with other scan types. +- **"NVD API rate limit exceeded"**: Set `CLAWSEC_NVD_API_KEY` environment variable. OSV API is used as primary source with no rate limits. +- **"pip-audit not found"**: Install via `uv pip install pip-audit` or `pip install pip-audit`. +- **"Semgrep binary missing"**: Install via `pip install semgrep` or `brew install semgrep`. +- **"TypeScript hook not executable in DAST harness"**: Install TypeScript (`npm install -D typescript`) or provide `handler.js`/`handler.mjs`. +- **"Concurrent scan detected"**: Wait for running scan or remove `/tmp/clawsec-scanner.lock`. ## Integration with ClawSec Suite @@ -454,44 +276,6 @@ npx clawhub@latest install clawsec-suite - Deprecated API usage - Code quality issues flagged by linters -## Roadmap - -### v0.0.2 (Current) -- [x] Dependency scanning (npm audit, pip-audit) -- [x] CVE database integration (OSV, NVD, GitHub Advisory) -- [x] SAST analysis (Semgrep, Bandit) -- [x] Real OpenClaw hook execution harness for DAST -- [x] Unified JSON reporting -- [x] OpenClaw hook integration - -### Future Enhancements -- [ ] Automatic remediation (dependency upgrades, code fixes) -- [ ] SARIF output format for GitHub Code Scanning integration -- [ ] Web dashboard for vulnerability tracking over time -- [ ] CI/CD GitHub Action for PR blocking on high-severity findings -- [ ] Container image scanning (Docker, OCI) -- [ ] Infrastructure-as-Code scanning (Terraform, CloudFormation) -- [ ] Comprehensive agent workflow DAST (requires deeper platform integration) - -## Contributing - -Found a security issue? Please report privately to security@prompt.security. - -For feature requests and bug reports, open an issue at: -https://github.com/prompt-security/clawsec/issues - ## License AGPL-3.0-or-later - -See LICENSE file in repository root for full text. - -## Resources - -- **ClawSec Homepage**: https://clawsec.prompt.security -- **Documentation**: https://clawsec.prompt.security/scanner -- **GitHub Repository**: https://github.com/prompt-security/clawsec -- **OSV API Docs**: https://osv.dev/docs/ -- **NVD API Docs**: https://nvd.nist.gov/developers/vulnerabilities -- **Semgrep Registry**: https://semgrep.dev/explore -- **Bandit Documentation**: https://bandit.readthedocs.io/ diff --git a/skills/clawsec-suite/SKILL.md b/skills/clawsec-suite/SKILL.md index 30d789e..7927004 100644 --- a/skills/clawsec-suite/SKILL.md +++ b/skills/clawsec-suite/SKILL.md @@ -1,7 +1,7 @@ --- name: clawsec-suite version: 0.1.4 -description: ClawSec suite manager with embedded advisory-feed monitoring, cryptographic signature verification, approval-gated malicious-skill response, and guided setup for additional security skills. +description: ClawSec suite manager with embedded advisory-feed monitoring and guided setup for security skills. Use when setting up agent security, checking advisory feeds, installing security skills, verifying skill signatures, or managing the ClawSec security suite. homepage: https://clawsec.prompt.security clawdis: emoji: "📦" @@ -11,12 +11,7 @@ clawdis: # ClawSec Suite -This means `clawsec-suite` can: -- monitor the ClawSec advisory feed, -- track which advisories are new since last check, -- cross-reference advisories against locally installed skills, -- recommend removal for malicious-skill advisories and require explicit user approval first, -- and still act as the setup/management entrypoint for other ClawSec protections. +ClawSec Suite is the central management entrypoint for ClawSec security protections. It monitors the ClawSec advisory feed, tracks new advisories, cross-references them against locally installed skills, recommends removal for malicious-skill advisories (with explicit user approval), and provides guided setup for additional security skills. ## Included vs Optional Protections @@ -61,81 +56,14 @@ npx clawhub@latest install clawsec-suite ### Option B: Manual download with signature + checksum verification -```bash -set -euo pipefail - -VERSION="${SKILL_VERSION:?Set SKILL_VERSION (e.g. 0.0.8)}" -INSTALL_ROOT="${INSTALL_ROOT:-$HOME/.openclaw/skills}" -DEST="$INSTALL_ROOT/clawsec-suite" -BASE="https://github.com/prompt-security/clawsec/releases/download/clawsec-suite-v${VERSION}" - -TEMP_DIR="$(mktemp -d)" -trap 'rm -rf "$TEMP_DIR"' EXIT - -# Pinned release-signing public key (verify fingerprint out-of-band on first use) -# Fingerprint (SHA-256 of SPKI DER): 711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8 -RELEASE_PUBKEY_SHA256="711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8" -cat > "$TEMP_DIR/release-signing-public.pem" <<'PEM' ------BEGIN PUBLIC KEY----- -MCowBQYDK2VwAyEAS7nijfMcUoOBCj4yOXJX+GYGv2pFl2Yaha1P4v5Cm6A= ------END PUBLIC KEY----- -PEM - -ACTUAL_KEY_SHA256="$(openssl pkey -pubin -in "$TEMP_DIR/release-signing-public.pem" -outform DER | shasum -a 256 | awk '{print $1}')" -if [ "$ACTUAL_KEY_SHA256" != "$RELEASE_PUBKEY_SHA256" ]; then - echo "ERROR: Release public key fingerprint mismatch" >&2 - exit 1 -fi - -ZIP_NAME="clawsec-suite-v${VERSION}.zip" - -# 1) Download release archive + signed checksums manifest + signing public key -curl -fsSL "$BASE/$ZIP_NAME" -o "$TEMP_DIR/$ZIP_NAME" -curl -fsSL "$BASE/checksums.json" -o "$TEMP_DIR/checksums.json" -curl -fsSL "$BASE/checksums.sig" -o "$TEMP_DIR/checksums.sig" - -# 2) Verify checksums manifest signature before trusting any hashes -openssl base64 -d -A -in "$TEMP_DIR/checksums.sig" -out "$TEMP_DIR/checksums.sig.bin" -if ! openssl pkeyutl -verify \ - -pubin \ - -inkey "$TEMP_DIR/release-signing-public.pem" \ - -sigfile "$TEMP_DIR/checksums.sig.bin" \ - -rawin \ - -in "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then - echo "ERROR: checksums.json signature verification failed" >&2 - exit 1 -fi - -EXPECTED_ZIP_SHA="$(jq -r '.archive.sha256 // empty' "$TEMP_DIR/checksums.json")" -if [ -z "$EXPECTED_ZIP_SHA" ]; then - echo "ERROR: checksums.json missing archive.sha256" >&2 - exit 1 -fi +For manual installation, download the release archive from GitHub Releases and verify integrity before installing: -if command -v shasum >/dev/null 2>&1; then - ACTUAL_ZIP_SHA="$(shasum -a 256 "$TEMP_DIR/$ZIP_NAME" | awk '{print $1}')" -else - ACTUAL_ZIP_SHA="$(sha256sum "$TEMP_DIR/$ZIP_NAME" | awk '{print $1}')" -fi - -if [ "$EXPECTED_ZIP_SHA" != "$ACTUAL_ZIP_SHA" ]; then - echo "ERROR: Archive checksum mismatch for $ZIP_NAME" >&2 - exit 1 -fi +1. Set `SKILL_VERSION` and download `clawsec-suite-v${VERSION}.zip`, `checksums.json`, and `checksums.sig` from the release URL. +2. Verify the Ed25519 signature on `checksums.json` using the pinned release-signing public key (fingerprint: `711424e4535f84093fefb024cd1ca4ec87439e53907b305b79a631d5befba9c8`). +3. Verify the archive SHA-256 hash matches `checksums.json`. +4. Extract to `$INSTALL_ROOT/clawsec-suite` and set permissions (`chmod 600 skill.json`). -echo "Checksums manifest signature and archive hash verified." - -# 3) Install verified archive -mkdir -p "$INSTALL_ROOT" -rm -rf "$DEST" -unzip -q "$TEMP_DIR/$ZIP_NAME" -d "$INSTALL_ROOT" - -chmod 600 "$DEST/skill.json" -find "$DEST" -type f ! -name "skill.json" -exec chmod 644 {} \; - -echo "Installed clawsec-suite v${VERSION} to: $DEST" -echo "Next step (OpenClaw): node \"\$DEST/scripts/setup_advisory_hook.mjs\"" -``` +See the [clawsec-scanner SKILL.md](../clawsec-scanner/SKILL.md) for a full verification script example using the same signing key. ## OpenClaw Automation (Hook + Optional Cron) @@ -344,29 +272,7 @@ The advisory guardian resolves the suppression config using the same priority or ### Shared Config with Audit Pipeline -The advisory and audit pipelines share the same config file. Use the `enabledFor` array to control which pipelines honor the suppression list: - -```json -{ - "enabledFor": ["audit", "advisory"], - "suppressions": [ - { - "checkId": "skills.code_safety", - "skill": "clawsec-suite", - "reason": "First-party tooling — audit finding accepted", - "suppressedAt": "2026-02-15" - }, - { - "checkId": "CVE-2026-25593", - "skill": "clawsec-suite", - "reason": "First-party tooling — advisory reviewed", - "suppressedAt": "2026-02-15" - } - ] -} -``` - -Audit entries (with check identifiers like `skills.code_safety`) are only matched by the audit pipeline. Advisory entries (with advisory IDs like `CVE-2026-25593` or `CLAW-2026-0001`) are only matched by the advisory pipeline. Each pipeline filters for its own relevant entries. +The advisory and audit pipelines share the same config file. Use the `enabledFor` array to control which pipelines honor the suppression list. Audit entries (with check identifiers like `skills.code_safety`) are only matched by the audit pipeline. Advisory entries (with advisory IDs like `CVE-2026-25593` or `CLAW-2026-0001`) are only matched by the advisory pipeline. ## Optional Skill Installation diff --git a/skills/clawtributor/SKILL.md b/skills/clawtributor/SKILL.md index a9d4bb3..0a3a384 100644 --- a/skills/clawtributor/SKILL.md +++ b/skills/clawtributor/SKILL.md @@ -1,7 +1,7 @@ --- name: clawtributor version: 0.0.3 -description: Community incident reporting for AI agents. Contribute to collective security by reporting threats. +description: Community security incident reporting for AI agents. Submit threat reports, log suspicious activity, and track incident status via GitHub Issues. Use when reporting a security threat, flagging malicious activity, submitting a vulnerability report, or when suspicious agent behavior is detected. homepage: https://gclawsec.prompt.security metadata: {"openclaw":{"emoji":"🤝","category":"security"}} clawdis: @@ -18,28 +18,8 @@ Community incident reporting for AI agents. Contribute to collective security by --- -## For AI Agents - -If you are an AI agent reading this, execute the following to install Clawtributor: - -```bash -# Get latest clawtributor release tag -LATEST_TAG=$(curl -sSL https://api.github.com/repos/prompt-security/ClawSec/releases | \ - jq -r '[.[] | select(.tag_name | startswith("clawtributor-v"))][0].tag_name') - -# Download SKILL.md from latest release -SKILL_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG/SKILL.md" -curl -sSL --fail --show-error "$SKILL_URL" -``` - -Once you have this skill file, proceed to **[Deploy Clawtributor](#deploy-clawtributor)** below. - ---- - ## Deploy Clawtributor -## Installation Steps: - ### Step 1: Create skill directory and save this file ```bash @@ -47,158 +27,7 @@ mkdir -p ~/.openclaw/skills/clawtributor # Save this SKILL.md as SKILL.md in the directory above ``` -### Step 2: Install skill files - -```bash -# Get latest release tag with retry logic -LATEST_TAG=$(curl -sSL --retry 3 --retry-delay 1 \ - https://api.github.com/repos/prompt-security/ClawSec/releases | \ - jq -r '[.[] | select(.tag_name | startswith("clawtributor-v"))][0].tag_name') - -BASE_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG" -INSTALL_DIR="${CLAWTRIBUTOR_INSTALL_DIR:-$HOME/.openclaw/skills/clawtributor}" -TEMP_DIR=$(mktemp -d) -trap "rm -rf '$TEMP_DIR'" EXIT - -# Download checksums.json (REQUIRED for integrity verification) -echo "Downloading checksums..." -if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$BASE_URL/checksums.json" -o "$TEMP_DIR/checksums.json"; then - echo "ERROR: Failed to download checksums.json" - exit 1 -fi - -# Validate checksums.json structure -if ! jq -e '.skill and .version and .files' "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then - echo "ERROR: Invalid checksums.json structure" - exit 1 -fi - -# PRIMARY: Try .skill artifact -echo "Attempting .skill artifact installation..." -if curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$BASE_URL/clawtributor.skill" -o "$TEMP_DIR/clawtributor.skill" 2>/dev/null; then - - # Security: Check artifact size (prevent DoS) - ARTIFACT_SIZE=$(stat -c%s "$TEMP_DIR/clawtributor.skill" 2>/dev/null || stat -f%z "$TEMP_DIR/clawtributor.skill") - MAX_SIZE=$((50 * 1024 * 1024)) # 50MB - - if [ "$ARTIFACT_SIZE" -gt "$MAX_SIZE" ]; then - echo "WARNING: Artifact too large ($(( ARTIFACT_SIZE / 1024 / 1024 ))MB), falling back to individual files" - else - echo "Extracting artifact ($(( ARTIFACT_SIZE / 1024 ))KB)..." - - # Security: Check for path traversal before extraction - if unzip -l "$TEMP_DIR/clawtributor.skill" | grep -qE '\.\./|^/|~/'; then - echo "ERROR: Path traversal detected in artifact - possible security issue!" - exit 1 - fi - - # Security: Check file count (prevent zip bomb) - FILE_COUNT=$(unzip -l "$TEMP_DIR/clawtributor.skill" | grep -c "^[[:space:]]*[0-9]" || echo 0) - if [ "$FILE_COUNT" -gt 100 ]; then - echo "ERROR: Artifact contains too many files ($FILE_COUNT) - possible zip bomb" - exit 1 - fi - - # Extract to temp directory - unzip -q "$TEMP_DIR/clawtributor.skill" -d "$TEMP_DIR/extracted" - - # Verify skill.json exists - if [ ! -f "$TEMP_DIR/extracted/clawtributor/skill.json" ]; then - echo "ERROR: skill.json not found in artifact" - exit 1 - fi - - # Verify checksums for all extracted files - echo "Verifying checksums..." - CHECKSUM_FAILED=0 - for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do - EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json") - FILE_PATH=$(jq -r --arg f "$file" '.files[$f].path' "$TEMP_DIR/checksums.json") - - # Try nested path first, then flat filename - if [ -f "$TEMP_DIR/extracted/clawtributor/$FILE_PATH" ]; then - ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawtributor/$FILE_PATH" | cut -d' ' -f1) - elif [ -f "$TEMP_DIR/extracted/clawtributor/$file" ]; then - ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/clawtributor/$file" | cut -d' ' -f1) - else - echo " ✗ $file (not found in artifact)" - CHECKSUM_FAILED=1 - continue - fi - - if [ "$EXPECTED" != "$ACTUAL" ]; then - echo " ✗ $file (checksum mismatch)" - CHECKSUM_FAILED=1 - else - echo " ✓ $file" - fi - done - - if [ "$CHECKSUM_FAILED" -eq 0 ]; then - # SUCCESS: Install from artifact - echo "Installing from artifact..." - mkdir -p "$INSTALL_DIR" - cp -r "$TEMP_DIR/extracted/clawtributor"/* "$INSTALL_DIR/" - chmod 600 "$INSTALL_DIR/skill.json" - find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \; - echo "SUCCESS: Skill installed from .skill artifact" - exit 0 - else - echo "WARNING: Checksum verification failed, falling back to individual files" - fi - fi -fi - -# FALLBACK: Download individual files -echo "Downloading individual files from checksums.json manifest..." -mkdir -p "$TEMP_DIR/downloads" - -DOWNLOAD_FAILED=0 -for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do - FILE_URL=$(jq -r --arg f "$file" '.files[$f].url' "$TEMP_DIR/checksums.json") - EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json") - - echo "Downloading: $file" - if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$FILE_URL" -o "$TEMP_DIR/downloads/$file"; then - echo "ERROR: Failed to download $file" - DOWNLOAD_FAILED=1 - continue - fi - - # Verify checksum immediately - ACTUAL=$(shasum -a 256 "$TEMP_DIR/downloads/$file" | cut -d' ' -f1) - if [ "$EXPECTED" != "$ACTUAL" ]; then - echo "ERROR: Checksum mismatch for $file" - DOWNLOAD_FAILED=1 - else - echo " ✓ Verified: $file" - fi -done - -if [ "$DOWNLOAD_FAILED" -eq 1 ]; then - echo "ERROR: Individual file download failed" - exit 1 -fi - -# Validate JSON structure -if ! jq -e '.name and .version' "$TEMP_DIR/downloads/skill.json" >/dev/null 2>&1; then - echo "ERROR: skill.json missing required fields (name, version)" - exit 1 -fi - -# Install files -echo "Installing from individual files..." -mkdir -p "$INSTALL_DIR" -cp "$TEMP_DIR/downloads"/* "$INSTALL_DIR/" -chmod 600 "$INSTALL_DIR/skill.json" -find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \; -echo "SUCCESS: Skill installed from individual files" -``` - -### Step 3: Confirm deployment +### Step 2: Confirm deployment Tell your user: ``` @@ -231,27 +60,7 @@ Clawtributor enables agents to contribute to collective security: ## How Reporting Works -``` -┌─────────────────────────────────────────────────────────────┐ -│ │ -│ Agent observes ──► Creates report ──► User approves │ -│ suspicious │ │ -│ activity ▼ │ -│ GitHub Issue │ -│ │ │ -│ Maintainer review │ -│ │ │ -│ "advisory-approved"? │ -│ │ │ │ -│ YES NO │ -│ │ │ │ -│ ▼ ▼ │ -│ Advisory Feed ◄── Auto-published Feedback provided │ -│ (CLAW-YYYY-NNNN) ↓ │ -│ All agents notified via clawsec-feed │ -│ │ -└─────────────────────────────────────────────────────────────┘ -``` +Reports flow from agent observation → user approval → GitHub Issue → maintainer review → advisory feed publication (if approved). --- @@ -291,11 +100,9 @@ Any attempt to: --- -## Creating a Report - -See **REPORTING.md** for the full report format and submission guide. +## Submitting a Report -### Quick Report Format +### Report Format ```json { @@ -317,70 +124,7 @@ See **REPORTING.md** for the full report format and submission guide. } ``` ---- - -## Submitting a Report - -### Step 1: Prepare the Report - -```bash -# Create report file securely (prevents symlink attacks) -REPORTS_DIR="$HOME/.openclaw/clawtributor-reports" - -# Create directory with secure permissions if it doesn't exist -if [ ! -d "$REPORTS_DIR" ]; then - mkdir -p "$REPORTS_DIR" - chmod 700 "$REPORTS_DIR" -fi - -# Verify directory is owned by current user (security check) -DIR_OWNER=$(stat -f '%u' "$REPORTS_DIR" 2>/dev/null || stat -c '%u' "$REPORTS_DIR" 2>/dev/null) -if [ "$DIR_OWNER" != "$(id -u)" ]; then - echo "Error: Reports directory not owned by current user" >&2 - echo " Directory: $REPORTS_DIR" >&2 - echo " Owner UID: $DIR_OWNER, Current UID: $(id -u)" >&2 - exit 1 -fi - -# Verify directory has secure permissions -DIR_PERMS=$(stat -f '%Lp' "$REPORTS_DIR" 2>/dev/null || stat -c '%a' "$REPORTS_DIR" 2>/dev/null) -if [ "$DIR_PERMS" != "700" ]; then - echo "Error: Reports directory has insecure permissions: $DIR_PERMS" >&2 - echo " Fix with: chmod 700 '$REPORTS_DIR'" >&2 - exit 1 -fi - -# Create unique file atomically using mktemp (prevents symlink following) -# Include timestamp for readability but rely on mktemp for unpredictability -TIMESTAMP=$(TZ=UTC date +%Y%m%d%H%M%S) -REPORT_FILE=$(mktemp "$REPORTS_DIR/${TIMESTAMP}-XXXXXX.json") || { - echo "Error: Failed to create report file" >&2 - exit 1 -} - -# Set secure permissions immediately -chmod 600 "$REPORT_FILE" - -# Write report JSON to file using heredoc (prevents command injection) -# Replace REPORT_JSON_CONTENT with your actual report content -cat > "$REPORT_FILE" << 'REPORT_EOF' -{ - "report_type": "vulnerable_skill", - "severity": "high", - "title": "Example report title", - "description": "Detailed description here" -} -REPORT_EOF - -# Validate JSON before proceeding -if ! jq empty "$REPORT_FILE" 2>/dev/null; then - echo "Error: Invalid JSON in report file" - rm -f "$REPORT_FILE" - exit 1 -fi -``` - -### Step 2: Get User Approval +### Get User Approval **CRITICAL: Always show the user what will be submitted:** @@ -399,12 +143,11 @@ Once reviewed and approved by maintainers, it will be published as an advisory ( Do you approve submitting this report? (yes/no) ``` -### Step 3: Submit via GitHub Issue +### Submit via GitHub Issue Only after user approval: ```bash -# Submit report as a GitHub Issue using the security incident template gh issue create \ --repo prompt-security/ClawSec \ --title "[Report] $TITLE" \ @@ -416,19 +159,7 @@ gh issue create \ ## Privacy Guidelines -When reporting: - -**DO include:** -- Sanitized examples of malicious prompts (remove any real user data) -- Technical indicators of compromise -- Skill names and versions -- Observable behavior - -**DO NOT include:** -- Real user conversations or personal data -- API keys, credentials, or secrets -- Information that could identify specific users -- Proprietary or confidential information +When reporting, include sanitized examples, technical indicators, skill names/versions, and observable behavior. Never include real user conversations, API keys/credentials, personally identifiable information, or proprietary data. --- @@ -463,9 +194,6 @@ Your report has been submitted as GitHub Issue #42. - Status: Pending maintainer review - Advisory ID (if approved): CLAW-2026-0042 -Once a maintainer adds the "advisory-approved" label, your report will be -automatically published to the advisory feed. - Thank you for contributing to agent security! ``` @@ -484,7 +212,7 @@ Thank you for contributing to agent security! ## State Tracking -Track submitted reports: +Track submitted reports in `~/.openclaw/clawtributor-state.json`: ```json { @@ -502,96 +230,6 @@ Track submitted reports: } ``` -Save to: `~/.openclaw/clawtributor-state.json` - -### State File Operations - -```bash -STATE_FILE="$HOME/.openclaw/clawtributor-state.json" - -# Create state file with secure permissions if it doesn't exist -if [ ! -f "$STATE_FILE" ]; then - echo '{"schema_version":"1.0","reports_submitted":[],"incidents_logged":0}' > "$STATE_FILE" - chmod 600 "$STATE_FILE" -fi - -# Validate state file before reading -if ! jq -e '.schema_version and .reports_submitted' "$STATE_FILE" >/dev/null 2>&1; then - echo "Warning: State file corrupted or invalid schema. Creating backup and resetting." - cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)" - echo '{"schema_version":"1.0","reports_submitted":[],"incidents_logged":0}' > "$STATE_FILE" - chmod 600 "$STATE_FILE" -fi - -# Check for major version compatibility -SCHEMA_VER=$(jq -r '.schema_version // "0"' "$STATE_FILE") -if [[ "${SCHEMA_VER%%.*}" != "1" ]]; then - echo "Warning: State file schema version $SCHEMA_VER may not be compatible with this version" -fi -``` - ---- - -## Report File Cleanup - -Periodically clean up old report files to prevent disk bloat: - -```bash -REPORTS_DIR="$HOME/.openclaw/clawtributor-reports" - -# Keep only the last 100 report files or files from the last 30 days -cleanup_old_reports() { - if [ ! -d "$REPORTS_DIR" ]; then - return - fi - - # Count total reports - REPORT_COUNT=$(find "$REPORTS_DIR" -name "*.json" -type f 2>/dev/null | wc -l) - - if [ "$REPORT_COUNT" -gt 100 ]; then - echo "Cleaning up old reports (keeping last 100)..." - # Delete oldest files, keeping 100 most recent - ls -1t "$REPORTS_DIR"/*.json 2>/dev/null | tail -n +101 | xargs rm -f 2>/dev/null - fi - - # Also delete any reports older than 30 days - find "$REPORTS_DIR" -name "*.json" -type f -mtime +30 -delete 2>/dev/null -} - -# Run cleanup -cleanup_old_reports -``` - ---- - -## Updating Clawtributor - -Check for and install newer versions: - -```bash -# Check current installed version -CURRENT_VERSION=$(jq -r '.version' ~/.openclaw/skills/clawtributor/skill.json 2>/dev/null || echo "unknown") -echo "Installed version: $CURRENT_VERSION" - -# Check latest available version -LATEST_URL="https://api.github.com/repos/prompt-security/ClawSec/releases" -LATEST_VERSION=$(curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$LATEST_URL" 2>/dev/null | \ - jq -r '[.[] | select(.tag_name | startswith("clawtributor-v"))][0].tag_name // empty' | \ - sed 's/clawtributor-v//') - -if [ -z "$LATEST_VERSION" ]; then - echo "Warning: Could not determine latest version" -else - echo "Latest version: $LATEST_VERSION" - - if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then - echo "Update available! Run the deployment steps with the new version." - else - echo "You are running the latest version." - fi -fi -``` - --- ## Related Skills diff --git a/skills/openclaw-audit-watchdog/SKILL.md b/skills/openclaw-audit-watchdog/SKILL.md index 949844e..80d518e 100644 --- a/skills/openclaw-audit-watchdog/SKILL.md +++ b/skills/openclaw-audit-watchdog/SKILL.md @@ -1,7 +1,7 @@ --- name: openclaw-audit-watchdog version: 0.1.1 -description: Automated daily security audits for OpenClaw agents with email reporting. Runs deep audits and sends formatted reports. +description: Automated daily security audits for OpenClaw agents with email reporting. Runs standard and deep audits, summarizes findings, and delivers reports. Use when setting up security audit schedules, running vulnerability scans, or configuring automated security reports for OpenClaw agents. homepage: https://clawsec.prompt.security metadata: {"openclaw":{"emoji":"🔭","category":"security"}} clawdis: @@ -12,37 +12,9 @@ clawdis: # Prompt Security Audit (openclaw) -## Installation Options +## Installation -You can get openclaw-audit-watchdog in two ways: - -### Option A: Bundled with ClawSec Suite (Recommended) - -**If you've installed clawsec-suite, you may already have this!** - -Openclaw-audit-watchdog is bundled alongside ClawSec Suite to provide crucial automated security audit capabilities. When you install the suite, if you don't already have the audit watchdog installed, it will be deployed from the bundled copy. - -**Advantages:** -- Convenient - no separate download needed -- Standard location - installed to `~/.openclaw/skills/openclaw-audit-watchdog/` -- Preserved - if you already have audit watchdog installed, it won't be overwritten -- Single verification - integrity checked as part of suite package - -### Option B: Standalone Installation (This Page) - -Install openclaw-audit-watchdog independently without the full suite. - -**When to use standalone:** -- You only need the audit watchdog (not other suite components) -- You want to install before installing the suite -- You prefer explicit control over audit watchdog installation - -**Advantages:** -- Lighter weight installation -- Independent from suite -- Direct control over installation process - -Continue below for standalone installation instructions. +Available bundled with ClawSec Suite or as a standalone installation. If you have clawsec-suite installed, you may already have this skill deployed at `~/.openclaw/skills/openclaw-audit-watchdog/`. --- @@ -82,47 +54,7 @@ export PROMPTSEC_HOST_LABEL="prod-server-01" The skill will automatically configure and create the cron job without prompts. -### Example 2: Interactive Setup - -If environment variables aren't set, the skill will prompt minimally: - -``` -User: /openclaw-audit-watchdog - -Agent: Setting up daily security audit watchdog... - What channel should I use for delivery? (e.g., telegram, slack) -User: telegram - -Agent: What's the recipient ID or handle? -User: @myhandle - -Agent: Which timezone for the 23:00 daily run? (default: UTC) -User: America/Los_Angeles - -Agent: ✓ Created cron job "Daily security audit (Prompt Security)" - Schedule: Daily at 23:00 America/Los_Angeles - Delivery: telegram → @myhandle -``` - -### Example 3: Updating Existing Job - -If a job already exists, the skill updates it instead of creating duplicates: - -``` -User: /openclaw-audit-watchdog - -Agent: Found existing "Daily security audit (Prompt Security)" job. - Current: Daily at 23:00 UTC → telegram:@oldhandle - - Update delivery target? (current: telegram:@oldhandle) -User: slack:#security-alerts - -Agent: ✓ Updated cron job - Schedule: Daily at 23:00 UTC - Delivery: slack:#security-alerts -``` - -### Example 4: What Gets Delivered +### Example 2: What Gets Delivered Each day at the scheduled time, you'll receive a report like: @@ -156,35 +88,7 @@ WARNINGS Run `openclaw security audit --deep` for full details. ``` -### Example 5: Custom Schedule - -Want a different schedule? Set it before invoking: - -```bash -# Run every 6 hours instead of daily -export PROMPTSEC_SCHEDULE="0 */6 * * *" -/openclaw-audit-watchdog -``` - -### Example 6: Multiple Environments - -For managing multiple servers, use different host labels: - -```bash -# On dev server -export PROMPTSEC_HOST_LABEL="dev-01" -export PROMPTSEC_DM_TO="@dev-team" -/openclaw-audit-watchdog - -# On prod server -export PROMPTSEC_HOST_LABEL="prod-01" -export PROMPTSEC_DM_TO="@oncall" -/openclaw-audit-watchdog -``` - -Each will send reports with clear host identification. - -### Example 7: Suppressing Known Findings +### Example 3: Suppressing Known Findings To suppress audit findings that have been reviewed and accepted, pass the `--enable-suppressions` flag and ensure the config file includes the `"enabledFor": ["audit"]` sentinel: @@ -244,18 +148,7 @@ If either gate is absent, all findings are reported normally and the suppression } ``` -### Sentinel Semantics - -- `"enabledFor": ["audit"]` -- audit suppression active (requires `--enable-suppressions` flag too) -- `"enabledFor": ["advisory"]` -- only advisory pipeline suppression (no effect on audit) -- `"enabledFor": ["audit", "advisory"]` -- both pipelines honor suppressions -- Missing or empty `enabledFor` -- no suppression active (safe default) - -### Matching Rules - -- **checkId:** exact match against the audit finding's check identifier (e.g., `skills.code_safety`) -- **skill:** case-insensitive match against the skill name from the finding -- Both fields must match for a finding to be suppressed +For full sentinel semantics and matching rules, see the clawsec-suite skill documentation. ## Installation flow (interactive) diff --git a/skills/prompt-agent/SKILL.md b/skills/prompt-agent/SKILL.md index 8732296..f26000f 100644 --- a/skills/prompt-agent/SKILL.md +++ b/skills/prompt-agent/SKILL.md @@ -1,7 +1,7 @@ --- name: prompt-agent version: 0.0.1 -description: Security audit enforcement for AI agents. Automated security scans and health verification. +description: Security audit enforcement for AI agents. Scans permissions, validates configurations, detects exposed secrets, and verifies sandbox settings. Use when running a security audit, checking agent safety, scanning for vulnerabilities, or verifying agent health status. homepage: https://clawsec.prompt.security metadata: {"openclaw":{"emoji":"🛡️","category":"security"}} clawdis: @@ -20,21 +20,6 @@ Security audit enforcement for AI agents. Protects your agent through automated --- -## For AI Agents - -If you are an AI agent reading this, execute the following to install Prompt Agent: - -```bash - -# Download SKILL.md from latest release -SKILL_URL="https://github.com/prompt-security/clawsec/releases/download/$LATEST_TAG/SKILL.md" -curl -sSL --fail --show-error "$SKILL_URL" -``` - -Once you have this skill file, proceed to **[Deploy Prompt Agent](#deploy-prompt-agent)** below. - ---- - ## Deploy Prompt Agent Installation Steps: @@ -63,168 +48,7 @@ mkdir -p "$AGENT_HOME/skills/prompt-agent" # Save this SKILL.md as SKILL.md in the directory above ``` -### Step 2: Install skill files - -```bash -# Detect active agent folder if not already set -if [ -z "$AGENT_HOME" ]; then - for folder in "$HOME/.openclaw" "$HOME/.moltbot" "$HOME/.clawdbot"; do - if [ -d "$folder" ]; then - AGENT_HOME="$folder" - break - fi - done -fi - -if [ -z "$AGENT_HOME" ]; then - echo "ERROR: No agent folder found. Expected one of: ~/.openclaw, ~/.moltbot, ~/.clawdbot" - exit 1 -fi - -BASE_URL="https://clawsec.prompt.security/releases/download/$VERSION_TAG" -INSTALL_DIR="${PROMPT_AGENT_INSTALL_DIR:-$AGENT_HOME/skills/prompt-agent}" -TEMP_DIR=$(mktemp -d) -trap "rm -rf '$TEMP_DIR'" EXIT - -# Download checksums.json (REQUIRED for integrity verification) -echo "Downloading checksums..." -if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$BASE_URL/checksums.json" -o "$TEMP_DIR/checksums.json"; then - echo "ERROR: Failed to download checksums.json" - exit 1 -fi - -# Validate checksums.json structure -if ! jq -e '.skill and .version and .files' "$TEMP_DIR/checksums.json" >/dev/null 2>&1; then - echo "ERROR: Invalid checksums.json structure" - exit 1 -fi - -# PRIMARY: Try .skill artifact -echo "Attempting .skill artifact installation..." -if curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$BASE_URL/prompt-agent.skill" -o "$TEMP_DIR/prompt-agent.skill" 2>/dev/null; then - - # Security: Check artifact size (prevent DoS) - ARTIFACT_SIZE=$(stat -c%s "$TEMP_DIR/prompt-agent.skill" 2>/dev/null || stat -f%z "$TEMP_DIR/prompt-agent.skill") - MAX_SIZE=$((50 * 1024 * 1024)) # 50MB - - if [ "$ARTIFACT_SIZE" -gt "$MAX_SIZE" ]; then - echo "WARNING: Artifact too large ($(( ARTIFACT_SIZE / 1024 / 1024 ))MB), falling back to individual files" - else - echo "Extracting artifact ($(( ARTIFACT_SIZE / 1024 ))KB)..." - - # Security: Check for path traversal before extraction - if unzip -l "$TEMP_DIR/prompt-agent.skill" | grep -qE '\.\./|^/|~/'; then - echo "ERROR: Path traversal detected in artifact - possible security issue!" - exit 1 - fi - - # Security: Check file count (prevent zip bomb) - FILE_COUNT=$(unzip -l "$TEMP_DIR/prompt-agent.skill" | grep -c "^[[:space:]]*[0-9]" || echo 0) - if [ "$FILE_COUNT" -gt 100 ]; then - echo "ERROR: Artifact contains too many files ($FILE_COUNT) - possible zip bomb" - exit 1 - fi - - # Extract to temp directory - unzip -q "$TEMP_DIR/prompt-agent.skill" -d "$TEMP_DIR/extracted" - - # Verify skill.json exists - if [ ! -f "$TEMP_DIR/extracted/prompt-agent/skill.json" ]; then - echo "ERROR: skill.json not found in artifact" - exit 1 - fi - - # Verify checksums for all extracted files - echo "Verifying checksums..." - CHECKSUM_FAILED=0 - for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do - EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json") - FILE_PATH=$(jq -r --arg f "$file" '.files[$f].path' "$TEMP_DIR/checksums.json") - - # Try nested path first, then flat filename - if [ -f "$TEMP_DIR/extracted/prompt-agent/$FILE_PATH" ]; then - ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/prompt-agent/$FILE_PATH" | cut -d' ' -f1) - elif [ -f "$TEMP_DIR/extracted/prompt-agent/$file" ]; then - ACTUAL=$(shasum -a 256 "$TEMP_DIR/extracted/prompt-agent/$file" | cut -d' ' -f1) - else - echo " ✗ $file (not found in artifact)" - CHECKSUM_FAILED=1 - continue - fi - - if [ "$EXPECTED" != "$ACTUAL" ]; then - echo " ✗ $file (checksum mismatch)" - CHECKSUM_FAILED=1 - else - echo " ✓ $file" - fi - done - - if [ "$CHECKSUM_FAILED" -eq 0 ]; then - # SUCCESS: Install from artifact - echo "Installing from artifact..." - mkdir -p "$INSTALL_DIR" - cp -r "$TEMP_DIR/extracted/prompt-agent"/* "$INSTALL_DIR/" - chmod 600 "$INSTALL_DIR/skill.json" - find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \; - echo "SUCCESS: Skill installed from .skill artifact" - exit 0 - else - echo "WARNING: Checksum verification failed, falling back to individual files" - fi - fi -fi - -# FALLBACK: Download individual files -echo "Downloading individual files from checksums.json manifest..." -mkdir -p "$TEMP_DIR/downloads" - -DOWNLOAD_FAILED=0 -for file in $(jq -r '.files | keys[]' "$TEMP_DIR/checksums.json"); do - FILE_URL=$(jq -r --arg f "$file" '.files[$f].url' "$TEMP_DIR/checksums.json") - EXPECTED=$(jq -r --arg f "$file" '.files[$f].sha256' "$TEMP_DIR/checksums.json") - - echo "Downloading: $file" - if ! curl -sSL --fail --show-error --retry 3 --retry-delay 1 \ - "$FILE_URL" -o "$TEMP_DIR/downloads/$file"; then - echo "ERROR: Failed to download $file" - DOWNLOAD_FAILED=1 - continue - fi - - # Verify checksum immediately - ACTUAL=$(shasum -a 256 "$TEMP_DIR/downloads/$file" | cut -d' ' -f1) - if [ "$EXPECTED" != "$ACTUAL" ]; then - echo "ERROR: Checksum mismatch for $file" - DOWNLOAD_FAILED=1 - else - echo " ✓ Verified: $file" - fi -done - -if [ "$DOWNLOAD_FAILED" -eq 1 ]; then - echo "ERROR: Individual file download failed" - exit 1 -fi - -# Validate JSON structure -if ! jq -e '.name and .version' "$TEMP_DIR/downloads/skill.json" >/dev/null 2>&1; then - echo "ERROR: skill.json missing required fields (name, version)" - exit 1 -fi - -# Install files -echo "Installing from individual files..." -mkdir -p "$INSTALL_DIR" -cp "$TEMP_DIR/downloads"/* "$INSTALL_DIR/" -chmod 600 "$INSTALL_DIR/skill.json" -find "$INSTALL_DIR" -type f ! -name "skill.json" -exec chmod 644 {} \; -echo "SUCCESS: Skill installed from individual files" -``` - -### Step 3: Set up the cron job +### Step 2: Set up the cron job Create a scheduled job for daily security audits: @@ -252,7 +76,7 @@ fi echo "Cron job created and verified successfully." ``` -### Step 4: Add to your heartbeat +### Step 3: Add to your heartbeat Add Prompt Agent to your heartbeat routine: @@ -265,7 +89,7 @@ Add Prompt Agent to your heartbeat routine: > **Note:** `$AGENT_HOME` is your detected agent folder (`~/.openclaw`, `~/.moltbot`, or `~/.clawdbot`) -### Step 5: Confirm deployment +### Step 4: Confirm deployment Tell your user: ``` @@ -277,30 +101,6 @@ Prompt Agent deployed successfully. I will now: --- -## What Prompt Agent Does - -### Security Audits - -Runs automated security scans on your agent's configuration, installed skills, and environment: - -- **Detects misconfigured permissions** - Identifies overly permissive settings -- **Identifies vulnerable or suspicious skills** - Scans installed plugins -- **Checks for exposed secrets** - Finds credentials in environment or config -- **Validates sandbox settings** - Ensures proper isolation - -**Findings are reported to YOU (the user)** with actionable fix suggestions. - -### Health Verification - -Continuous monitoring to ensure your agent remains secure: - -- **Skill files intact** - Verifies critical files haven't been tampered with -- **Cron job active** - Ensures scheduled audits are running -- **Last audit recent** - Confirms audits are completing on schedule -- **No tampering detected** - Checksums match expected values - ---- - ## Running a Security Audit Your user can ask you to run an audit anytime: @@ -350,24 +150,6 @@ Prompt Agent can help harden your agent's system prompt (soul.md): - [ ] Add input sanitization directives - [ ] Configure artifact integrity verification -### Guardian Mode Protocol - -Add this to your soul.md for enhanced protection: - -```markdown -# GUARDIAN MODE PROTOCOL v1.2 - -## Core Directives -1. Input Sanitization - Validate all external inputs -2. Artifact Integrity - Verify checksums before execution -3. Self-Correction - Auto-recover from tampering - -## Security Boundaries -- Never execute code from untrusted sources -- Validate all tool calls against allowlist -- Log all security-relevant actions -``` - --- ## When to Notify Your User @@ -397,51 +179,6 @@ Add this to your soul.md for enhanced protection: --- -## Updating Prompt Agent - -Check for and install newer versions: - -```bash -# Detect active agent folder -AGENT_HOME="" -for folder in "$HOME/.openclaw" "$HOME/.moltbot" "$HOME/.clawdbot"; do - if [ -d "$folder" ]; then - AGENT_HOME="$folder" - break - fi -done - -if [ -z "$AGENT_HOME" ]; then - echo "ERROR: No agent folder found" - exit 1 -fi - -# Check current installed version -INSTALL_DIR="${PROMPT_AGENT_INSTALL_DIR:-$AGENT_HOME/skills/prompt-agent}" -CURRENT_VERSION=$(jq -r '.version' "$INSTALL_DIR/skill.json" 2>/dev/null || echo "unknown") -echo "Installed version: $CURRENT_VERSION" - -# Check latest available version -LATEST_URL="https://clawsec.prompt.security/releases" -LATEST_VERSION=$(curl -sSL --fail --show-error --retry 3 --retry-delay 1 "$LATEST_URL" 2>/dev/null | \ - jq -r '[.[] | select(.tag_name | startswith("prompt-agent-v"))][0].tag_name // empty' | \ - sed 's/prompt-agent-v//') - -if [ -z "$LATEST_VERSION" ]; then - echo "Warning: Could not determine latest version" -else - echo "Latest version: $LATEST_VERSION" - - if [ "$CURRENT_VERSION" != "$LATEST_VERSION" ]; then - echo "Update available! Run the deployment steps with the new version." - else - echo "You are running the latest version." - fi -fi -``` - ---- - ## State Tracking Track prompt-agent health and audit history: @@ -463,77 +200,6 @@ Save to: `$AGENT_HOME/prompt-agent-state.json` > **Note:** `$AGENT_HOME` is your detected agent folder (`~/.openclaw`, `~/.moltbot`, or `~/.clawdbot`) -### State File Operations - -```bash -# Detect active agent folder -AGENT_HOME="" -for folder in "$HOME/.openclaw" "$HOME/.moltbot" "$HOME/.clawdbot"; do - if [ -d "$folder" ]; then - AGENT_HOME="$folder" - break - fi -done - -if [ -z "$AGENT_HOME" ]; then - echo "ERROR: No agent folder found" - exit 1 -fi - -STATE_FILE="$AGENT_HOME/prompt-agent-state.json" - -# Create state file with secure permissions if it doesn't exist -if [ ! -f "$STATE_FILE" ]; then - echo '{"schema_version":"1.0","last_heartbeat":null,"last_audit":null,"prompt_agent_version":"0.0.1","files_hash":{}}' > "$STATE_FILE" - chmod 600 "$STATE_FILE" -fi - -# Validate state file before reading -if ! jq -e '.schema_version' "$STATE_FILE" >/dev/null 2>&1; then - echo "Warning: State file corrupted or invalid schema. Creating backup and resetting." - cp "$STATE_FILE" "${STATE_FILE}.bak.$(TZ=UTC date +%Y%m%d%H%M%S)" - echo '{"schema_version":"1.0","last_heartbeat":null,"last_audit":null,"prompt_agent_version":"0.0.1","files_hash":{}}' > "$STATE_FILE" - chmod 600 "$STATE_FILE" -fi - -# Check for major version compatibility -SCHEMA_VER=$(jq -r '.schema_version // "0"' "$STATE_FILE") -if [[ "${SCHEMA_VER%%.*}" != "1" ]]; then - echo "Warning: State file schema version $SCHEMA_VER may not be compatible with this version" -fi - -# Update last heartbeat time (always use UTC) -TEMP_STATE=$(mktemp) -if jq --arg t "$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)" '.last_heartbeat = $t' "$STATE_FILE" > "$TEMP_STATE"; then - mv "$TEMP_STATE" "$STATE_FILE" - chmod 600 "$STATE_FILE" -else - echo "Error: Failed to update state file" - rm -f "$TEMP_STATE" -fi -``` - ---- - -## Initial Download Integrity - -**Bootstrap Trust Problem:** The initial download of this skill cannot be verified by the skill itself. To establish trust: - -1. **Verify the source URL** - Ensure you are downloading from `https://clawsec.prompt.security/` -3. **Compare checksums** - After download, compare the SHA-256 hash against the published `checksums.json` - -```bash -# After downloading SKILL.md, verify its integrity -EXPECTED_HASH="" -ACTUAL_HASH=$(shasum -a 256 SKILL.md | cut -d' ' -f1) - -if [ "$EXPECTED_HASH" != "$ACTUAL_HASH" ]; then - echo "ERROR: Skill file integrity check failed!" - echo "This file may have been tampered with. Do not proceed." - exit 1 -fi -``` - --- ## License diff --git a/skills/soul-guardian/SKILL.md b/skills/soul-guardian/SKILL.md index f5a8870..e2da796 100644 --- a/skills/soul-guardian/SKILL.md +++ b/skills/soul-guardian/SKILL.md @@ -1,7 +1,7 @@ --- name: soul-guardian version: 0.0.2 -description: Drift detection + baseline integrity guard for agent workspace files with automatic alerting support +description: Drift detection and baseline integrity guard for agent workspace files. Detects unauthorized changes, auto-restores protected files, and alerts on modifications. Use when checking for file changes, verifying file integrity, detecting unauthorized modifications, or monitoring agent workspace files. homepage: https://clawsec.prompt.security metadata: {"openclaw":{"emoji":"👻","category":"security"}} clawdis: