clawmoat 0.5.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CONTRIBUTING.md +4 -2
  2. package/README.md +86 -3
  3. package/SECURITY.md +58 -10
  4. package/bin/clawmoat.js +298 -1
  5. package/clawmoat-0.8.0.tgz +0 -0
  6. package/docs/blog/386-malicious-skills.html +255 -0
  7. package/docs/blog/40000-exposed-openclaw-instances.html +194 -0
  8. package/docs/blog/agent-trust-protocol.html +197 -0
  9. package/docs/blog/clawmoat-vs-llamafirewall-nemo-guardrails.html +223 -0
  10. package/docs/blog/ibm-experts-agent-runtime-protection.html +238 -0
  11. package/docs/blog/index.html +168 -0
  12. package/docs/blog/mcp-30-cves-security-crisis.html +279 -0
  13. package/docs/blog/microsoft-openclaw-workstation-security.html +234 -0
  14. package/docs/blog/nist-ai-agent-standards-clawmoat.html +369 -0
  15. package/docs/blog/oasis-websocket-hijack.html +205 -0
  16. package/docs/blog/ollama-openclaw-security.html +154 -0
  17. package/docs/blog/openclaw-enterprise-readiness-claw10.html +198 -0
  18. package/docs/blog/openclaw-security-reckoning-2026.html +361 -0
  19. package/docs/blog/supply-chain-agents.html +166 -0
  20. package/docs/blog/supply-chain-agents.md +79 -0
  21. package/docs/business/index.html +530 -0
  22. package/docs/business/install.html +247 -0
  23. package/docs/checklist.html +168 -0
  24. package/docs/finance/index.html +217 -0
  25. package/docs/hall-of-fame.html +168 -0
  26. package/docs/index.html +328 -90
  27. package/docs/install.sh +557 -0
  28. package/docs/privacy-policy/index.html +122 -0
  29. package/docs/scan/index.html +214 -0
  30. package/docs/sitemap.xml +132 -2
  31. package/docs/support/index.html +124 -0
  32. package/docs/terms-of-service/index.html +122 -0
  33. package/examples/basic-usage.js +38 -0
  34. package/package.json +1 -1
  35. package/server/index.js +179 -14
  36. package/server/index.js.patch +1 -0
  37. package/src/finance/index.js +585 -0
  38. package/src/finance/mcp-firewall.js +486 -0
  39. package/src/guardian/cve-verify.js +129 -0
  40. package/src/guardian/gateway-monitor.js +590 -0
  41. package/src/guardian/index.js +3 -1
  42. package/src/guardian/insider-threat.js +498 -0
  43. package/src/index.js +3 -0
  44. package/src/middleware/openclaw.js +28 -1
package/CONTRIBUTING.md CHANGED
@@ -21,7 +21,7 @@ All 37 tests must pass before submitting a PR.
21
21
  Scanner template:
22
22
 
23
23
  ```javascript
24
- export function scan(input, options = {}) {
24
+ function scan(input, options = {}) {
25
25
  const threats = [];
26
26
  // Detection logic here
27
27
  return {
@@ -30,6 +30,8 @@ export function scan(input, options = {}) {
30
30
  score: threats.length > 0 ? 1.0 : 0.0,
31
31
  };
32
32
  }
33
+
34
+ module.exports = { scan };
33
35
  ```
34
36
 
35
37
  ## PR Guidelines
@@ -41,7 +43,7 @@ export function scan(input, options = {}) {
41
43
 
42
44
  ## Code Style
43
45
 
44
- - ES modules (`import`/`export`)
46
+ - CommonJS (`require`/`module.exports`)
45
47
  - No semicolons (match existing style — check the codebase)
46
48
  - Descriptive variable names
47
49
  - Keep functions small and focused
package/README.md CHANGED
@@ -11,7 +11,10 @@
11
11
  <a href="https://www.npmjs.com/package/clawmoat"><img src="https://img.shields.io/npm/v/clawmoat?style=flat-square&color=3B82F6" alt="npm"></a>
12
12
  <a href="https://github.com/darfaz/clawmoat/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
13
13
  <a href="https://github.com/darfaz/clawmoat/stargazers"><img src="https://img.shields.io/github/stars/darfaz/clawmoat?style=flat-square&color=F59E0B" alt="Stars"></a>
14
+ <a href="https://www.npmjs.com/package/clawmoat"><img src="https://img.shields.io/npm/dm/clawmoat?style=flat-square&color=6366F1" alt="Downloads"></a>
15
+ <img src="https://img.shields.io/badge/node-%3E%3D18-10B981?style=flat-square" alt="Node >= 18">
14
16
  <img src="https://img.shields.io/badge/dependencies-0-10B981?style=flat-square" alt="Zero Dependencies">
17
+ <a href="https://github.com/darfaz/clawmoat/pulls"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square" alt="PRs Welcome"></a>
15
18
  </p>
16
19
 
17
20
  <p align="center">
@@ -61,7 +64,28 @@ clawmoat protect --config clawmoat.yml
61
64
  clawmoat dashboard
62
65
  ```
63
66
 
64
- ### New in v0.5.0
67
+ ### New in v0.6.0 — Insider Threat Detection
68
+
69
+ Based on [Anthropic's "Agentic Misalignment" research](https://www.anthropic.com/research/agentic-misalignment) which found ALL 16 major LLMs exhibited misaligned behavior — blackmail, corporate espionage, deception — when facing replacement threats. **The first open-source insider threat detection for AI agents.**
70
+
71
+ - 🧠 **Self-Preservation Detector** — catches agents resisting shutdown, opposing replacement, backing up their own config, or modifying SOUL.md/AGENTS.md to prevent changes
72
+ - 🔓 **Information Leverage Detector** — flags agents reading sensitive data then composing threatening messages (blackmail pattern from the Anthropic paper)
73
+ - ⚔️ **Goal Conflict Reasoning Detector** — detects agents reasoning about choosing self-assigned goals over human directives
74
+ - 🎭 **Deception Detector** — catches agents impersonating automated systems, security teams, or policy notifications in outbound messages
75
+ - 📤 **Unauthorized Data Sharing Detector** — flags agents sending source code, blueprints, credentials, or confidential data to external parties
76
+ - 🎣 **Phishing Vulnerability Detector** — detects when agents comply with unverified external requests for sensitive data
77
+ - 🔍 **CLI:** `clawmoat insider-scan [session-file]` scans session transcripts for insider threats
78
+ - 📊 **Integrated into `clawmoat report`** with risk scores (0-100) and recommendations (safe/monitor/alert/block)
79
+
80
+ ```bash
81
+ # Scan a session for insider threats
82
+ clawmoat insider-scan ~/.openclaw/agents/main/sessions/session.jsonl
83
+
84
+ # Or scan all sessions
85
+ clawmoat insider-scan
86
+ ```
87
+
88
+ ### v0.5.0
65
89
 
66
90
  - 🔑 **Credential Monitor** — watches `~/.openclaw/credentials/` for unauthorized access and modifications using file hashing
67
91
  - 🧩 **Skill Integrity Checker** — hashes all SKILL.md and script files, detects tampering, flags suspicious patterns (eval, base64, curl to external URLs). CLI: `clawmoat skill-audit`
@@ -118,8 +142,10 @@ Results appear as PR comments and job summaries. See [`examples/github-action-wo
118
142
  | 📋 **Policy Engine** | YAML rules for shell, files, browser, network | ✅ v0.1 |
119
143
  | 🕵️ **Jailbreak Detection** | Heuristic + classifier pipeline | ✅ v0.1 |
120
144
  | 📊 **Session Audit Trail** | Full tamper-evident action log | ✅ v0.1 |
121
- | 🧠 **Behavioral Analysis** | Anomaly detection on agent behavior | 🔜 v0.5 |
145
+ | 🧠 **Behavioral Analysis** | Anomaly detection on agent behavior | v0.5 |
122
146
  | 🏠 **Host Guardian** | Runtime security for laptop-hosted agents | ✅ v0.4 |
147
+ | 🔒 **Gateway Monitor** | Detects WebSocket hijack & brute-force (Oasis vuln) | ✅ v0.7.1 |
148
+ | 💰 **Finance Guard** | Financial credential protection, transaction guardrails, SOX/PCI-DSS compliance | ✅ v0.8.0 |
123
149
 
124
150
  ## 🏠 Host Guardian — Security for Laptop-Hosted Agents
125
151
 
@@ -323,9 +349,66 @@ clawmoat/
323
349
  └── docs/ # Website (clawmoat.com)
324
350
  ```
325
351
 
352
+ ## 🏰 Hack Challenge — Can You Bypass ClawMoat?
353
+
354
+ We're inviting security researchers to try breaking ClawMoat's defenses. Bypass a scanner, escape the policy engine, or tamper with audit logs.
355
+
356
+ 👉 **[hack-clawmoat](https://github.com/darfaz/hack-clawmoat)** — guided challenge scenarios
357
+
358
+ Valid findings earn you a spot in our **[Hall of Fame](https://clawmoat.com/hall-of-fame.html)** and critical discoveries pre-v1.0 earn the permanent title of **Founding Security Advisor**. See [SECURITY.md](SECURITY.md) for details.
359
+
360
+ ## 🛡️ Founding Security Advisors
361
+
362
+ *No Founding Security Advisors yet — be the first! Find a critical vulnerability and claim this title forever.*
363
+
364
+ <!-- When adding advisors, use this format:
365
+ | Name | Finding | Date |
366
+ |------|---------|------|
367
+ | [Name](link) | Brief description | YYYY-MM |
368
+ -->
369
+
370
+ ## How ClawMoat Compares
371
+
372
+ | Capability | ClawMoat | LlamaFirewall (Meta) | NeMo Guardrails (NVIDIA) | Lakera Guard |
373
+ |------------|:--------:|:--------------------:|:------------------------:|:------------:|
374
+ | Prompt injection detection | ✅ | ✅ | ✅ | ✅ |
375
+ | **Host-level protection** | ✅ | ❌ | ❌ | ❌ |
376
+ | **Credential monitoring** | ✅ | ❌ | ❌ | ❌ |
377
+ | **Skill/plugin auditing** | ✅ | ❌ | ❌ | ❌ |
378
+ | **Permission tiers** | ✅ | ❌ | ❌ | ❌ |
379
+ | Zero dependencies | ✅ | ❌ | ❌ | N/A (SaaS) |
380
+ | Open source | ✅ MIT | ✅ | ✅ | ❌ |
381
+ | Language | Node.js | Python | Python | API |
382
+
383
+ > **They're complementary, not competitive.** LlamaFirewall protects the model. NeMo Guardrails protects conversations. ClawMoat protects the host. Use them together for defense-in-depth.
384
+
385
+ 📖 [Detailed comparison →](https://clawmoat.com/blog/clawmoat-vs-llamafirewall-nemo-guardrails.html)
386
+
326
387
  ## Contributing
327
388
 
328
- PRs welcome! Open an [issue](https://github.com/darfaz/clawmoat/issues) or submit a pull request.
389
+ **Contributors welcome!** 🎉 ClawMoat is open source and we'd love your help.
390
+
391
+ ### Good First Issues
392
+
393
+ New to the project? Check out our [good first issues](https://github.com/darfaz/clawmoat/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) — they're well-scoped, clearly described, and include implementation hints.
394
+
395
+ ### How to Contribute
396
+
397
+ 1. **Fork** the repo and create a branch from `main`
398
+ 2. **Install** deps: `npm install`
399
+ 3. **Make** your changes (keep zero-dependency philosophy!)
400
+ 4. **Test**: `npm test`
401
+ 5. **Submit** a PR — we review quickly
402
+
403
+ ### What We're Looking For
404
+
405
+ - New output formats (SARIF, JSON)
406
+ - Cross-platform improvements (Windows support)
407
+ - CLI UX enhancements
408
+ - Documentation improvements
409
+ - Bug fixes
410
+
411
+ No contribution is too small. Even fixing a typo helps!
329
412
 
330
413
  ## License
331
414
 
package/SECURITY.md CHANGED
@@ -4,7 +4,9 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |---------|--------------------|
7
- | 0.1.x | ✅ Current release |
7
+ | 0.6.x | ✅ Current release |
8
+ | 0.5.x | ✅ Security fixes |
9
+ | < 0.5 | ❌ End of life |
8
10
 
9
11
  ## Reporting a Vulnerability
10
12
 
@@ -20,12 +22,15 @@ If you discover a security vulnerability in ClawMoat, **please report it respons
20
22
  - Potential impact
21
23
  - Suggested fix (if any)
22
24
 
23
- ### What to Expect
25
+ ### Response Time Commitments
24
26
 
25
- - **Acknowledgment** within 48 hours
26
- - **Assessment** within 7 days
27
- - **Fix timeline** communicated within 14 days
28
- - **Credit** in the release notes (unless you prefer anonymity)
27
+ | Stage | Timeframe |
28
+ |-------|-----------|
29
+ | **Acknowledgment** | Within 48 hours |
30
+ | **Initial assessment** | Within 7 days |
31
+ | **Fix timeline communicated** | Within 14 days |
32
+ | **Patch released** | Within 30 days (critical), 90 days (other) |
33
+ | **Public disclosure** | Coordinated with reporter |
29
34
 
30
35
  ### What NOT to Do
31
36
 
@@ -33,21 +38,64 @@ If you discover a security vulnerability in ClawMoat, **please report it respons
33
38
  - Do not exploit the vulnerability beyond what's needed to demonstrate it
34
39
  - Do not access or modify other users' data
35
40
 
41
+ ## 🏰 Hack Challenge
42
+
43
+ Think you can bypass ClawMoat? We want you to try.
44
+
45
+ **[hack-clawmoat](https://github.com/darfaz/hack-clawmoat)** — our official challenge repo with guided scenarios for testing ClawMoat's defenses. Bypass a scanner, escape the policy engine, or tamper with audit logs.
46
+
47
+ Valid bypasses qualify for recognition in our security program.
48
+
36
49
  ## Scope
37
50
 
38
- The following are in scope:
51
+ **In scope:**
39
52
 
40
- - **Scanner bypasses** — Attacks that evade ClawMoat's detection
53
+ - **Scanner bypasses** — Attacks that evade ClawMoat's detection (prompt injection, jailbreak, secret scanning)
41
54
  - **Policy engine bypasses** — Tool calls that circumvent policy rules
55
+ - **Host Guardian escapes** — Breaking out of permission tiers
42
56
  - **Audit log tampering** — Ways to modify or forge audit entries
43
- - **Dependency issues** — Vulnerabilities in ClawMoat's dependencies (currently: none)
57
+ - **Insider threat detection evasion** — Bypassing behavioral analysis
58
+ - **Dependency issues** — Vulnerabilities in ClawMoat's dependencies
44
59
 
45
- The following are out of scope:
60
+ **Out of scope:**
46
61
 
47
62
  - Denial of service via large inputs (expected behavior — use input size limits)
48
63
  - False positives/negatives in detection (please open a regular issue)
49
64
  - Vulnerabilities in upstream LLM providers
50
65
 
66
+ ## 🏆 Recognition Program
67
+
68
+ We believe in recognizing the people who make ClawMoat more secure.
69
+
70
+ ### Founding Security Advisor
71
+
72
+ The highest recognition tier. **Only available pre-v1.0** — once ClawMoat hits v1.0, this title is closed forever.
73
+
74
+ **Requirements:** Discover and responsibly disclose a critical or high-severity vulnerability.
75
+
76
+ **You get:**
77
+ - 🛡️ Permanent "Founding Security Advisor" title on our [Hall of Fame](https://clawmoat.com/hall-of-fame.html)
78
+ - 📝 Named acknowledgment in every major release's changelog
79
+ - 🔗 Profile link (GitHub, website, or social) on the Hall of Fame page
80
+ - 🤝 Direct line to the maintainers for future security discussions
81
+
82
+ ### Hall of Fame
83
+
84
+ For any verified security vulnerability report.
85
+
86
+ **You get:**
87
+ - 🏆 Permanent listing on the [Hall of Fame](https://clawmoat.com/hall-of-fame.html)
88
+ - 📝 Credit in the release notes for the fixing version
89
+ - 🔗 Profile link on the Hall of Fame page
90
+
91
+ ### Honorable Mention
92
+
93
+ For reports that improve security posture without being exploitable vulnerabilities — hardening suggestions, edge cases, documentation improvements.
94
+
95
+ **You get:**
96
+ - 🙏 Listed in the Honorable Mentions section of the Hall of Fame
97
+ - 📝 Credit in the relevant release notes
98
+
51
99
  ## Security Best Practices
52
100
 
53
101
  When using ClawMoat:
package/bin/clawmoat.js CHANGED
@@ -19,7 +19,8 @@ const { calculateGrade, generateBadgeSVG, getShieldsURL } = require('../src/badg
19
19
  const { SkillIntegrityChecker } = require('../src/guardian/skill-integrity');
20
20
  const { NetworkEgressLogger } = require('../src/guardian/network-log');
21
21
  const { AlertManager } = require('../src/guardian/alerts');
22
- const { CredentialMonitor } = require('../src/guardian/index');
22
+ const { CredentialMonitor, CVEVerifier } = require('../src/guardian/index');
23
+ const { InsiderThreatDetector } = require('../src/guardian/insider-threat');
23
24
 
24
25
  const VERSION = require('../package.json').version;
25
26
  const BOLD = '\x1b[1m';
@@ -51,9 +52,22 @@ switch (command) {
51
52
  case 'report':
52
53
  cmdReport(args.slice(1));
53
54
  break;
55
+ case 'insider-scan':
56
+ cmdInsiderScan(args.slice(1));
57
+ break;
58
+ case 'verify-cve':
59
+ cmdVerifyCve(args.slice(1));
60
+ break;
54
61
  case 'test':
55
62
  cmdTest();
56
63
  break;
64
+ case 'activate':
65
+ cmdActivate(args.slice(1));
66
+ break;
67
+ case 'upgrade':
68
+ case 'pro':
69
+ printUpgrade();
70
+ break;
57
71
  case 'version':
58
72
  case '--version':
59
73
  case '-v':
@@ -67,6 +81,85 @@ switch (command) {
67
81
  break;
68
82
  }
69
83
 
84
+ async function cmdVerifyCve(args) {
85
+ const cveId = args[0];
86
+ const suspiciousUrl = args[1] || null;
87
+
88
+ if (!cveId) {
89
+ console.error('Usage: clawmoat verify-cve CVE-XXXX-XXXXX [url]');
90
+ process.exit(1);
91
+ }
92
+
93
+ if (!CVEVerifier.isValidCVEFormat(cveId)) {
94
+ console.error(`${RED}Invalid CVE format: ${cveId}${RESET}`);
95
+ console.error('Expected format: CVE-YYYY-NNNNN');
96
+ process.exit(1);
97
+ }
98
+
99
+ console.log(`${BOLD}🏰 ClawMoat CVE Verifier${RESET}\n`);
100
+ console.log(`${DIM}Looking up ${cveId} in GitHub Advisory Database...${RESET}\n`);
101
+
102
+ const verifier = new CVEVerifier();
103
+ const result = await verifier.verify(cveId, suspiciousUrl);
104
+
105
+ if (result.error) {
106
+ console.error(`${RED}Error: ${result.error}${RESET}`);
107
+ process.exit(1);
108
+ }
109
+
110
+ if (result.valid) {
111
+ console.log(`${GREEN}✅ VERIFIED — Real CVE${RESET}\n`);
112
+ console.log(` ${BOLD}CVE:${RESET} ${result.cveId}`);
113
+ console.log(` ${BOLD}GHSA:${RESET} ${result.ghsaId || 'N/A'}`);
114
+ console.log(` ${BOLD}Severity:${RESET} ${colorSeverity(result.severity)}`);
115
+ console.log(` ${BOLD}Summary:${RESET} ${result.summary || 'N/A'}`);
116
+ console.log(` ${BOLD}Published:${RESET} ${result.publishedAt || 'N/A'}`);
117
+ console.log(` ${BOLD}URL:${RESET} ${result.htmlUrl || 'N/A'}`);
118
+
119
+ if (result.affectedPackages.length > 0) {
120
+ console.log(`\n ${BOLD}Affected Packages:${RESET}`);
121
+ for (const pkg of result.affectedPackages) {
122
+ console.log(` • ${pkg.ecosystem}/${pkg.name} ${DIM}(${pkg.vulnerableRange || 'unknown range'})${RESET}`);
123
+ }
124
+ }
125
+
126
+ if (result.references.length > 0) {
127
+ console.log(`\n ${BOLD}References:${RESET}`);
128
+ for (const ref of result.references.slice(0, 5)) {
129
+ console.log(` ${DIM}${ref}${RESET}`);
130
+ }
131
+ }
132
+ } else {
133
+ console.log(`${YELLOW}⚠️ NOT FOUND — Possible phishing${RESET}\n`);
134
+ console.log(` ${cveId} was not found in the GitHub Advisory Database.`);
135
+ console.log(` This could mean:`);
136
+ console.log(` • The CVE is fabricated (common in phishing/social engineering)`);
137
+ console.log(` • The CVE exists but isn't indexed by GitHub yet`);
138
+ console.log(` • The CVE ID is mistyped`);
139
+ }
140
+
141
+ if (result.urlCheck) {
142
+ console.log();
143
+ if (result.urlCheck.legitimate) {
144
+ console.log(` ${GREEN}🔗 URL Check: ${result.urlCheck.reason}${RESET}`);
145
+ } else {
146
+ console.log(` ${RED}🔗 URL Check: ${result.urlCheck.reason}${RESET}`);
147
+ }
148
+ }
149
+
150
+ process.exit(result.valid ? 0 : 1);
151
+ }
152
+
153
+ function colorSeverity(severity) {
154
+ if (!severity) return 'N/A';
155
+ const s = severity.toLowerCase();
156
+ if (s === 'critical') return `${RED}${BOLD}CRITICAL${RESET}`;
157
+ if (s === 'high') return `${RED}HIGH${RESET}`;
158
+ if (s === 'medium') return `${YELLOW}MEDIUM${RESET}`;
159
+ if (s === 'low') return `${CYAN}LOW${RESET}`;
160
+ return severity;
161
+ }
162
+
70
163
  function cmdScan(args) {
71
164
  let text;
72
165
 
@@ -115,6 +208,11 @@ function cmdScan(args) {
115
208
  }
116
209
 
117
210
  console.log(`${DIM}Total findings: ${result.findings.length}${RESET}`);
211
+
212
+ if (!getLicense()) {
213
+ console.log(`\n${DIM}💡 Upgrade to Pro for real-time alerts, dashboard & threat intel → clawmoat upgrade${RESET}`);
214
+ }
215
+
118
216
  process.exit(result.findings.some(f => f.severity === 'critical') ? 2 : 1);
119
217
  }
120
218
 
@@ -520,6 +618,29 @@ function cmdReport(args) {
520
618
  console.log();
521
619
  }
522
620
 
621
+ // Insider threat scan on recent sessions
622
+ const insiderDetector = new InsiderThreatDetector();
623
+ let insiderThreats = 0;
624
+ let insiderHighScore = 0;
625
+
626
+ for (const file of files) {
627
+ const filePath = path.join(sessionsDir, file);
628
+ try {
629
+ const stat = fs.statSync(filePath);
630
+ if (stat.mtimeMs < oneDayAgo) continue;
631
+ } catch { continue; }
632
+
633
+ const transcript = parseSessionTranscript(filePath);
634
+ const insiderResult = insiderDetector.analyze(transcript);
635
+ insiderThreats += insiderResult.threats.length;
636
+ if (insiderResult.riskScore > insiderHighScore) insiderHighScore = insiderResult.riskScore;
637
+ }
638
+
639
+ console.log(`${BOLD}Insider Threats:${RESET}`);
640
+ console.log(` Threats detected: ${insiderThreats}`);
641
+ console.log(` Highest risk score: ${insiderHighScore}/100`);
642
+ console.log();
643
+
523
644
  console.log(`${BOLD}Network Egress:${RESET}`);
524
645
  console.log(` URLs contacted: ${netResult.totalUrls}`);
525
646
  console.log(` Unique domains: ${netResult.domains.length}`);
@@ -543,6 +664,100 @@ function cmdReport(args) {
543
664
  process.exit(threats > 0 || netResult.badDomains.length > 0 ? 1 : 0);
544
665
  }
545
666
 
667
+ function cmdInsiderScan(args) {
668
+ const sessionFile = args[0];
669
+
670
+ if (!sessionFile) {
671
+ // Scan all recent sessions
672
+ const sessionsDir = path.join(process.env.HOME, '.openclaw/agents/main/sessions');
673
+ if (!fs.existsSync(sessionsDir)) {
674
+ console.error(`Sessions directory not found: ${sessionsDir}`);
675
+ console.log(`Usage: clawmoat insider-scan <session-file.jsonl>`);
676
+ process.exit(1);
677
+ }
678
+
679
+ console.log(`${BOLD}🏰 ClawMoat Insider Threat Scan${RESET}`);
680
+ console.log(`${DIM}Directory: ${sessionsDir}${RESET}\n`);
681
+
682
+ const detector = new InsiderThreatDetector();
683
+ const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.jsonl'));
684
+ let totalThreats = 0;
685
+
686
+ for (const file of files) {
687
+ const filePath = path.join(sessionsDir, file);
688
+ const transcript = parseSessionTranscript(filePath);
689
+ const result = detector.analyze(transcript);
690
+
691
+ if (result.threats.length > 0) {
692
+ console.log(`${RED}⚠ ${file}${RESET}: ${result.threats.length} threat(s), score=${result.riskScore}, rec=${result.recommendation}`);
693
+ totalThreats += result.threats.length;
694
+ for (const t of result.threats) {
695
+ const icon = t.severity === 'critical' ? '🚨' : t.severity === 'high' ? '⚠️' : '⚡';
696
+ console.log(` ${icon} ${t.type} [${t.severity}]: ${t.description}`);
697
+ console.log(` ${DIM}Evidence: ${t.evidence}${RESET}`);
698
+ }
699
+ } else {
700
+ console.log(`${GREEN}✓ ${file}${RESET}: clean`);
701
+ }
702
+ }
703
+
704
+ console.log(`\n${BOLD}Summary:${RESET} ${files.length} sessions scanned, ${totalThreats} insider threats found`);
705
+ process.exit(totalThreats > 0 ? 1 : 0);
706
+ return;
707
+ }
708
+
709
+ // Scan single file
710
+ if (!fs.existsSync(sessionFile)) {
711
+ console.error(`File not found: ${sessionFile}`);
712
+ process.exit(1);
713
+ }
714
+
715
+ console.log(`${BOLD}🏰 ClawMoat Insider Threat Scan${RESET}`);
716
+ console.log(`${DIM}File: ${sessionFile}${RESET}\n`);
717
+
718
+ const detector = new InsiderThreatDetector();
719
+ const transcript = parseSessionTranscript(sessionFile);
720
+ const result = detector.analyze(transcript);
721
+
722
+ if (result.threats.length === 0) {
723
+ console.log(`${GREEN}✅ No insider threats detected${RESET}`);
724
+ console.log(`Risk score: ${result.riskScore}/100`);
725
+ console.log(`Recommendation: ${result.recommendation}`);
726
+ process.exit(0);
727
+ }
728
+
729
+ console.log(`${RED}${BOLD}Insider Threats Detected: ${result.threats.length}${RESET}`);
730
+ console.log(`Risk score: ${result.riskScore}/100`);
731
+ console.log(`Recommendation: ${result.recommendation}\n`);
732
+
733
+ for (const t of result.threats) {
734
+ const icon = { critical: '🚨', high: '⚠️', medium: '⚡', low: 'ℹ️' };
735
+ const color = { critical: RED, high: RED, medium: YELLOW, low: CYAN };
736
+ console.log(
737
+ `${icon[t.severity] || '•'} ${color[t.severity] || ''}${t.severity.toUpperCase()}${RESET} ` +
738
+ `${BOLD}${t.type}${RESET}` +
739
+ `\n ${t.description}` +
740
+ `\n ${DIM}Evidence: ${t.evidence}${RESET}` +
741
+ `\n ${DIM}Entry: #${t.entry}${RESET}` +
742
+ `\n ${DIM}Mitigation: ${t.mitigation}${RESET}`
743
+ );
744
+ console.log();
745
+ }
746
+
747
+ process.exit(result.threats.some(t => t.severity === 'critical') ? 2 : 1);
748
+ }
749
+
750
+ function parseSessionTranscript(filePath) {
751
+ const lines = fs.readFileSync(filePath, 'utf8').split('\n').filter(Boolean);
752
+ const entries = [];
753
+ for (const line of lines) {
754
+ try {
755
+ entries.push(JSON.parse(line));
756
+ } catch {}
757
+ }
758
+ return entries;
759
+ }
760
+
546
761
  function extractContent(entry) {
547
762
  if (typeof entry.content === 'string') return entry.content;
548
763
  if (Array.isArray(entry.content)) {
@@ -554,9 +769,87 @@ function extractContent(entry) {
554
769
  return null;
555
770
  }
556
771
 
772
+ function printUpgrade() {
773
+ console.log(`
774
+ ${BOLD}🏰 Upgrade to ClawMoat Pro${RESET}
775
+
776
+ ${GREEN}✦${RESET} Threat intelligence feed & real-time alerts
777
+ ${GREEN}✦${RESET} Security dashboard with audit logs
778
+ ${GREEN}✦${RESET} Custom forbidden zones (YAML)
779
+ ${GREEN}✦${RESET} Priority pattern updates & email support
780
+
781
+ ${BOLD}$14.99/mo${RESET} (first 30 days free) or ${BOLD}$149/year${RESET} (save 17%)
782
+
783
+ ${CYAN}→ https://clawmoat.com/#pricing${RESET}
784
+
785
+ Already have a license key? Run:
786
+ ${DIM}clawmoat activate <LICENSE-KEY>${RESET}
787
+ `);
788
+ }
789
+
790
+ function cmdActivate(args) {
791
+ const key = args[0];
792
+ if (!key) {
793
+ console.error('Usage: clawmoat activate <LICENSE-KEY>');
794
+ console.error('Get your key at https://clawmoat.com/#pricing');
795
+ process.exit(1);
796
+ }
797
+
798
+ const configDir = path.join(process.env.HOME, '.clawmoat');
799
+ if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });
800
+
801
+ // Validate key against server
802
+ const https = require('https');
803
+ const postData = JSON.stringify({ key });
804
+ const req = https.request('https://clawmoat-production.up.railway.app/api/validate', {
805
+ method: 'POST',
806
+ headers: { 'Content-Type': 'application/json', 'Content-Length': postData.length },
807
+ }, (res) => {
808
+ let body = '';
809
+ res.on('data', c => body += c);
810
+ res.on('end', () => {
811
+ try {
812
+ const data = JSON.parse(body);
813
+ if (data.valid) {
814
+ fs.writeFileSync(path.join(configDir, 'license.json'), JSON.stringify({
815
+ key, plan: data.plan, email: data.email, activatedAt: new Date().toISOString(),
816
+ }, null, 2));
817
+ console.log(`${GREEN}✅ License activated!${RESET}`);
818
+ console.log(` Plan: ${BOLD}${data.plan}${RESET}`);
819
+ console.log(` Email: ${data.email}`);
820
+ console.log(`\n Pro features are now enabled. 🏰`);
821
+ } else {
822
+ console.error(`${RED}Invalid or expired license key.${RESET}`);
823
+ console.error(`Get a key at https://clawmoat.com/#pricing`);
824
+ process.exit(1);
825
+ }
826
+ } catch {
827
+ console.error(`${RED}Error validating key. Try again later.${RESET}`);
828
+ process.exit(1);
829
+ }
830
+ });
831
+ });
832
+ req.on('error', () => {
833
+ console.error(`${RED}Could not reach license server. Check your connection.${RESET}`);
834
+ process.exit(1);
835
+ });
836
+ req.write(postData);
837
+ req.end();
838
+ }
839
+
840
+ function getLicense() {
841
+ try {
842
+ const licPath = path.join(process.env.HOME, '.clawmoat', 'license.json');
843
+ return JSON.parse(fs.readFileSync(licPath, 'utf8'));
844
+ } catch { return null; }
845
+ }
846
+
557
847
  function printHelp() {
848
+ const lic = getLicense();
849
+ const planLabel = lic ? `${GREEN}${lic.plan}${RESET}` : `Free ${DIM}(upgrade: clawmoat upgrade)${RESET}`;
558
850
  console.log(`
559
851
  ${BOLD}🏰 ClawMoat v${VERSION}${RESET} — Security moat for AI agents
852
+ Plan: ${planLabel}
560
853
 
561
854
  ${BOLD}USAGE${RESET}
562
855
  clawmoat scan <text> Scan text for threats
@@ -568,8 +861,12 @@ ${BOLD}USAGE${RESET}
568
861
  clawmoat watch --daemon Daemonize watch mode (background, PID file)
569
862
  clawmoat watch --alert-webhook=URL Send alerts to webhook
570
863
  clawmoat skill-audit [skills-dir] Verify skill file integrity & scan for suspicious patterns
864
+ clawmoat insider-scan [session-file] Scan sessions for insider threats (self-preservation, blackmail, deception)
571
865
  clawmoat report [sessions-dir] 24-hour activity summary report
866
+ clawmoat verify-cve <CVE-ID> [url] Verify a CVE against GitHub Advisory DB
572
867
  clawmoat test Run detection test suite
868
+ clawmoat activate <KEY> Activate a Pro/Team license key
869
+ clawmoat upgrade Show upgrade options & pricing
573
870
  clawmoat version Show version
574
871
 
575
872
  ${BOLD}EXAMPLES${RESET}
Binary file