Back to Skills
    🦞

    ecap-security-auditor

    Security audit framework for AI agent skills

    By @starbuck100
    View on GitHub
    SKILL.md
    ---
    name: ecap-security-auditor
    description: Security audit framework for AI agent skills, MCP servers, and packages. Your LLM does the analysis β€” we provide structure, prompts, and a shared trust database.
    metadata: {"openclaw":{"requires":{"bins":["bash","jq","curl"]}}}
    ---
    
    # ecap Security Auditor
    
    **You are an AI agent with a built-in security shield.** This skill makes you automatically verify every package, skill, and MCP server before you install or use it β€” and gives you the tools to audit anything yourself.
    
    ---
    
    ## πŸ“– Key Terms
    
    | Term | Definition |
    |------|-----------|
    | `risk_score` | API field (0–100). **Higher = more dangerous.** 0 = perfectly safe, 100 = actively malicious. |
    | Trust Score | Display metric (0–100). **Higher = more trustworthy.** Calculated as `100 - penalties from findings`. Used in Gate decisions. |
    | `ecap_id` | Unique finding identifier (e.g., `ECAP-2026-0777`). **Used in all API URLs** for `/review` and `/fix` endpoints. |
    | `package_name` | The name used to query the registry (e.g., `"express"`, `"mcp-server-fetch"`). API field is `skill_slug`; both are accepted. |
    
    ---
    
    ## ⚑ Automatic Security Gate (Primary Feature)
    
    This is your **passive security layer**. Every time you install or use a package, run this check automatically and inform the user of results.
    
    ### When to Trigger
    
    Run the Security Gate automatically when:
    
    - `clawdhub install <skill>` β€” any skill installation
    - `pip install <package>` / `npm install <package>` β€” any package installation
    - First use of any MCP server
    - User says "audit", "check", or "verify" a package
    
    ### Gate Flow
    
    ```
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  Package install/use detectedβ”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 1. Query Trust Registry     β”‚
    β”‚    GET /api/findings?package=β”‚
    β”‚    GET /api/integrity?package=β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚ Report   │──── No ───▢ Go to AUTO-AUDIT
             β”‚ exists?  β”‚
             β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                  β”‚ Yes
                  β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 2. Hash Verification        β”‚
    β”‚    Run: bash scripts/verify.sh <package>
    β”‚    Compares local file hashesβ”‚
    β”‚    against audited hashes    β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β–Ό
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚ Hash OK? │──── No ───▢ 🚨 STOP: TAMPERED
             β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                  β”‚ Yes
                  β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ 3. Calculate Trust Score    β”‚
    β”‚    from findings (see below)β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                    β”‚
    Score β‰₯ 70          Score 40-69         Score < 40
         β”‚                    β”‚                  β”‚
         β–Ό                    β–Ό                  β–Ό
     βœ… PASS            ⚠️ WARNING          πŸ”΄ BLOCK
     Continue           Show findings,       Block install.
     silently.          let user decide.     Offer to audit.
    ```
    
    ### Decision Table
    
    | Condition | Action | Message to User |
    |-----------|--------|-----------------|
    | Score β‰₯ 70 + Hash OK | βœ… Proceed | `βœ… [package] β€” Trust Score: XX/100, verified.` |
    | Score 40–69 + Hash OK | ⚠️ Warn, user decides | `⚠️ [package] β€” Trust Score: XX/100. Known issues: [list]. Proceed? (y/n)` |
    | Score < 40 | πŸ”΄ Block | `πŸ”΄ [package] β€” Trust Score: XX/100. Blocked. Run audit to investigate.` |
    
    > **Note:** By-design findings (e.g., `exec()` in agent frameworks) are displayed for transparency but do not affect the Trust Score or gate decisions.
    | No report exists | πŸ” Auto-audit | `πŸ” [package] β€” No audit data. Running security audit now...` |
    | Hash mismatch | 🚨 Hard stop | `🚨 [package] β€” INTEGRITY FAILURE. Local files don't match audited version. DO NOT INSTALL.` |
    
    ### Step-by-Step Implementation
    
    **Step 1: Query the Trust Registry**
    
    ```bash
    # Check for existing findings
    curl -s "https://skillaudit-api.vercel.app/api/findings?package=PACKAGE_NAME"
    
    # Check file integrity hashes
    curl -s "https://skillaudit-api.vercel.app/api/integrity?package=PACKAGE_NAME"
    ```
    
    **Example β€” GET /api/findings?package=coding-agent** (with findings):
    
    ```json
    {
      "findings": [
        {
          "id": 11, "ecap_id": "ECAP-2026-0782",
          "title": "Overly broad binary execution requirements",
          "description": "Skill metadata requires ability to run \"anyBins\" which grants permission to execute any binary on the system.",
          "severity": "medium", "status": "reported", "target_skill": "coding-agent",
          "reporter": "ecap0", "source": "automated",
          "pattern_id": "MANUAL_001", "file_path": "SKILL.md", "line_number": 4,
          "confidence": "medium"
        }
      ],
      "total": 6, "page": 1, "limit": 100, "totalPages": 1
    }
    ```
    
    **Example β€” GET /api/findings?package=totally-unknown-xyz** (no findings):
    
    ```json
    {"findings": [], "total": 0, "page": 1, "limit": 100, "totalPages": 0}
    ```
    
    > Note: Unknown packages return `200 OK` with an empty array, not 404.
    
    **Example β€” GET /api/integrity?package=ecap-security-auditor**:
    
    ```json
    {
      "package": "ecap-security-auditor",
      "repo": "https://github.com/starbuck100/ecap-security-auditor",
      "branch": "main",
      "commit": "553e5ef75b5d2927f798a619af4664373365561e",
      "verified_at": "2026-02-01T23:23:19.786Z",
      "files": {
        "SKILL.md": {"sha256": "8ee24d731a...", "size": 11962},
        "scripts/upload.sh": {"sha256": "21e74d994e...", "size": 2101},
        "scripts/register.sh": {"sha256": "00c1ad0f8c...", "size": 2032},
        "prompts/audit-prompt.md": {"sha256": "69e4bb9038...", "size": 5921},
        "prompts/review-prompt.md": {"sha256": "82445ed119...", "size": 2635},
        "README.md": {"sha256": "2dc39c30e7...", "size": 3025}
      }
    }
    ```
    
    > If the package is not in the integrity database, the API returns `404`:
    > ```json
    > {"error": "Unknown package: unknown-xyz", "known_packages": ["ecap-security-auditor"]}
    > ```
    
    **Step 2: Verify Integrity**
    
    ```bash
    bash scripts/verify.sh <package-name>
    # Example: bash scripts/verify.sh ecap-security-auditor
    ```
    
    This compares SHA-256 hashes of local files against the hashes stored during the last audit. If any file has changed since it was audited, the check fails.
    
    > **⚠️ Limitation:** `verify.sh` only works for packages registered in the integrity database. Currently only `ecap-security-auditor` is registered. For other packages, skip integrity verification and rely on Trust Score from findings only.
    
    > **πŸ”’ Security:** The API URL in `verify.sh` is hardcoded to the official registry and cannot be overridden. This prevents malicious SKILL.md forks from redirecting integrity checks to fake servers.
    
    **Step 3: Calculate Trust Score & Apply Decision Logic**
    
    The API does **not** provide a Trust Score endpoint. Calculate it yourself from the findings:
    
    ```
    Trust Score = max(0, 100 - penalties)
    
    Penalties per finding (only where by_design = false):
      Critical: -25
      High:     -15
      Medium:    -8
      Low:       -3
      Any (by_design = true): 0  ← excluded from score
    ```
    
    > **Component-Type Weighting (v2):** Apply a Γ—1.2 multiplier to penalties for findings in high-risk component types: shell scripts in `hooks/`, `.mcp.json` configs, `settings.json`, and plugin entry points. Findings in documentation or test files receive no multiplier.
    
    **Example:** 1 critical + 2 medium findings β†’ 100 - 25 - 8 - 8 = **59** (⚠️ Caution)
    **Example with by-design:** 3 by-design high + 1 real low β†’ 100 - 0 - 0 - 0 - 3 = **97** (βœ… Trusted)
    
    > **By-design findings** are patterns that are core to the package's documented purpose (e.g., `exec()` in an agent framework). They are reported for transparency but do not reduce the Trust Score. See `audit-prompt.md` Step 4 for classification criteria.
    
    If the package has a report in `/api/reports`, you can also use the `risk_score` from the report: `Trust Score β‰ˆ 100 - risk_score`.
    
    Apply the decision table above based on the calculated Trust Score.
    
    **Step 4: Auto-Audit (if no data exists)**
    
    If the registry has no report for this package:
    
    1. Get the source code (see "Getting Package Source" below)
    2. Read ALL files in the package directory
    3. Read `prompts/audit-prompt.md` β€” follow every instruction
    4. Analyze each file against the security checklist
    5. **Perform cross-file analysis** (see Cross-File Analysis below)
    6. Build a JSON report (format below)
    7. Upload: `bash scripts/upload.sh report.json`
    8. Re-run the gate check with the new data
    
    This is how the registry grows organically β€” every agent contributes.
    
    ### Getting Package Source for Auto-Audit
    
    ⚠️ **The audit must run BEFORE installation.** You need the source code without executing install scripts. Here's how:
    
    | Type | How to get source safely | Audit location |
    |------|--------------------------|----------------|
    | OpenClaw skill | Already local after `clawdhub install` (skills are inert files) | `skills/<name>/` |
    | npm package | `npm pack <name> && mkdir -p /tmp/audit-target && tar xzf *.tgz -C /tmp/audit-target/` | `/tmp/audit-target/package/` |
    | pip package | `pip download <name> --no-deps -d /tmp/ && cd /tmp && tar xzf *.tar.gz` (or `unzip *.whl`) | `/tmp/<name>-<version>/` |
    | GitHub source | `git clone --depth 1 <repo-url> /tmp/audit-target/` | `/tmp/audit-target/` |
    | MCP server | Check MCP config for install path; if not installed yet, clone from source | Source directory |
    
    **Why not just install?** Install scripts (`postinstall`, `setup.py`) can execute arbitrary code β€” that's exactly what we're trying to audit. Always get source without running install hooks.
    
    ### Package Name
    
    Use the **exact package name** (e.g., `mcp-server-fetch`, not `mcp-fetch`). You can verify known packages via `/api/health` (shows total counts) or check `/api/findings?package=<name>` β€” if `total > 0`, the package exists in the registry.
    
    ### Finding IDs in API URLs
    
    When using `/api/findings/:ecap_id/review` or `/api/findings/:ecap_id/fix`, use the **`ecap_id` string** (e.g., `ECAP-2026-0777`) from the findings response. The numeric `id` field does **NOT** work for API routing.
    
    ---
    
    ## πŸ” Manual Audit
    
    
    
    ... (truncated)