@yiaany/ghostapi 0.1.7 → 0.1.9

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 (322) hide show
  1. package/CHANGELOG.md +42 -2
  2. package/CONTRIBUTING.md +119 -117
  3. package/LICENSE +21 -21
  4. package/README.md +208 -181
  5. package/SECURITY.md +53 -37
  6. package/dist/actions/gateway.d.ts +179 -0
  7. package/dist/actions/gateway.js +514 -0
  8. package/dist/actions/gateway.js.map +1 -0
  9. package/dist/actions/index.d.ts +2 -0
  10. package/dist/actions/index.js +2 -0
  11. package/dist/actions/index.js.map +1 -0
  12. package/dist/ai/aiClient.js +4 -4
  13. package/dist/ai/aiClient.js.map +1 -1
  14. package/dist/ai/aiGenerator.d.ts +2 -2
  15. package/dist/ai/aiGenerator.js +21 -72
  16. package/dist/ai/aiGenerator.js.map +1 -1
  17. package/dist/ai/prompts.js +51 -51
  18. package/dist/ai/prompts.js.map +1 -1
  19. package/dist/approvals/approvalInbox.d.ts +150 -0
  20. package/dist/approvals/approvalInbox.js +412 -0
  21. package/dist/approvals/approvalInbox.js.map +1 -0
  22. package/dist/approvals/index.d.ts +2 -0
  23. package/dist/approvals/index.js +2 -0
  24. package/dist/approvals/index.js.map +1 -0
  25. package/dist/behavior/behaviorStore.d.ts +2 -0
  26. package/dist/behavior/behaviorStore.js +50 -46
  27. package/dist/behavior/behaviorStore.js.map +1 -1
  28. package/dist/cache/index.d.ts +2 -0
  29. package/dist/cache/index.js +58 -14
  30. package/dist/cache/index.js.map +1 -1
  31. package/dist/cli/index.js +438 -58
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/openUrl.d.ts +10 -0
  34. package/dist/cli/openUrl.js +31 -0
  35. package/dist/cli/openUrl.js.map +1 -0
  36. package/dist/cli/parser.d.ts +155 -0
  37. package/dist/cli/parser.js +504 -2
  38. package/dist/cli/parser.js.map +1 -1
  39. package/dist/config/dataPaths.d.ts +31 -0
  40. package/dist/config/dataPaths.js +45 -0
  41. package/dist/config/dataPaths.js.map +1 -0
  42. package/dist/config/localConfig.d.ts +1 -2
  43. package/dist/config/localConfig.js +27 -21
  44. package/dist/config/localConfig.js.map +1 -1
  45. package/dist/config/serverConfig.d.ts +2 -0
  46. package/dist/config/serverConfig.js +8 -1
  47. package/dist/config/serverConfig.js.map +1 -1
  48. package/dist/contracts/contract.d.ts +76 -0
  49. package/dist/contracts/contract.js +603 -0
  50. package/dist/contracts/contract.js.map +1 -0
  51. package/dist/contracts/index.d.ts +2 -0
  52. package/dist/contracts/index.js +2 -0
  53. package/dist/contracts/index.js.map +1 -0
  54. package/dist/credentials/credentialBroker.d.ts +207 -0
  55. package/dist/credentials/credentialBroker.js +588 -0
  56. package/dist/credentials/credentialBroker.js.map +1 -0
  57. package/dist/credentials/index.d.ts +2 -0
  58. package/dist/credentials/index.js +2 -0
  59. package/dist/credentials/index.js.map +1 -0
  60. package/dist/dashboard/app.js +685 -615
  61. package/dist/dashboard/index.html +13 -7
  62. package/dist/dashboard/styles.css +349 -349
  63. package/dist/egress/capabilities.d.ts +32 -0
  64. package/dist/egress/capabilities.js +165 -0
  65. package/dist/egress/capabilities.js.map +1 -0
  66. package/dist/egress/linuxBootstrap.d.ts +1 -0
  67. package/dist/egress/linuxBootstrap.js +121 -0
  68. package/dist/egress/linuxBootstrap.js.map +1 -0
  69. package/dist/egress/run.d.ts +18 -0
  70. package/dist/egress/run.js +305 -0
  71. package/dist/egress/run.js.map +1 -0
  72. package/dist/errors/errorEngine.d.ts +2 -2
  73. package/dist/errors/errorEngine.js +3 -40
  74. package/dist/errors/errorEngine.js.map +1 -1
  75. package/dist/evals/evals.d.ts +126 -0
  76. package/dist/evals/evals.js +466 -0
  77. package/dist/evals/evals.js.map +1 -0
  78. package/dist/evals/index.d.ts +2 -0
  79. package/dist/evals/index.js +2 -0
  80. package/dist/evals/index.js.map +1 -0
  81. package/dist/evidence/index.d.ts +2 -0
  82. package/dist/evidence/index.js +2 -0
  83. package/dist/evidence/index.js.map +1 -0
  84. package/dist/evidence/report.d.ts +143 -0
  85. package/dist/evidence/report.js +556 -0
  86. package/dist/evidence/report.js.map +1 -0
  87. package/dist/fault/faultLab.d.ts +5 -4
  88. package/dist/fault/faultLab.js +66 -24
  89. package/dist/fault/faultLab.js.map +1 -1
  90. package/dist/index.d.ts +46 -0
  91. package/dist/index.js +23 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/inventory/analysis.d.ts +12 -0
  94. package/dist/inventory/analysis.js +457 -0
  95. package/dist/inventory/analysis.js.map +1 -0
  96. package/dist/inventory/index.d.ts +5 -0
  97. package/dist/inventory/index.js +4 -0
  98. package/dist/inventory/index.js.map +1 -0
  99. package/dist/inventory/inventoryController.d.ts +53 -0
  100. package/dist/inventory/inventoryController.js +1044 -0
  101. package/dist/inventory/inventoryController.js.map +1 -0
  102. package/dist/inventory/types.d.ts +579 -0
  103. package/dist/inventory/types.js +787 -0
  104. package/dist/inventory/types.js.map +1 -0
  105. package/dist/landing/assets/index-CxWsopzP.css +1 -0
  106. package/dist/landing/assets/index-DZlpyhqd.js +55 -0
  107. package/dist/landing/assets/index-Dk-Xezs3.js +55 -0
  108. package/dist/landing/index.html +15 -15
  109. package/dist/ledger/actionLedger.d.ts +125 -0
  110. package/dist/ledger/actionLedger.js +594 -0
  111. package/dist/ledger/actionLedger.js.map +1 -0
  112. package/dist/ledger/index.d.ts +2 -0
  113. package/dist/ledger/index.js +2 -0
  114. package/dist/ledger/index.js.map +1 -0
  115. package/dist/mcp/server.js +4 -3
  116. package/dist/mcp/server.js.map +1 -1
  117. package/dist/policy/index.d.ts +3 -0
  118. package/dist/policy/index.js +2 -0
  119. package/dist/policy/index.js.map +1 -0
  120. package/dist/policy/policy.d.ts +14 -0
  121. package/dist/policy/policy.js +282 -0
  122. package/dist/policy/policy.js.map +1 -0
  123. package/dist/policy/types.d.ts +52 -0
  124. package/dist/policy/types.js +2 -0
  125. package/dist/policy/types.js.map +1 -0
  126. package/dist/productTelemetry/index.d.ts +16 -0
  127. package/dist/productTelemetry/index.js +142 -0
  128. package/dist/productTelemetry/index.js.map +1 -0
  129. package/dist/providers/conformance.d.ts +7 -0
  130. package/dist/providers/conformance.js +48 -0
  131. package/dist/providers/conformance.js.map +1 -0
  132. package/dist/providers/index.d.ts +4 -2
  133. package/dist/providers/index.js +3 -1
  134. package/dist/providers/index.js.map +1 -1
  135. package/dist/providers/packs/resendPack.d.ts +2 -0
  136. package/dist/providers/packs/resendPack.js +147 -0
  137. package/dist/providers/packs/resendPack.js.map +1 -0
  138. package/dist/providers/packs/stripePack.d.ts +2 -0
  139. package/dist/providers/packs/stripePack.js +852 -0
  140. package/dist/providers/packs/stripePack.js.map +1 -0
  141. package/dist/providers/registry.d.ts +7 -3
  142. package/dist/providers/registry.js +55 -4
  143. package/dist/providers/registry.js.map +1 -1
  144. package/dist/providers/resend.js +2 -11
  145. package/dist/providers/resend.js.map +1 -1
  146. package/dist/providers/runtime.d.ts +8 -0
  147. package/dist/providers/runtime.js +48 -0
  148. package/dist/providers/runtime.js.map +1 -0
  149. package/dist/providers/stripeWebhook.d.ts +13 -0
  150. package/dist/providers/stripeWebhook.js +50 -0
  151. package/dist/providers/stripeWebhook.js.map +1 -0
  152. package/dist/providers/types.d.ts +153 -0
  153. package/dist/proxy/cacheKey.js +3 -3
  154. package/dist/proxy/cacheKey.js.map +1 -1
  155. package/dist/proxy/providerDetector.d.ts +2 -7
  156. package/dist/proxy/providerDetector.js +4 -4
  157. package/dist/proxy/providerDetector.js.map +1 -1
  158. package/dist/proxy/proxyHandler.js +116 -12
  159. package/dist/proxy/proxyHandler.js.map +1 -1
  160. package/dist/proxy/requestNormalizer.d.ts +0 -1
  161. package/dist/proxy/requestNormalizer.js +2 -5
  162. package/dist/proxy/requestNormalizer.js.map +1 -1
  163. package/dist/reliability/costGovernance.d.ts +175 -0
  164. package/dist/reliability/costGovernance.js +515 -0
  165. package/dist/reliability/costGovernance.js.map +1 -0
  166. package/dist/reliability/index.d.ts +8 -0
  167. package/dist/reliability/index.js +5 -0
  168. package/dist/reliability/index.js.map +1 -0
  169. package/dist/reliability/reconciliation.d.ts +157 -0
  170. package/dist/reliability/reconciliation.js +522 -0
  171. package/dist/reliability/reconciliation.js.map +1 -0
  172. package/dist/reliability/runtimeHealth.d.ts +60 -0
  173. package/dist/reliability/runtimeHealth.js +356 -0
  174. package/dist/reliability/runtimeHealth.js.map +1 -0
  175. package/dist/reliability/slo.d.ts +131 -0
  176. package/dist/reliability/slo.js +375 -0
  177. package/dist/reliability/slo.js.map +1 -0
  178. package/dist/report/safetyReport.js +7 -3
  179. package/dist/report/safetyReport.js.map +1 -1
  180. package/dist/safety/index.d.ts +2 -0
  181. package/dist/safety/index.js +2 -0
  182. package/dist/safety/index.js.map +1 -0
  183. package/dist/safety/safetyController.d.ts +187 -0
  184. package/dist/safety/safetyController.js +477 -0
  185. package/dist/safety/safetyController.js.map +1 -0
  186. package/dist/scenarios/scenarioBundle.d.ts +75 -0
  187. package/dist/scenarios/scenarioBundle.js +750 -0
  188. package/dist/scenarios/scenarioBundle.js.map +1 -0
  189. package/dist/scenarios/scenarioStore.d.ts +1 -0
  190. package/dist/scenarios/scenarioStore.js +47 -32
  191. package/dist/scenarios/scenarioStore.js.map +1 -1
  192. package/dist/security/headerSanitizer.d.ts +2 -0
  193. package/dist/security/headerSanitizer.js +36 -1
  194. package/dist/security/headerSanitizer.js.map +1 -1
  195. package/dist/security/secrets.js +24 -4
  196. package/dist/security/secrets.js.map +1 -1
  197. package/dist/server/accessControl.d.ts +5 -0
  198. package/dist/server/accessControl.js +100 -0
  199. package/dist/server/accessControl.js.map +1 -0
  200. package/dist/server/createServer.d.ts +0 -5
  201. package/dist/server/createServer.js +9 -29
  202. package/dist/server/createServer.js.map +1 -1
  203. package/dist/server/eventsStore.d.ts +6 -1
  204. package/dist/server/eventsStore.js +83 -15
  205. package/dist/server/eventsStore.js.map +1 -1
  206. package/dist/server/routes.js +42 -10
  207. package/dist/server/routes.js.map +1 -1
  208. package/dist/server/sse.d.ts +2 -1
  209. package/dist/server/sse.js +15 -3
  210. package/dist/server/sse.js.map +1 -1
  211. package/dist/setup/setupGenerator.js +53 -6
  212. package/dist/setup/setupGenerator.js.map +1 -1
  213. package/dist/state/stateStore.d.ts +5 -0
  214. package/dist/state/stateStore.js +48 -62
  215. package/dist/state/stateStore.js.map +1 -1
  216. package/dist/storage/fileStore.d.ts +10 -0
  217. package/dist/storage/fileStore.js +131 -0
  218. package/dist/storage/fileStore.js.map +1 -0
  219. package/dist/teamControl/controlPlane.d.ts +255 -0
  220. package/dist/teamControl/controlPlane.js +918 -0
  221. package/dist/teamControl/controlPlane.js.map +1 -0
  222. package/dist/teamControl/deployment.d.ts +33 -0
  223. package/dist/teamControl/deployment.js +67 -0
  224. package/dist/teamControl/deployment.js.map +1 -0
  225. package/dist/teamControl/index.d.ts +4 -0
  226. package/dist/teamControl/index.js +3 -0
  227. package/dist/teamControl/index.js.map +1 -0
  228. package/dist/tests/testGenerator.js +4 -1
  229. package/dist/tests/testGenerator.js.map +1 -1
  230. package/dist/trust/index.d.ts +2 -0
  231. package/dist/trust/index.js +2 -0
  232. package/dist/trust/index.js.map +1 -0
  233. package/dist/trust/trustLadder.d.ts +182 -0
  234. package/dist/trust/trustLadder.js +560 -0
  235. package/dist/trust/trustLadder.js.map +1 -0
  236. package/dist/worlds/index.d.ts +2 -0
  237. package/dist/worlds/index.js +2 -0
  238. package/dist/worlds/index.js.map +1 -0
  239. package/dist/worlds/worlds.d.ts +160 -0
  240. package/dist/worlds/worlds.js +491 -0
  241. package/dist/worlds/worlds.js.map +1 -0
  242. package/docs/assets/dashboard.png +0 -0
  243. package/docs/ci.md +49 -0
  244. package/docs/commercial/README.md +29 -0
  245. package/docs/commercial/data-inventory.md +36 -0
  246. package/docs/commercial/manual-invoicing.md +44 -0
  247. package/docs/commercial/metrics.md +51 -0
  248. package/docs/commercial/pricing.md +103 -0
  249. package/docs/commercial/privacy-policy-draft.md +41 -0
  250. package/docs/commercial/terms-topics-for-counsel.md +51 -0
  251. package/docs/design-partners/README.md +52 -0
  252. package/docs/design-partners/demo-narratives.md +33 -0
  253. package/docs/design-partners/design-partner-offer.md +39 -0
  254. package/docs/design-partners/discovery-questions.md +28 -0
  255. package/docs/design-partners/feedback-capture-template.md +48 -0
  256. package/docs/design-partners/icp-one-pager.md +43 -0
  257. package/docs/design-partners/onboarding-checklist.md +33 -0
  258. package/docs/design-partners/pilot-success-criteria.md +27 -0
  259. package/docs/design-partners/pricing-interview-script.md +18 -0
  260. package/docs/design-partners/telemetry-plan.md +48 -0
  261. package/docs/development/baseline.md +114 -0
  262. package/docs/development/onboarding-smoke.md +37 -0
  263. package/docs/development/verification-0.1.8.md +25 -0
  264. package/docs/enterprise-product-roadmap-ru.md +1879 -0
  265. package/docs/fundraising/README.md +87 -0
  266. package/docs/fundraising/data-room-checklist.md +72 -0
  267. package/docs/fundraising/demo-script.md +52 -0
  268. package/docs/fundraising/design-partners-50.md +74 -0
  269. package/docs/fundraising/launch-posts.md +37 -0
  270. package/docs/fundraising/metrics-and-evidence.md +30 -0
  271. package/docs/fundraising/roadmap-12-month.md +25 -0
  272. package/docs/fundraising/technical-due-diligence-index.md +37 -0
  273. package/docs/fundraising/yc-application.md +25 -0
  274. package/docs/github-actions.md +84 -0
  275. package/docs/hosted-pilot.md +111 -0
  276. package/docs/mcp.md +52 -50
  277. package/docs/operations/disaster-recovery-runbook.md +81 -0
  278. package/docs/operations/kill-switch-runbook.md +32 -0
  279. package/docs/policy.md +61 -0
  280. package/docs/providers/authoring-packs.md +175 -0
  281. package/docs/providers/stripe-core-pack.md +82 -0
  282. package/docs/release-checklist.md +83 -71
  283. package/docs/release-migration-and-rollback.md +63 -0
  284. package/docs/release-readiness.md +39 -0
  285. package/docs/security/action-gateway-threat-model.md +34 -0
  286. package/docs/security/action-ledger-incident-replay-threat-model.md +42 -0
  287. package/docs/security/approval-inbox-threat-model.md +35 -0
  288. package/docs/security/credential-broker-threat-model.md +52 -0
  289. package/docs/security/egress-threat-model.md +126 -0
  290. package/docs/security/inventory-threat-model.md +104 -0
  291. package/docs/security/kill-switch-budgets-threat-model.md +37 -0
  292. package/docs/security/reliability-threat-model.md +111 -0
  293. package/docs/security/trust-ladder-threat-model.md +33 -0
  294. package/docs/team-control-plane.md +72 -0
  295. package/docs/usage.md +571 -57
  296. package/examples/README.md +10 -0
  297. package/examples/agent-instructions/README.md +39 -39
  298. package/examples/ci-smoke/README.md +21 -0
  299. package/examples/ci-smoke/ghostapi.policy.yaml +22 -0
  300. package/examples/ci-smoke/package.json +9 -0
  301. package/examples/ci-smoke/production-egress.mjs +2 -0
  302. package/examples/ci-smoke/safe.mjs +17 -0
  303. package/examples/evals/README.md +24 -0
  304. package/examples/evals/retry-after.eval.json +52 -0
  305. package/examples/generic-rest/README.md +27 -27
  306. package/examples/github-fetch/README.md +35 -35
  307. package/examples/openai-streaming/README.md +16 -0
  308. package/examples/openai-streaming/streaming-tool-call.mjs +31 -0
  309. package/examples/policy/ghostapi.policy.yaml +27 -0
  310. package/examples/record-replay/README.md +19 -0
  311. package/examples/record-replay/replay-requests.json +22 -0
  312. package/examples/record-replay/stripe-checkout.har.json +30 -0
  313. package/examples/resend-node/README.md +22 -22
  314. package/examples/stripe-node/README.md +35 -29
  315. package/examples/stripe-node/checkout-flow.mjs +61 -0
  316. package/examples/twilio-node/README.md +21 -21
  317. package/examples/worlds/README.md +19 -0
  318. package/examples/worlds/subscription-recovery.mjs +12 -0
  319. package/package.json +27 -12
  320. package/dist/providers/stripe.d.ts +0 -2
  321. package/dist/providers/stripe.js +0 -15
  322. package/dist/providers/stripe.js.map +0 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- A local API sandbox, dashboard, and MCP control plane for building third-party integrations without touching production.
12
+ Build and test third-party API integrations locally, without charging cards, sending messages, leaking production keys, or mutating real services.
13
13
  </p>
14
14
 
15
15
  <p align="center">
@@ -17,15 +17,16 @@
17
17
  <a href="https://github.com/yiaany/ghostapi/blob/main/LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-0f172a"></a>
18
18
  <a href="https://github.com/yiaany/ghostapi/actions/workflows/ci.yml"><img alt="ci" src="https://github.com/yiaany/ghostapi/actions/workflows/ci.yml/badge.svg"></a>
19
19
  <img alt="node" src="https://img.shields.io/badge/node-%3E%3D20-0f172a">
20
- <img alt="mcp" src="https://img.shields.io/badge/MCP-enabled-0f172a">
20
+ <img alt="MCP" src="https://img.shields.io/badge/MCP-enabled-0f172a">
21
21
  </p>
22
22
 
23
23
  <p align="center">
24
24
  <a href="#quickstart">Quickstart</a> ·
25
- <a href="#mcp-setup">MCP Setup</a> ·
26
- <a href="#how-it-works">How It Works</a> ·
27
- <a href="#sdk-recipes">SDK Recipes</a> ·
28
- <a href="#contributing">Contributing</a>
25
+ <a href="#what-you-get">Features</a> ·
26
+ <a href="#provider-support">Providers</a> ·
27
+ <a href="#mcp-for-agents">MCP</a> ·
28
+ <a href="#safety-boundaries">Safety</a> ·
29
+ <a href="#hosted-and-enterprise">Enterprise</a>
29
30
  </p>
30
31
 
31
32
  ```bash
@@ -33,113 +34,144 @@ npx @yiaany/ghostapi start --open
33
34
  ```
34
35
 
35
36
  <p align="center">
36
- <img src="docs/assets/dashboard.png" alt="GhostAPI dashboard showing local API traffic">
37
+ <img src="docs/assets/dashboard.png" alt="GhostAPI dashboard with live local Stripe, OpenAI, and REST traffic">
37
38
  </p>
38
39
 
39
- ## The Problem
40
+ ## Why GhostAPI
40
41
 
41
- AI coding agents are now strong enough to write Stripe checkouts, OpenAI workflows, GitHub automations, Twilio messaging, and email integrations. The dangerous part is that they also run the code they write.
42
+ Coding agents can write a Stripe checkout, an OpenAI workflow, a GitHub automation, or an email integration in minutes. The dangerous part is what happens when they run that code.
42
43
 
43
- That creates a bad default loop:
44
+ Without a safe local target, a test can:
44
45
 
45
- | Agent action | Production risk |
46
- | --- | --- |
47
- | Tests a Stripe flow | Real money movement or broken payment state. |
48
- | Tests Twilio or Resend | Real SMS or email sent to real people. |
49
- | Tests GitHub automation | Real issues, branches, releases, or repo mutations. |
50
- | Tests OpenAI calls | Real token spend and possible prompt/data leakage. |
51
- | Logs request/response payloads | Secrets leak into terminals, prompts, screenshots, or cache. |
52
-
53
- GhostAPI gives agents a local universe where integrations behave like real providers, but every request stays on your machine.
54
-
55
- ## What GhostAPI Does
56
-
57
- GhostAPI is a local API control layer for agent-driven development.
58
-
59
- <table>
60
- <tr>
61
- <td><strong>Local API Sandbox</strong><br>Run provider-shaped APIs on <code>127.0.0.1:8080</code> instead of live Stripe, OpenAI, Twilio, Resend, GitHub, Discord, or random REST services.</td>
62
- <td><strong>Live Dashboard</strong><br>Watch every request, inspect request and response bodies, replay scenarios, generate setup snippets, and verify what your agent actually did.</td>
63
- </tr>
64
- <tr>
65
- <td><strong>MCP Control Plane</strong><br>Let agents inspect state, read traffic logs, force deterministic responses, and toggle Chaos Mode through MCP tools.</td>
66
- <td><strong>Safe Failure Testing</strong><br>Force card declines, rate limits, upstream errors, latency, and provider-shaped edge cases without waiting for real APIs to fail.</td>
67
- </tr>
68
- <tr>
69
- <td><strong>Secret Masking</strong><br>Mask secret-looking headers, query params, bodies, cache keys, dashboard payloads, events, and prompt inputs.</td>
70
- <td><strong>Repo Setup Generator</strong><br>Generate MCP config, agent instructions, environment snippets, and SDK patches for the current project.</td>
71
- </tr>
72
- </table>
46
+ - charge a real card;
47
+ - send a real email or SMS;
48
+ - create or modify real GitHub resources;
49
+ - spend API credits;
50
+ - leak credentials into logs, prompts, screenshots, or test fixtures.
51
+
52
+ GhostAPI gives your application and coding agent a local API world at `127.0.0.1:8080`. Requests are detected, sanitized, recorded, and answered with deterministic provider-shaped responses. You can inspect the result in the dashboard, control behavior through MCP, and turn failures into repeatable tests.
73
53
 
74
54
  ## Quickstart
75
55
 
76
- Run GhostAPI instantly:
56
+ Start the local server and dashboard:
77
57
 
78
58
  ```bash
79
59
  npx @yiaany/ghostapi start --open
80
60
  ```
81
61
 
82
- Install globally:
62
+ Send a Stripe-shaped request:
83
63
 
84
64
  ```bash
85
- npm i -g @yiaany/ghostapi
86
- ghostapi start --open
65
+ curl -X POST http://127.0.0.1:8080/v1/customers \
66
+ -H "content-type: application/json" \
67
+ -H "authorization: Bearer stripe_test_ghostapi" \
68
+ -d '{"email":"ada@example.com","name":"Ada Lovelace"}'
87
69
  ```
88
70
 
89
- Open the dashboard:
90
-
91
- ```text
92
- http://127.0.0.1:8080/dashboard
93
- ```
71
+ Open the dashboard at `http://127.0.0.1:8080/dashboard`. The request appears in live traffic with its provider, request body, generated response, source, status, and timing.
94
72
 
95
- Health check:
73
+ Initialize GhostAPI inside an existing repository:
96
74
 
97
75
  ```bash
98
- curl http://127.0.0.1:8080/health
76
+ npx @yiaany/ghostapi init
77
+ npx @yiaany/ghostapi doctor
99
78
  ```
100
79
 
101
- ## 30 Second Demo
80
+ `init` creates local configuration, a versioned safety policy, MCP snippets, and agent instructions without overwriting existing files.
102
81
 
103
- Start the local API world:
82
+ On a supported Linux host, run a command inside the loopback-only network namespace:
104
83
 
105
84
  ```bash
106
- npx @yiaany/ghostapi start --open
85
+ npx @yiaany/ghostapi run -- npm test
107
86
  ```
108
87
 
109
- Send a Stripe-shaped request locally:
88
+ On Windows and macOS, `ghostapi run` fails closed because an equivalent process-isolation backend is not implemented. The local API server and dashboard still work normally.
110
89
 
111
- ```bash
112
- curl -X POST http://127.0.0.1:8080/v1/customers \
113
- -H "content-type: application/json" \
114
- -H "authorization: Bearer stripe_test_ghostapi" \
115
- -d '{"email":"ada@example.com","name":"Ada Lovelace"}'
116
- ```
90
+ ## What You Get
117
91
 
118
- Inspect the captured request in the dashboard:
92
+ | Feature | What it does |
93
+ | --- | --- |
94
+ | Local API sandbox | Gives SDKs and applications a local target instead of a live provider. |
95
+ | Provider-shaped behavior | Returns realistic objects, validation errors, rate limits, declines, and failure payloads. |
96
+ | Live dashboard | Shows requests and responses, filters traffic by provider, generates tests, and arms scenarios. |
97
+ | MCP control plane | Lets compatible coding agents inspect state, read traffic, configure responses, and toggle Chaos Mode. |
98
+ | Stateful synthetic worlds | Maintains deterministic local identities and state across Stripe, GitHub, email, and REST projections. |
99
+ | Scenarios and record/replay | Saves sanitized sandbox traffic and replays it offline as deterministic fixtures. |
100
+ | Contract drift checks | Imports bounded OpenAPI/HAR contracts and classifies breaking, non-breaking, and uncertain changes. |
101
+ | Agent evals and evidence | Produces redacted, tamper-evident reports for local review and CI policy gates. |
102
+ | Secret protection | Masks secret-shaped headers, query parameters, bodies, paths, events, prompts, and cache inputs. |
103
+ | Fault testing | Forces latency, provider errors, card declines, rate limits, and other unhappy paths. |
104
+ | Safety controls | Includes local approvals, scoped budgets, kill switches, circuit breakers, ledgers, and reconciliation for synthetic actions. |
105
+ | Reliability tooling | Tracks local SLO samples, cost attribution, runtime health, backups, inventory, and attack-path metadata. |
119
106
 
120
- ```text
121
- http://127.0.0.1:8080/dashboard
107
+ ## Dashboard
108
+
109
+ The dashboard is the fastest way to understand what an agent or application actually did.
110
+
111
+ - Watch traffic arrive in real time over SSE.
112
+ - Inspect sanitized request and response JSON.
113
+ - Filter by Stripe, Twilio, Resend, GitHub, Discord, OpenAI, or generic REST.
114
+ - Generate a Vitest test from a captured request.
115
+ - Generate and copy setup files for supported coding agents.
116
+ - Arm deterministic scenario presets.
117
+ - Toggle Chaos Mode and inspect the local safety report.
118
+
119
+ Dashboard and API routes are token-protected on every non-loopback bind. Use HTTPS or a secure tunnel when exposing GhostAPI beyond localhost.
120
+
121
+ ## Provider Support
122
+
123
+ GhostAPI has two levels of provider support.
124
+
125
+ ### Stateful provider packs
126
+
127
+ | Provider | Included behavior |
128
+ | --- | --- |
129
+ | Stripe | Customers, products, prices, subscriptions, invoices, payment intents, payment methods, checkout sessions, refunds, pagination, lifecycle scenarios, and signed local webhooks. |
130
+ | Resend | Deterministic email-shaped requests, responses, validation, and failure behavior. |
131
+
132
+ ### Provider-shaped adapters and generic inference
133
+
134
+ OpenAI, Twilio, GitHub, Discord, and generic REST routes are detected and receive provider-shaped mock responses and errors. These adapters are useful for local development, but they do not claim complete parity with every live-provider endpoint.
135
+
136
+ Unsupported endpoints fail diagnostically instead of silently pretending that an operation succeeded.
137
+
138
+ ## SDK Setup
139
+
140
+ Stripe:
141
+
142
+ ```ts
143
+ import Stripe from "stripe";
144
+
145
+ export const stripe = new Stripe(
146
+ process.env.STRIPE_SECRET_KEY ?? "stripe_test_ghostapi",
147
+ {
148
+ host: process.env.GHOSTAPI_HOST ?? "127.0.0.1",
149
+ port: Number(process.env.GHOSTAPI_PORT ?? "8080"),
150
+ protocol: process.env.GHOSTAPI_PROTOCOL ?? "http"
151
+ }
152
+ );
122
153
  ```
123
154
 
124
- ## One-Command Repo Setup
155
+ OpenAI:
125
156
 
126
- Run setup inside any project:
157
+ ```ts
158
+ import OpenAI from "openai";
127
159
 
128
- ```bash
129
- npx @yiaany/ghostapi setup --write
160
+ export const openai = new OpenAI({
161
+ apiKey: process.env.OPENAI_API_KEY ?? "sk-ghostapi",
162
+ baseURL: process.env.GHOSTAPI_OPENAI_BASE_URL ?? "http://127.0.0.1:8080/v1"
163
+ });
130
164
  ```
131
165
 
132
- This generates local setup assets for agent workflows:
166
+ Generic REST:
133
167
 
134
- | Output | Why it matters |
135
- | --- | --- |
136
- | Agent instructions | Tell coding agents to keep provider calls local. |
137
- | MCP snippets | Configure Cursor, Claude, Cline, Aider, Codex, OpenCode, Gemini CLI, Goose, OpenClaw, Hermes, and generic MCP clients. |
138
- | Environment snippets | Point SDKs at `http://127.0.0.1:8080`. |
139
- | SDK patches | Show how to route Stripe and OpenAI SDKs into GhostAPI. |
140
- | Safety guidance | Warn before live providers or live-looking keys enter the loop. |
168
+ ```bash
169
+ curl -X POST http://127.0.0.1:8080/tasks \
170
+ -H "content-type: application/json" \
171
+ -d '{"title":"Add integration tests","status":"open"}'
172
+ ```
141
173
 
142
- ## MCP Setup
174
+ ## MCP For Agents
143
175
 
144
176
  Start the MCP server:
145
177
 
@@ -147,7 +179,7 @@ Start the MCP server:
147
179
  npx @yiaany/ghostapi mcp
148
180
  ```
149
181
 
150
- Universal MCP config:
182
+ Generic MCP configuration:
151
183
 
152
184
  ```json
153
185
  {
@@ -160,158 +192,153 @@ Universal MCP config:
160
192
  }
161
193
  ```
162
194
 
163
- Agent prompt:
164
-
165
- ```text
166
- Use the GhostAPI MCP server.
167
-
168
- Keep all third-party API calls local on http://127.0.0.1:8080.
169
- Do not call real providers.
170
-
171
- Use GhostAPI MCP tools to inspect state, read traffic logs, configure deterministic responses, and test failure scenarios.
172
- ```
173
-
174
- MCP tools:
195
+ Available tools:
175
196
 
176
197
  | Tool | Purpose |
177
198
  | --- | --- |
178
- | `inspect_state` | Read local API objects from `.ghostapi/state.json`. |
179
- | `get_traffic_logs` | Inspect recent local traffic. |
180
- | `set_api_behavior` | Force deterministic responses for `method + path`. |
181
- | `toggle_chaos_mode` | Enable local latency and provider-shaped errors. |
199
+ | `inspect_state` | Read current local API objects. |
200
+ | `get_traffic_logs` | Inspect sanitized recent traffic. |
201
+ | `set_api_behavior` | Force a deterministic response for a method and path. |
202
+ | `toggle_chaos_mode` | Enable or disable local latency and failure injection. |
182
203
 
183
- ## How It Works
204
+ Generate setup snippets for Cursor, Claude, Cline, Aider, Codex, OpenCode, Gemini CLI, Goose, OpenClaw, Hermes, and generic MCP clients:
184
205
 
185
- ```text
186
- Your app or agent
187
- -> http://127.0.0.1:8080
188
- -> GhostAPI proxy
189
- -> provider detection
190
- -> local state / scenarios / deterministic behavior
191
- -> dashboard + MCP inspection
206
+ ```bash
207
+ npx @yiaany/ghostapi setup --write
192
208
  ```
193
209
 
194
- GhostAPI does five things in the loop:
195
-
196
- | Step | What happens |
197
- | --- | --- |
198
- | Detect | It infers the provider from routes, headers, SDK shapes, and request bodies. |
199
- | Normalize | It converts requests into safe, inspectable local events. |
200
- | Mask | It strips secret-looking values before logs, cache, dashboard, and prompts. |
201
- | Respond | It returns provider-shaped mock responses, errors, or saved state. |
202
- | Control | MCP and dashboard tools let agents force behavior and replay flows. |
210
+ ## Scenarios, Contracts, And Evals
203
211
 
204
- ## SDK Recipes
212
+ Record approved sandbox traffic into a sanitized offline bundle:
205
213
 
206
- Stripe:
214
+ ```bash
215
+ ghostapi record \
216
+ --input capture.har \
217
+ --allow-sandbox-host api.sandbox.example \
218
+ --approve
219
+ ```
207
220
 
208
- ```ts
209
- import Stripe from "stripe";
221
+ Replay it without network access:
210
222
 
211
- export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY ?? "stripe_test_ghostapi", {
212
- host: process.env.GHOSTAPI_HOST ?? "127.0.0.1",
213
- port: Number(process.env.GHOSTAPI_PORT ?? "8080"),
214
- protocol: process.env.GHOSTAPI_PROTOCOL ?? "http"
215
- });
223
+ ```bash
224
+ ghostapi replay bundle.json --requests requests.json
216
225
  ```
217
226
 
218
- OpenAI:
227
+ Import and compare API contracts:
219
228
 
220
- ```ts
221
- import OpenAI from "openai";
229
+ ```bash
230
+ ghostapi contract import-openapi --input openapi.json
231
+ ghostapi contract diff \
232
+ --baseline base.contract.json \
233
+ --candidate head.contract.json \
234
+ --policy ghostapi.policy.yaml \
235
+ --ci
236
+ ```
222
237
 
223
- export const openai = new OpenAI({
224
- apiKey: process.env.OPENAI_API_KEY ?? "sk-ghostapi",
225
- baseURL: process.env.GHOSTAPI_OPENAI_BASE_URL ?? "http://127.0.0.1:8080/v1"
226
- });
238
+ Generate sanitized CI evidence:
239
+
240
+ ```bash
241
+ ghostapi evidence generate --policy ghostapi.policy.yaml --ci
227
242
  ```
228
243
 
229
- Generic REST:
244
+ Run a deterministic agent eval:
230
245
 
231
246
  ```bash
232
- curl -X POST http://127.0.0.1:8080/tasks \
233
- -H "content-type: application/json" \
234
- -d '{"title":"Write integration tests","status":"open"}'
247
+ ghostapi eval \
248
+ --template retry-after \
249
+ --evidence .ghostapi/reports/latest.json \
250
+ --ci
235
251
  ```
236
252
 
237
- ## Built For
253
+ ## Safety Boundaries
238
254
 
239
- | Audience | Use GhostAPI to |
240
- | --- | --- |
241
- | AI coding agents | Build integrations without accidentally touching production. |
242
- | SaaS developers | Test provider happy paths and failure paths locally. |
243
- | API-heavy teams | Turn captured traffic into repeatable scenarios and tests. |
244
- | Open-source maintainers | Give contributors safe examples that do not require live provider accounts. |
255
+ GhostAPI is designed to fail closed, but its boundaries are explicit:
245
256
 
246
- ## Safety Model
257
+ - Real provider calls are disabled by default.
258
+ - Ambient `OPENAI_API_KEY` does not enable external generation.
259
+ - External LLM generation requires an explicit flag plus a separate `GHOSTAPI_LLM_API_KEY`.
260
+ - Non-loopback access requires a strong dashboard token.
261
+ - External response redirects, unsafe response headers, traversal, remote schema references, symlinks, archives, and oversized inputs are rejected where applicable.
262
+ - Persistent stores have size, entry, retention, or rotation limits.
263
+ - The Linux `run` backend provides loopback-only process network isolation when namespace preflight succeeds.
264
+ - `run` is not a hostile-code filesystem sandbox.
265
+ - Secret masking is heuristic. Use synthetic credentials and data even in local fixtures.
266
+ - Local approval, action, credential, ledger, trust, and safety components execute synthetic operations only. They are not a production-provider executor.
247
267
 
248
- - No real provider calls by default.
249
- - Keep SDKs pointed at `http://127.0.0.1:8080`.
250
- - Use fake local keys like `stripe_test_ghostapi` and `sk-ghostapi`.
251
- - Secrets are masked before logs, cache, dashboard, events, and prompts.
252
- - Chaos Mode is opt-in.
253
- - Local state lives under `.ghostapi/` and is gitignored.
268
+ Read the detailed threat models in [`docs/security`](docs/security) and the reporting policy in [`SECURITY.md`](SECURITY.md).
254
269
 
255
- ## Local Files
270
+ ## Platform Support
256
271
 
257
- | Path | Purpose |
258
- | --- | --- |
259
- | `.ghostapi/config.json` | Local GhostAPI config. |
260
- | `.ghostapi/state.json` | Simulated API object state. |
261
- | `.ghostapi/events.jsonl` | Captured local request events. |
262
- | `.ghostapi/behaviors.json` | Deterministic behavior overrides. |
263
- | `.ghostapi/cache/` | Local response cache. |
272
+ | Platform | Local API and dashboard | `ghostapi run` enforcement |
273
+ | --- | --- | --- |
274
+ | Linux | Supported on Node.js 20+ | Supported when `unshare`, `iproute2`, and namespace preflight pass. |
275
+ | Windows | Supported on Node.js 20+ | Not implemented; fails closed. |
276
+ | macOS | Supported on Node.js 20+ | Not implemented; fails closed. |
264
277
 
265
- ## CLI Reference
278
+ Check the current machine:
266
279
 
267
280
  ```bash
268
- npx @yiaany/ghostapi start --open
269
- npx @yiaany/ghostapi open
270
- npx @yiaany/ghostapi setup --write
271
- npx @yiaany/ghostapi mcp
272
- npx @yiaany/ghostapi report
273
- npx @yiaany/ghostapi doctor --port 8080
274
- npx @yiaany/ghostapi clear cache|state|events|all
275
- npx @yiaany/ghostapi providers list
276
- npx @yiaany/ghostapi providers inspect stripe
281
+ ghostapi doctor --json
282
+ ghostapi doctor --egress
277
283
  ```
278
284
 
279
- ## Repository About
280
-
281
- Use this for the GitHub repository description:
285
+ ## Health Endpoints
282
286
 
283
287
  ```text
284
- The local internet for AI coding agents. Simulate Stripe, OpenAI, Twilio, Resend, GitHub, Discord, and REST APIs locally with a dashboard, MCP tools, scenarios, and secret masking.
288
+ GET /health process liveness, HTTP 200 while state can be evaluated
289
+ GET /health/readiness structural readiness, HTTP 503 when a required store is unsafe
285
290
  ```
286
291
 
287
- Recommended topics:
288
-
289
- ```text
290
- mcp, ai-agents, stripe, openai, mock-server, api-testing, sandbox, proxy, local-development, typescript, cursor
291
- ```
292
+ ## Hosted And Enterprise
292
293
 
293
- ## Docs
294
+ The `hosted/` directory contains an implemented but not yet deployed team pilot. It includes:
294
295
 
295
- - [MCP setup](docs/mcp.md)
296
- - [Usage guide](docs/usage.md)
297
- - [Release checklist](docs/release-checklist.md)
298
- - [Contributing](CONTRIBUTING.md)
299
- - [Security policy](SECURITY.md)
296
+ - organizations, projects, invitations, memberships, and role-based access;
297
+ - tenant-safe report and scenario APIs;
298
+ - hashed and rotatable CI ingest keys;
299
+ - bounded request handling, CSRF checks, security headers, quotas, and abuse limits;
300
+ - PostgreSQL migrations, idempotency, outbox dispatch, worker leases, retries, dead letters, and retention cleanup;
301
+ - Redis-backed rate limiting, QStash verification, readiness checks, and a non-root Docker image.
300
302
 
301
- ## Contributing
303
+ It is not advertised as a production SaaS yet. Live OAuth, Redis, QStash, load, failover, backup/restore, and disaster-recovery behavior must still be proven in staging before a paid pilot.
302
304
 
303
- Contributions are welcome. GhostAPI should stay local-first, safe by default, and useful for real agent workflows.
305
+ The detailed product plan for a complete enterprise edition is available in [`docs/enterprise-product-roadmap-ru.md`](docs/enterprise-product-roadmap-ru.md).
304
306
 
305
- Before opening a pull request:
307
+ ## Development
306
308
 
307
309
  ```bash
310
+ npm ci
311
+ npm run lint
308
312
  npm run typecheck
309
313
  npm test
310
314
  npm run build
315
+ npm run smoke:package
311
316
  ```
312
317
 
313
- Do not add tests or examples that call live providers by default. See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide.
318
+ Hosted pilot checks:
319
+
320
+ ```bash
321
+ cd hosted
322
+ npm ci
323
+ npm run check
324
+ ```
325
+
326
+ See [`CONTRIBUTING.md`](CONTRIBUTING.md), [`docs/release-readiness.md`](docs/release-readiness.md), and [`docs/development/verification-0.1.8.md`](docs/development/verification-0.1.8.md) for the complete verification boundary.
327
+
328
+ ## Documentation
329
+
330
+ - [Usage guide](docs/usage.md)
331
+ - [MCP setup](docs/mcp.md)
332
+ - [Policy reference](docs/policy.md)
333
+ - [GitHub Actions integration](docs/github-actions.md)
334
+ - [Generic CI integration](docs/ci.md)
335
+ - [Stripe provider pack](docs/providers/stripe-core-pack.md)
336
+ - [Security policy](SECURITY.md)
337
+ - [Threat models](docs/security)
338
+ - [Release readiness](docs/release-readiness.md)
339
+ - [Migration and rollback](docs/release-migration-and-rollback.md)
340
+ - [Enterprise roadmap in Russian](docs/enterprise-product-roadmap-ru.md)
314
341
 
315
342
  ## License
316
343
 
317
- MIT. See [LICENSE](LICENSE).
344
+ MIT. See [`LICENSE`](LICENSE).
package/SECURITY.md CHANGED
@@ -1,37 +1,53 @@
1
- # Security Policy
2
-
3
- GhostAPI exists to make local integration development safer. Security-sensitive behavior should be treated as core product behavior, not an afterthought.
4
-
5
- ## Supported Versions
6
-
7
- GhostAPI is pre-1.0. Security fixes target the current `main` branch and the latest published package once releases begin.
8
-
9
- ## Safety Model
10
-
11
- - GhostAPI does not make real external provider API calls by default.
12
- - Incoming requests are normalized and sanitized before use in prompts, cache keys, logs, or dashboard events.
13
- - Secret-looking fields are masked, including `authorization`, `api_key`, `apikey`, `x-api-key`, `access_token`, `refresh_token`, `client_secret`, `password`, `secret`, `token`, and `key`.
14
- - Known token patterns are masked, including Stripe keys, GitHub tokens, Slack bot tokens, SendGrid keys, and bearer tokens.
15
- - Local cache entries are stored under `.ghostapi/cache/{provider}/{hash}.json`.
16
- - Local state is stored under `.ghostapi/state.json`.
17
- - `ghostapi doctor` warns when `NODE_TLS_REJECT_UNAUTHORIZED=0` is set.
18
-
19
- ## Reporting A Vulnerability
20
-
21
- Please do not open a public issue for a vulnerability.
22
-
23
- Until a dedicated security email is published, report privately to the project maintainer or repository owner and include:
24
-
25
- - A clear description of the issue.
26
- - Steps to reproduce.
27
- - Expected impact.
28
- - Whether secrets, prompts, cache, state, dashboard events, or network behavior are involved.
29
- - Suggested fix, if you have one.
30
-
31
- We will acknowledge valid reports as quickly as possible and prioritize fixes that could leak secrets, trigger real external calls unexpectedly, or expose local data.
32
-
33
- ## Out Of Scope
34
-
35
- - Issues requiring malicious local filesystem access outside GhostAPI's process permissions.
36
- - Vulnerabilities in unsupported Node.js versions.
37
- - Reports without reproduction details.
1
+ # Security Policy
2
+
3
+ GhostAPI exists to make local integration development safer. Security-sensitive behavior should be treated as core product behavior, not an afterthought.
4
+
5
+ ## Supported Versions
6
+
7
+ GhostAPI is pre-1.0. Security fixes target the current `main` branch and the latest published package once releases begin.
8
+
9
+ ## Safety Model
10
+
11
+ - GhostAPI does not make real external provider API calls by default.
12
+ - External LLM generation requires explicit `--allow-external-llm` or `GHOSTAPI_ALLOW_EXTERNAL_LLM=true` plus `GHOSTAPI_LLM_API_KEY`. Ambient `OPENAI_API_KEY` is ignored by the GhostAPI runtime.
13
+ - Incoming requests are normalized and sanitized before use in prompts, cache keys, logs, or dashboard events.
14
+ - Secret-looking fields are masked, including `authorization`, `api_key`, `apikey`, `x-api-key`, `access_token`, `refresh_token`, `client_secret`, `password`, `secret`, `token`, and `key`.
15
+ - Known token patterns are masked, including Stripe keys, GitHub tokens, Slack bot tokens, SendGrid keys, and bearer tokens.
16
+ - State, behaviors, scenarios, and events are sanitized again at persistence boundaries. Cache keys are derived from sanitized requests; cached generated responses preserve provider response fidelity.
17
+ - Runtime data defaults to `.ghostapi/` and can be isolated with `GHOSTAPI_DATA_DIR`.
18
+ - JSON stores use adjacent inter-process lock files and same-directory temporary-file replacement to avoid covered local lost-update and partial-write scenarios.
19
+ - The persisted event log rotates at 5 MiB, retaining two archives. Individual persisted event details are limited to 256 KiB.
20
+ - Non-loopback binds fail closed unless `GHOSTAPI_AUTH_TOKEN` contains at least 24 characters. The token protects `/dashboard`, dashboard assets, `/api/*`, and `/events`.
21
+ - Loopback remains token-free for local convenience, but hostile browser origins are rejected for dashboard routes.
22
+ - `ghostapi doctor` warns when `NODE_TLS_REJECT_UNAUTHORIZED=0` is set.
23
+
24
+ ## Threat Assumptions
25
+
26
+ - GhostAPI is a local development tool, not a network-isolation boundary. Provider simulation routes remain reachable on the configured bind address, except that remote proxy requests require the dashboard token while external LLM generation is enabled.
27
+ - Dashboard authentication provides access control, not transport confidentiality. Use HTTPS or a secure tunnel for any non-loopback bind; never send the token over untrusted plain HTTP.
28
+ - Filesystem locks coordinate cooperating GhostAPI processes on one local filesystem. They are not distributed locks and are not guaranteed on network shares or independently synchronized copies.
29
+ - On POSIX systems GhostAPI requests owner-only directory/file modes. On Windows, effective access is inherited from the configured directory ACL.
30
+ - Secret masking is heuristic. Do not place production credentials or sensitive personal data in scenarios, behaviors, manually edited state, or other local fixtures.
31
+ - A process that can read the GhostAPI data directory or inspect the running process environment is inside the trust boundary.
32
+ - Query-token bootstrap is accepted only for `GET /dashboard`, then redirected to a URL without the token and stored in an HttpOnly `SameSite=Strict` cookie. API and SSE query tokens are rejected.
33
+ - GhostAPI does not claim DNS, process, container, or host-level egress isolation.
34
+
35
+ ## Reporting A Vulnerability
36
+
37
+ Please do not open a public issue for a vulnerability.
38
+
39
+ Until a dedicated security email is published, report privately to the project maintainer or repository owner and include:
40
+
41
+ - A clear description of the issue.
42
+ - Steps to reproduce.
43
+ - Expected impact.
44
+ - Whether secrets, prompts, cache, state, dashboard events, or network behavior are involved.
45
+ - Suggested fix, if you have one.
46
+
47
+ We will acknowledge valid reports as quickly as possible and prioritize fixes that could leak secrets, trigger real external calls unexpectedly, or expose local data.
48
+
49
+ ## Out Of Scope
50
+
51
+ - Issues requiring malicious local filesystem access already authorized to the GhostAPI data directory.
52
+ - Vulnerabilities in unsupported Node.js versions.
53
+ - Reports without reproduction details.