clawmoat 0.8.0 → 1.0.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 (171) hide show
  1. package/.dockerignore +9 -0
  2. package/CHANGELOG.md +18 -0
  3. package/DEMO.md +87 -0
  4. package/Dockerfile +5 -18
  5. package/README.md +232 -8
  6. package/THREAT_MODEL.md +129 -0
  7. package/agent/README.md +131 -0
  8. package/agent/index.js +471 -0
  9. package/agent/install-service.sh +94 -0
  10. package/agent/openclaw-hook.js +453 -0
  11. package/agent/provider-setup.js +649 -0
  12. package/agent/setup.js +274 -0
  13. package/assets/BADGE-USAGE.md +20 -0
  14. package/assets/clawmoat-badge.svg +21 -0
  15. package/bin/clawmoat.js +468 -111
  16. package/docs/affiliates/dashboard.html +124 -0
  17. package/docs/affiliates/index.html +236 -0
  18. package/docs/agent-install.html +183 -0
  19. package/docs/ai-agent-security-scanner.html +10 -6
  20. package/docs/badge/index.html +149 -0
  21. package/docs/badge/scanning.svg +23 -0
  22. package/docs/blog/386-malicious-skills.html +11 -4
  23. package/docs/blog/40000-exposed-openclaw-instances.html +11 -4
  24. package/docs/blog/agent-trust-protocol.html +5 -4
  25. package/docs/blog/ai-agent-earns-commissions.html +230 -0
  26. package/docs/blog/bugmageddon-agent-firewall.html +174 -0
  27. package/docs/blog/calculator-math.html +180 -0
  28. package/docs/blog/clawmoat-vs-llamafirewall-nemo-guardrails.html +10 -4
  29. package/docs/blog/host-guardian-launch.html +18 -8
  30. package/docs/blog/ibm-experts-agent-runtime-protection.html +15 -6
  31. package/docs/blog/index.html +67 -9
  32. package/docs/blog/langchain-security-tutorial.html +18 -8
  33. package/docs/blog/mcp-30-cves-security-crisis.html +11 -4
  34. package/docs/blog/meta-researcher-rogue-agent.html +201 -0
  35. package/docs/blog/microsoft-openclaw-workstation-security.html +5 -4
  36. package/docs/blog/nist-ai-agent-standards-clawmoat.html +16 -8
  37. package/docs/blog/oasis-websocket-hijack.html +11 -4
  38. package/docs/blog/ollama-openclaw-security.html +10 -4
  39. package/docs/blog/openclaw-enterprise-readiness-claw10.html +5 -4
  40. package/docs/blog/openclaw-security-reckoning-2026.html +11 -4
  41. package/docs/blog/owasp-agentic-ai-top10.html +18 -8
  42. package/docs/blog/securing-ai-agents.html +18 -8
  43. package/docs/blog/supply-chain-agents.html +18 -8
  44. package/docs/business/index.html +11 -16
  45. package/docs/business/install.html +21 -7
  46. package/docs/checklist.html +10 -4
  47. package/docs/compare/index.html +122 -0
  48. package/docs/compare/lakera/index.html +62 -0
  49. package/docs/compare/llm-guard/index.html +49 -0
  50. package/docs/compare/snyk-agent-scan/index.html +63 -0
  51. package/docs/compare.html +10 -6
  52. package/docs/dashboard/index.html +520 -0
  53. package/docs/finance/index.html +9 -6
  54. package/docs/guides/business-deployment.html +770 -0
  55. package/docs/hall-of-fame.html +11 -5
  56. package/docs/index.html +266 -137
  57. package/docs/integrations/langchain.html +14 -6
  58. package/docs/integrations/openai.html +14 -6
  59. package/docs/integrations/openclaw.html +55 -7
  60. package/docs/plans/2026-03-26-threat-intel-api.md +255 -0
  61. package/docs/plans/2026-04-14-bugmageddon-marketing-pack.md +329 -0
  62. package/docs/plans/2026-04-14-clawmoat-v1-bugmageddon.md +248 -0
  63. package/docs/plans/2026-04-14-v1-release-update.md +91 -0
  64. package/docs/plans/2026-04-19-supabase-audit.md +68 -0
  65. package/docs/plans/2026-05-12-sales-push.md +303 -0
  66. package/docs/playground/index.html +893 -0
  67. package/docs/playground.html +4 -7
  68. package/docs/rfcs/defense-in-depth.md +467 -0
  69. package/docs/scan/index.html +156 -12
  70. package/docs/services/case-study.html +255 -0
  71. package/docs/services/downloads/install-openclaw.bat +45 -0
  72. package/docs/services/downloads/install-openclaw.command +38 -0
  73. package/docs/services/downloads/install-openclaw.sh +38 -0
  74. package/docs/services/get-started.html +165 -0
  75. package/docs/services/index.html +598 -0
  76. package/docs/services/multi-agent-security.html +284 -0
  77. package/docs/services/one-pager.html +99 -0
  78. package/docs/services/pitch-deck.html +229 -0
  79. package/docs/services/roi-calculator.html +258 -0
  80. package/docs/sitemap.xml +62 -2
  81. package/docs/support/index.html +12 -1
  82. package/docs/templates/customer-service/HEARTBEAT.md +61 -0
  83. package/docs/templates/customer-service/MEMORY.md +89 -0
  84. package/docs/templates/customer-service/SOUL.md +41 -0
  85. package/docs/templates/customer-service/USER.md +56 -0
  86. package/docs/templates/executive/HEARTBEAT.md +86 -0
  87. package/docs/templates/executive/MEMORY.md +92 -0
  88. package/docs/templates/executive/SOUL.md +44 -0
  89. package/docs/templates/executive/USER.md +62 -0
  90. package/docs/templates/finance/HEARTBEAT.md +58 -0
  91. package/docs/templates/finance/MEMORY.md +87 -0
  92. package/docs/templates/finance/SOUL.md +38 -0
  93. package/docs/templates/finance/USER.md +53 -0
  94. package/docs/templates/index.html +115 -0
  95. package/docs/templates/operations/HEARTBEAT.md +63 -0
  96. package/docs/templates/operations/MEMORY.md +68 -0
  97. package/docs/templates/operations/SOUL.md +38 -0
  98. package/docs/templates/operations/USER.md +49 -0
  99. package/docs/templates/sales/HEARTBEAT.md +55 -0
  100. package/docs/templates/sales/MEMORY.md +89 -0
  101. package/docs/templates/sales/SOUL.md +34 -0
  102. package/docs/templates/sales/USER.md +54 -0
  103. package/eslint.config.js +32 -0
  104. package/evals/README.md +29 -0
  105. package/evals/cases.json +390 -0
  106. package/evals/results.md +68 -0
  107. package/evals/run.js +180 -0
  108. package/examples/demo-attack/demo.js +186 -0
  109. package/examples/python-quickstart/README.md +54 -0
  110. package/examples/python-quickstart/clawmoat_client.py +167 -0
  111. package/examples/video-demo/README.md +14 -0
  112. package/examples/video-demo/scene-a-normal.js +29 -0
  113. package/examples/video-demo/scene-b-attack-arrives.js +31 -0
  114. package/examples/video-demo/scene-c-hijack.js +44 -0
  115. package/examples/video-demo/scene-d-clawmoat.js +46 -0
  116. package/integrations/crewai/README.md +32 -0
  117. package/integrations/crewai/clawmoat_crewai/__init__.py +17 -0
  118. package/integrations/crewai/clawmoat_crewai/guard.py +103 -0
  119. package/integrations/crewai/pyproject.toml +21 -0
  120. package/integrations/langchain/README.md +91 -0
  121. package/integrations/langchain/clawmoat_langchain/__init__.py +17 -0
  122. package/integrations/langchain/clawmoat_langchain/callback.py +489 -0
  123. package/integrations/langchain/pyproject.toml +32 -0
  124. package/integrations/litellm/README.md +324 -0
  125. package/integrations/litellm/clawmoat_litellm/__init__.py +21 -0
  126. package/integrations/litellm/clawmoat_litellm/callback.py +329 -0
  127. package/integrations/litellm/clawmoat_litellm/proxy_middleware.py +224 -0
  128. package/integrations/litellm/pyproject.toml +74 -0
  129. package/integrations/openai-agents/README.md +392 -0
  130. package/integrations/openai-agents/clawmoat_openai_agents/__init__.py +20 -0
  131. package/integrations/openai-agents/clawmoat_openai_agents/guardrail.py +431 -0
  132. package/integrations/openai-agents/clawmoat_openai_agents/middleware.py +311 -0
  133. package/integrations/openai-agents/pyproject.toml +76 -0
  134. package/package.json +6 -5
  135. package/plugins/openclaw-adapter/PHASE1.md +439 -0
  136. package/plugins/openclaw-adapter/README.md +103 -0
  137. package/plugins/openclaw-adapter/SPEC.md +1644 -0
  138. package/plugins/openclaw-adapter/package.json +31 -0
  139. package/plugins/openclaw-adapter/src/index.test.ts +226 -0
  140. package/plugins/openclaw-adapter/src/index.ts +140 -0
  141. package/plugins/openclaw-adapter/tsconfig.json +14 -0
  142. package/server/data/threats.json +290 -0
  143. package/server/index.js +142 -7
  144. package/src/adapters/express.js +161 -0
  145. package/src/adapters/index.js +92 -0
  146. package/src/adapters/langchain.js +185 -0
  147. package/src/approval/index.js +456 -0
  148. package/src/ban-scanner.js +200 -0
  149. package/src/boundary-scanner.js +296 -0
  150. package/src/ci-scanner.js +279 -0
  151. package/src/code-scanner.js +245 -0
  152. package/src/enforce.js +166 -0
  153. package/src/formatters/json.js +80 -0
  154. package/src/formatters/sarif.js +388 -0
  155. package/src/guardian/alerts.js +34 -3
  156. package/src/guardian/index.js +41 -2
  157. package/src/index.js +102 -0
  158. package/src/integrations/agentmesh.js +501 -0
  159. package/src/language-detector.js +201 -0
  160. package/src/mcp-scanner.js +253 -0
  161. package/src/multimodal/index.js +579 -0
  162. package/src/obfuscation-scanner.js +457 -0
  163. package/src/policy-engine.js +402 -0
  164. package/src/scanners/dependency-attacks.js +128 -0
  165. package/src/scanners/prompt-injection.js +18 -0
  166. package/src/scanners/supply-chain.js +14 -0
  167. package/src/templates/default-config.yml +90 -0
  168. package/src/vuln-ops/exploitability.js +46 -0
  169. package/src/watch/live-monitor.js +720 -0
  170. package/clawmoat-0.8.0.tgz +0 -0
  171. package/server/index.js.patch +0 -1
@@ -66,14 +66,14 @@ footer{border-top:1px solid var(--navy-mid);padding:40px 0;text-align:center;col
66
66
  <body>
67
67
 
68
68
  <nav>
69
- <div class="container" style="max-width:1140px">
69
+ <div class="container">
70
70
  <a href="/" class="logo">🏰 Claw<span>Moat</span></a>
71
+ <button class="menu-toggle" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu">☰</button>
71
72
  <div class="nav-links">
72
- <a href="/">Home</a>
73
- <a href="/integrations/langchain.html" style="color:var(--white)">Integrations</a>
73
+ <a href="/">Security</a>
74
+ <a href="/services/">AI Agents</a>
74
75
  <a href="/blog/">Blog</a>
75
- <a href="https://github.com/darfaz/clawmoat">GitHub</a>
76
- <a href="/#waitlist" class="btn-sm">Get Early Access</a>
76
+ <a href="https://github.com/darfaz/clawmoat">GitHub ↗</a>
77
77
  </div>
78
78
  </div>
79
79
  </nav>
@@ -276,7 +276,15 @@ audit:
276
276
  </article>
277
277
 
278
278
  <footer>
279
- <p>🏰 ClawMoat — Security moat for AI agents</p>
279
+ <div class="container">
280
+ <div style="display:flex;gap:24px;justify-content:center;flex-wrap:wrap;margin-bottom:16px">
281
+ <a href="https://github.com/darfaz/clawmoat" style="color:var(--gray)">GitHub</a>
282
+ <a href="https://www.npmjs.com/package/clawmoat" style="color:var(--gray)">npm</a>
283
+ <a href="/blog/" style="color:var(--gray)">Blog</a>
284
+ <a href="mailto:hello@clawmoat.com" style="color:var(--gray)">hello@clawmoat.com</a>
285
+ </div>
286
+ <p style="text-align:center;color:var(--gray);font-size:.85rem">© 2026 ClawMoat</p>
287
+ </div>
280
288
  </footer>
281
289
 
282
290
  </body>
@@ -66,14 +66,14 @@ footer{border-top:1px solid var(--navy-mid);padding:40px 0;text-align:center;col
66
66
  <body>
67
67
 
68
68
  <nav>
69
- <div class="container" style="max-width:1140px">
69
+ <div class="container">
70
70
  <a href="/" class="logo">🏰 Claw<span>Moat</span></a>
71
+ <button class="menu-toggle" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu">☰</button>
71
72
  <div class="nav-links">
72
- <a href="/">Home</a>
73
- <a href="/integrations/openai.html" style="color:var(--white)">Integrations</a>
73
+ <a href="/">Security</a>
74
+ <a href="/services/">AI Agents</a>
74
75
  <a href="/blog/">Blog</a>
75
- <a href="https://github.com/darfaz/clawmoat">GitHub</a>
76
- <a href="/#waitlist" class="btn-sm">Get Early Access</a>
76
+ <a href="https://github.com/darfaz/clawmoat">GitHub ↗</a>
77
77
  </div>
78
78
  </div>
79
79
  </nav>
@@ -297,7 +297,15 @@ tools:
297
297
  </article>
298
298
 
299
299
  <footer>
300
- <p>🏰 ClawMoat — Security moat for AI agents</p>
300
+ <div class="container">
301
+ <div style="display:flex;gap:24px;justify-content:center;flex-wrap:wrap;margin-bottom:16px">
302
+ <a href="https://github.com/darfaz/clawmoat" style="color:var(--gray)">GitHub</a>
303
+ <a href="https://www.npmjs.com/package/clawmoat" style="color:var(--gray)">npm</a>
304
+ <a href="/blog/" style="color:var(--gray)">Blog</a>
305
+ <a href="mailto:hello@clawmoat.com" style="color:var(--gray)">hello@clawmoat.com</a>
306
+ </div>
307
+ <p style="text-align:center;color:var(--gray);font-size:.85rem">© 2026 ClawMoat</p>
308
+ </div>
301
309
  </footer>
302
310
 
303
311
  </body>
@@ -66,14 +66,14 @@ footer{border-top:1px solid var(--navy-mid);padding:40px 0;text-align:center;col
66
66
  <body>
67
67
 
68
68
  <nav>
69
- <div class="container" style="max-width:1140px">
69
+ <div class="container">
70
70
  <a href="/" class="logo">🏰 Claw<span>Moat</span></a>
71
+ <button class="menu-toggle" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu">☰</button>
71
72
  <div class="nav-links">
72
- <a href="/">Home</a>
73
- <a href="/integrations/openclaw.html" style="color:var(--white)">Integrations</a>
73
+ <a href="/">Security</a>
74
+ <a href="/services/">AI Agents</a>
74
75
  <a href="/blog/">Blog</a>
75
- <a href="https://github.com/darfaz/clawmoat">GitHub</a>
76
- <a href="/#waitlist" class="btn-sm">Get Early Access</a>
76
+ <a href="https://github.com/darfaz/clawmoat">GitHub ↗</a>
77
77
  </div>
78
78
  </div>
79
79
  </nav>
@@ -293,19 +293,67 @@ done</code></pre>
293
293
  </div>
294
294
  </div>
295
295
 
296
+ <h2>Official Sanitizer Plugin</h2>
297
+
298
+ <div class="callout">
299
+ <strong>🔌 NEW:</strong> ClawMoat is now the <strong>reference implementation</strong> for OpenClaw's pluggable sanitizer pipeline. Every piece of content — transcripts, MCP tool results, agent messages — can pass through ClawMoat before reaching the AI agent.
300
+ </div>
301
+
302
+ <pre><code><span class="lang-label">Shell</span>npm install @openclaw/plugin-clawmoat</code></pre>
303
+
304
+ <pre><code><span class="lang-label">JSON</span>// openclaw.json
305
+ {
306
+ "sanitizers": [{
307
+ "module": "@openclaw/plugin-clawmoat",
308
+ "threshold": "medium",
309
+ "scanSecrets": true
310
+ }]
311
+ }</code></pre>
312
+
313
+ <p>The plugin provides:</p>
314
+ <ul>
315
+ <li><strong>Configurable block thresholds</strong> — low, medium, high, critical</li>
316
+ <li><strong>Clean threat mapping</strong> — ClawMoat threat types → OpenClaw ruleIds</li>
317
+ <li><strong>Full audit logging</strong> — every scan result recorded</li>
318
+ <li><strong>10 test cases</strong> covering injection, credentials, thresholds, and edge cases</li>
319
+ </ul>
320
+
321
+ <p>See the <a href="https://github.com/darfaz/clawmoat/tree/main/plugins/openclaw-adapter">full spec and implementation guide</a> on GitHub.</p>
322
+
323
+ <h2>ClawMoat Dashboard</h2>
324
+
325
+ <p>Pro subscribers get access to the <a href="https://app.clawmoat.com"><strong>ClawMoat Dashboard</strong></a> — a hosted security console where you can:</p>
326
+
327
+ <ul>
328
+ <li><strong>Scan text in your browser</strong> — paste any content and get instant threat analysis</li>
329
+ <li><strong>Generate API keys</strong> — integrate ClawMoat scanning into your own tools via REST API</li>
330
+ <li><strong>View scan history</strong> — full audit trail of every scan with threat level badges</li>
331
+ <li><strong>Monitor stats</strong> — total scans, threats detected, last scan time</li>
332
+ </ul>
333
+
334
+ <p>No terminal required. Log in with your email and start scanning.</p>
335
+
296
336
  <h2>Next Steps</h2>
297
337
  <ul>
338
+ <li><a href="https://app.clawmoat.com">ClawMoat Dashboard</a> — scan, monitor, and manage API keys</li>
298
339
  <li><a href="/integrations/langchain.html">LangChain Integration</a> — use ClawMoat with LangChain agents</li>
299
340
  <li><a href="/integrations/openai.html">OpenAI Integration</a> — secure function calling</li>
300
341
  <li><a href="https://github.com/darfaz/clawmoat">GitHub</a> — contribute, report issues, star the repo</li>
301
- <li><a href="/#waitlist">Join the waitlist</a> — get early access to ClawMoat Pro with cloud dashboards</li>
302
342
  </ul>
303
343
 
304
344
  </div>
305
345
  </article>
306
346
 
307
347
  <footer>
308
- <p>🏰 ClawMoat — Security moat for AI agents</p>
348
+ <div class="container">
349
+ <div style="display:flex;gap:24px;justify-content:center;flex-wrap:wrap;margin-bottom:16px">
350
+ <a href="https://github.com/darfaz/clawmoat" style="color:var(--gray)">GitHub</a>
351
+ <a href="https://www.npmjs.com/package/clawmoat" style="color:var(--gray)">npm</a>
352
+ <a href="/blog/" style="color:var(--gray)">Blog</a>
353
+ <a href="mailto:hello@clawmoat.com" style="color:var(--gray)">hello@clawmoat.com</a>
354
+ </div>
355
+ <p style="text-align:center;color:var(--gray);font-size:.85rem">© 2026 ClawMoat</p>
356
+ </div>
309
357
  </footer>
310
358
 
311
359
  </body>
@@ -0,0 +1,255 @@
1
+ # ClawMoat Threat Intel API — Implementation Plan
2
+
3
+ > **For implementation:** Use the executing-plans skill to implement this plan task-by-task.
4
+
5
+ **Goal:** Ship an MVP API endpoint that serves structured AI agent security threat intelligence, with Stripe metered billing.
6
+
7
+ **Architecture:** Express.js server (extends existing ~/clawmoat/server/), backed by a JSON threat database that Leo populates from daily security news scans. Endpoints serve filtered threat data. Stripe usage-based billing tracks API calls per key. Deployed on Railway.
8
+
9
+ **Tech Stack:** Express.js, Stripe metered billing, JSON flat-file storage (MVP), API key auth, Railway deploy
10
+
11
+ ---
12
+
13
+ ## Task 1: Threat Database Schema & Seed Data
14
+
15
+ **Files:**
16
+ - Create: `server/data/threats.json`
17
+ - Create: `server/data/schema.md`
18
+
19
+ **Step 1: Define the threat schema**
20
+
21
+ ```json
22
+ {
23
+ "id": "CLAWMOAT-2026-0001",
24
+ "title": "LiteLLM .pth File Injection",
25
+ "published": "2026-03-24T00:00:00Z",
26
+ "updated": "2026-03-26T00:00:00Z",
27
+ "severity": "critical",
28
+ "category": "supply-chain",
29
+ "tags": ["python", "pypi", "credential-theft", "pth-injection"],
30
+ "summary": "LiteLLM versions 1.82.7-1.82.8 contain credential-stealing .pth payload",
31
+ "affected": {
32
+ "packages": ["litellm==1.82.7", "litellm==1.82.8"],
33
+ "ecosystems": ["pypi"]
34
+ },
35
+ "ioc": {
36
+ "domains": ["models.litellm.cloud"],
37
+ "files": ["litellm_init.pth"],
38
+ "hashes": [],
39
+ "patterns": ["exec(base64.b64decode(", ".pth import subprocess"]
40
+ },
41
+ "detection": {
42
+ "clawmoat_module": "scanners/supply-chain",
43
+ "clawmoat_function": "scanSkillContent",
44
+ "rules_triggered": ["obfuscated_exec_b64", "pth_file_injection", "exfil_litellm_lookalike"]
45
+ },
46
+ "references": [
47
+ "https://github.com/BerriAI/litellm/issues/24512",
48
+ "https://news.ycombinator.com/item?id=47501426",
49
+ "https://awesomeagents.ai/news/litellm-supply-chain-compromise-credential-theft/"
50
+ ],
51
+ "mitigation": "Rotate all credentials on affected systems. Check: pip show litellm | grep Version. Search: find / -name litellm_init.pth"
52
+ }
53
+ ```
54
+
55
+ **Step 2: Seed with this week's 5 threats**
56
+
57
+ Populate threats.json with:
58
+ 1. LiteLLM .pth injection (CLAWMOAT-2026-0001)
59
+ 2. Meta AI agent data leak (CLAWMOAT-2026-0002)
60
+ 3. API key exposure on 10K websites (CLAWMOAT-2026-0003)
61
+ 4. LeakBase credential marketplace (CLAWMOAT-2026-0004)
62
+ 5. Gemini API key theft — $82K bill (CLAWMOAT-2026-0005)
63
+
64
+ **Step 3: Commit**
65
+
66
+ ```
67
+ git commit -m "feat: threat intel database schema + seed data (5 threats)"
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Task 2: API Endpoint — GET /api/v1/threats
73
+
74
+ **Files:**
75
+ - Create: `server/routes/threats.js`
76
+ - Modify: `server/index.js` (mount route)
77
+ - Create: `server/middleware/api-key-auth.js`
78
+ - Test: `server/tests/threats.test.js`
79
+
80
+ **Step 1: Write failing test**
81
+
82
+ ```javascript
83
+ const request = require('supertest');
84
+ const app = require('../index');
85
+
86
+ describe('GET /api/v1/threats', () => {
87
+ it('returns 401 without API key', async () => {
88
+ const res = await request(app).get('/api/v1/threats');
89
+ expect(res.status).toBe(401);
90
+ });
91
+
92
+ it('returns threats with valid API key', async () => {
93
+ const res = await request(app)
94
+ .get('/api/v1/threats')
95
+ .set('X-API-Key', 'test-key-123');
96
+ expect(res.status).toBe(200);
97
+ expect(res.body.threats).toBeInstanceOf(Array);
98
+ expect(res.body.threats.length).toBeGreaterThan(0);
99
+ });
100
+
101
+ it('filters by category', async () => {
102
+ const res = await request(app)
103
+ .get('/api/v1/threats?category=supply-chain')
104
+ .set('X-API-Key', 'test-key-123');
105
+ expect(res.body.threats.every(t => t.category === 'supply-chain')).toBe(true);
106
+ });
107
+
108
+ it('filters by severity', async () => {
109
+ const res = await request(app)
110
+ .get('/api/v1/threats?severity=critical')
111
+ .set('X-API-Key', 'test-key-123');
112
+ expect(res.body.threats.every(t => t.severity === 'critical')).toBe(true);
113
+ });
114
+
115
+ it('filters by date range', async () => {
116
+ const res = await request(app)
117
+ .get('/api/v1/threats?since=2026-03-24')
118
+ .set('X-API-Key', 'test-key-123');
119
+ expect(res.body.threats.length).toBeGreaterThan(0);
120
+ });
121
+ });
122
+ ```
123
+
124
+ **Step 2: Run test, confirm failure**
125
+
126
+ **Step 3: Implement API key middleware**
127
+
128
+ ```javascript
129
+ // server/middleware/api-key-auth.js
130
+ const validKeys = new Map(); // loaded from server/data/api-keys.json
131
+
132
+ function apiKeyAuth(req, res, next) {
133
+ const key = req.headers['x-api-key'];
134
+ if (!key) return res.status(401).json({ error: 'API key required' });
135
+ const record = validKeys.get(key);
136
+ if (!record) return res.status(403).json({ error: 'Invalid API key' });
137
+ req.apiUser = record;
138
+ next();
139
+ }
140
+ ```
141
+
142
+ **Step 4: Implement threats route**
143
+
144
+ Query params: `category`, `severity`, `since`, `tags`, `limit` (default 20, max 100)
145
+
146
+ Response format:
147
+ ```json
148
+ {
149
+ "threats": [...],
150
+ "count": 5,
151
+ "total": 5,
152
+ "updated": "2026-03-26T15:00:00Z"
153
+ }
154
+ ```
155
+
156
+ **Step 5: Run tests, confirm pass**
157
+
158
+ **Step 6: Commit**
159
+
160
+ ```
161
+ git commit -m "feat: GET /api/v1/threats endpoint with filtering + API key auth"
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Task 3: GET /api/v1/threats/:id — Single Threat Detail
167
+
168
+ **Files:**
169
+ - Modify: `server/routes/threats.js`
170
+ - Modify: `server/tests/threats.test.js`
171
+
172
+ Returns full threat object including IOCs, detection rules, mitigation steps.
173
+
174
+ ---
175
+
176
+ ## Task 4: GET /api/v1/ioc — Indicators of Compromise Feed
177
+
178
+ **Files:**
179
+ - Create: `server/routes/ioc.js`
180
+ - Test: `server/tests/ioc.test.js`
181
+
182
+ Aggregates all IOCs across threats into a flat feed. Useful for agents to bulk-update their blocklists.
183
+
184
+ ```json
185
+ {
186
+ "domains": ["models.litellm.cloud", ...],
187
+ "files": ["litellm_init.pth", ...],
188
+ "patterns": ["exec(base64.b64decode(", ...],
189
+ "updated": "2026-03-26T15:00:00Z"
190
+ }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Task 5: Stripe Metered Billing
196
+
197
+ **Files:**
198
+ - Create: `server/middleware/usage-tracker.js`
199
+ - Create: `server/billing/stripe.js`
200
+ - Modify: `server/middleware/api-key-auth.js` (link to Stripe customer)
201
+
202
+ **Pricing:**
203
+ - Free tier: 100 calls/month (no card required)
204
+ - Pro: $4.99/mo flat + $0.001/call over 5,000
205
+ - Unlimited: $19.99/mo
206
+
207
+ **Implementation:**
208
+ 1. On each API call, increment usage counter in api-keys.json
209
+ 2. Stripe webhook on subscription create → generate API key → email to user
210
+ 3. Daily cron: report usage to Stripe metered billing
211
+ 4. Free tier: check call count, return 429 when exceeded
212
+
213
+ ---
214
+
215
+ ## Task 6: API Key Self-Service
216
+
217
+ **Files:**
218
+ - Create: `server/routes/keys.js`
219
+ - Test: `server/tests/keys.test.js`
220
+
221
+ POST /api/v1/keys — generate a free-tier API key (email required)
222
+ GET /api/v1/keys/:key/usage — check your usage
223
+
224
+ ---
225
+
226
+ ## Task 7: Railway Deploy
227
+
228
+ **Files:**
229
+ - Modify: `server/package.json` (start script)
230
+ - Create: `server/Procfile`
231
+ - Create: `server/.env.example`
232
+
233
+ Environment vars: STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, API_MASTER_KEY
234
+
235
+ Deploy to Railway on clawmoat.com subdomain: `api.clawmoat.com`
236
+
237
+ ---
238
+
239
+ ## Task 8: Documentation
240
+
241
+ **Files:**
242
+ - Create: `docs/api/README.md`
243
+ - Create: `docs/api/openapi.yaml`
244
+ - Modify: `README.md` (add Threat Intel API section)
245
+
246
+ OpenAPI spec for the full API. Add to clawmoat.com as /docs/api page.
247
+
248
+ ---
249
+
250
+ ## MVP Scope (Tonight)
251
+
252
+ Tasks 1-3 + 7 = working API with seed data, deployed on Railway.
253
+ Tasks 4-6 + 8 = fast follow (this week).
254
+
255
+ **Total estimated time: 4-5 hours for MVP, 2-3 more for billing + docs.**