General
ecap-security-auditor
Security audit framework for AI agent skills
---
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)
general
By
Comments
Sign in to leave a comment