@zivis/mcp 0.1.0-alpha.26 → 0.1.0-alpha.3

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 (328) hide show
  1. package/dist/api-client.d.ts +24 -1
  2. package/dist/api-client.js +52 -29
  3. package/dist/api-client.js.map +1 -0
  4. package/dist/auth/index.d.ts +22 -1
  5. package/dist/auth/index.js +38 -17
  6. package/dist/auth/index.js.map +1 -0
  7. package/dist/auth/jwt.d.ts +16 -0
  8. package/dist/auth/jwt.js +13 -0
  9. package/dist/auth/jwt.js.map +1 -0
  10. package/dist/auth/keychain.d.ts +32 -6
  11. package/dist/auth/keychain.js +114 -83
  12. package/dist/auth/keychain.js.map +1 -0
  13. package/dist/auth/oauth.d.ts +37 -2
  14. package/dist/auth/oauth.js +48 -38
  15. package/dist/auth/oauth.js.map +1 -0
  16. package/dist/auth/sessions.d.ts +25 -5
  17. package/dist/auth/sessions.js +39 -20
  18. package/dist/auth/sessions.js.map +1 -0
  19. package/dist/auth/token-refresh.d.ts +22 -2
  20. package/dist/auth/token-refresh.js +35 -32
  21. package/dist/auth/token-refresh.js.map +1 -0
  22. package/dist/cli.d.ts +18 -1
  23. package/dist/cli.js +908 -30
  24. package/dist/cli.js.map +1 -0
  25. package/dist/index.d.ts +6 -0
  26. package/dist/index.js +7 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/project-binding.d.ts +19 -2
  29. package/dist/project-binding.js +21 -38
  30. package/dist/project-binding.js.map +1 -0
  31. package/dist/resolve-application-id.d.ts +4 -0
  32. package/dist/resolve-application-id.js +5 -0
  33. package/dist/resolve-application-id.js.map +1 -0
  34. package/dist/sanitize.d.ts +21 -0
  35. package/dist/sanitize.js +41 -0
  36. package/dist/sanitize.js.map +1 -0
  37. package/dist/server.d.ts +13 -1
  38. package/dist/server.js +247 -122
  39. package/dist/server.js.map +1 -0
  40. package/dist/tools/check-project.d.ts +18 -5
  41. package/dist/tools/check-project.js +110 -122
  42. package/dist/tools/check-project.js.map +1 -0
  43. package/dist/tools/check-repo-trust.d.ts +19 -4
  44. package/dist/tools/check-repo-trust.js +47 -56
  45. package/dist/tools/check-repo-trust.js.map +1 -0
  46. package/dist/tools/create-diagram.d.ts +5 -0
  47. package/dist/tools/create-diagram.js +10 -0
  48. package/dist/tools/create-diagram.js.map +1 -0
  49. package/dist/tools/create-document.d.ts +5 -0
  50. package/dist/tools/create-document.js +6 -0
  51. package/dist/tools/create-document.js.map +1 -0
  52. package/dist/tools/discover-local-infra.d.ts +10 -0
  53. package/dist/tools/discover-local-infra.js +73 -3
  54. package/dist/tools/discover-local-infra.js.map +1 -0
  55. package/dist/tools/enterprise/capture-evidence.d.ts +54 -0
  56. package/dist/tools/enterprise/capture-evidence.js +72 -0
  57. package/dist/tools/enterprise/capture-evidence.js.map +1 -0
  58. package/dist/tools/enterprise/create-report-ticket.d.ts +34 -0
  59. package/dist/tools/enterprise/create-report-ticket.js +44 -0
  60. package/dist/tools/enterprise/create-report-ticket.js.map +1 -0
  61. package/dist/tools/enterprise/end-pentest-session.d.ts +33 -0
  62. package/dist/tools/enterprise/end-pentest-session.js +42 -0
  63. package/dist/tools/enterprise/end-pentest-session.js.map +1 -0
  64. package/dist/tools/enterprise/generate-report.d.ts +55 -0
  65. package/dist/tools/enterprise/generate-report.js +111 -0
  66. package/dist/tools/enterprise/generate-report.js.map +1 -0
  67. package/dist/tools/enterprise/get-org-zat.d.ts +5 -0
  68. package/dist/tools/enterprise/get-org-zat.js +6 -0
  69. package/dist/tools/enterprise/get-org-zat.js.map +1 -0
  70. package/dist/tools/enterprise/get-report-status.d.ts +27 -0
  71. package/dist/tools/enterprise/get-report-status.js +38 -0
  72. package/dist/tools/enterprise/get-report-status.js.map +1 -0
  73. package/dist/tools/enterprise/get-threat-model.d.ts +6 -1
  74. package/dist/tools/enterprise/get-threat-model.js +17 -52
  75. package/dist/tools/enterprise/get-threat-model.js.map +1 -0
  76. package/dist/tools/enterprise/list-agents.d.ts +42 -0
  77. package/dist/tools/enterprise/list-agents.js +95 -0
  78. package/dist/tools/enterprise/list-agents.js.map +1 -0
  79. package/dist/tools/enterprise/list-report-issues.d.ts +36 -0
  80. package/dist/tools/enterprise/list-report-issues.js +50 -0
  81. package/dist/tools/enterprise/list-report-issues.js.map +1 -0
  82. package/dist/tools/enterprise/list-threat-models.d.ts +5 -0
  83. package/dist/tools/enterprise/list-threat-models.js +8 -0
  84. package/dist/tools/enterprise/list-threat-models.js.map +1 -0
  85. package/dist/tools/enterprise/manage-actor.d.ts +6 -1
  86. package/dist/tools/enterprise/manage-actor.js +7 -14
  87. package/dist/tools/enterprise/manage-actor.js.map +1 -0
  88. package/dist/tools/enterprise/manage-attack-scenario.d.ts +6 -1
  89. package/dist/tools/enterprise/manage-attack-scenario.js +7 -13
  90. package/dist/tools/enterprise/manage-attack-scenario.js.map +1 -0
  91. package/dist/tools/enterprise/manage-component.d.ts +6 -1
  92. package/dist/tools/enterprise/manage-component.js +7 -20
  93. package/dist/tools/enterprise/manage-component.js.map +1 -0
  94. package/dist/tools/enterprise/manage-data-asset.d.ts +7 -2
  95. package/dist/tools/enterprise/manage-data-asset.js +7 -17
  96. package/dist/tools/enterprise/manage-data-asset.js.map +1 -0
  97. package/dist/tools/enterprise/manage-data-flow.d.ts +7 -2
  98. package/dist/tools/enterprise/manage-data-flow.js +7 -19
  99. package/dist/tools/enterprise/manage-data-flow.js.map +1 -0
  100. package/dist/tools/enterprise/manage-finding.d.ts +69 -0
  101. package/dist/tools/enterprise/manage-finding.js +106 -0
  102. package/dist/tools/enterprise/manage-finding.js.map +1 -0
  103. package/dist/tools/enterprise/manage-security-control.d.ts +6 -1
  104. package/dist/tools/enterprise/manage-security-control.js +7 -18
  105. package/dist/tools/enterprise/manage-security-control.js.map +1 -0
  106. package/dist/tools/enterprise/manage-test-case.d.ts +7 -2
  107. package/dist/tools/enterprise/manage-test-case.js +6 -8
  108. package/dist/tools/enterprise/manage-test-case.js.map +1 -0
  109. package/dist/tools/enterprise/promote-finding-to-issue.d.ts +36 -0
  110. package/dist/tools/enterprise/promote-finding-to-issue.js +65 -0
  111. package/dist/tools/enterprise/promote-finding-to-issue.js.map +1 -0
  112. package/dist/tools/enterprise/publish-report-version.d.ts +34 -0
  113. package/dist/tools/enterprise/publish-report-version.js +75 -0
  114. package/dist/tools/enterprise/publish-report-version.js.map +1 -0
  115. package/dist/tools/enterprise/publish-test-to-library.d.ts +31 -0
  116. package/dist/tools/enterprise/publish-test-to-library.js +40 -0
  117. package/dist/tools/enterprise/publish-test-to-library.js.map +1 -0
  118. package/dist/tools/enterprise/record-test-result.d.ts +67 -0
  119. package/dist/tools/enterprise/record-test-result.js +75 -0
  120. package/dist/tools/enterprise/record-test-result.js.map +1 -0
  121. package/dist/tools/enterprise/start-pentest-session.d.ts +35 -0
  122. package/dist/tools/enterprise/start-pentest-session.js +50 -0
  123. package/dist/tools/enterprise/start-pentest-session.js.map +1 -0
  124. package/dist/tools/enterprise/sync-report-section.d.ts +41 -0
  125. package/dist/tools/enterprise/sync-report-section.js +79 -0
  126. package/dist/tools/enterprise/sync-report-section.js.map +1 -0
  127. package/dist/tools/enterprise/update-report-issue.d.ts +55 -0
  128. package/dist/tools/enterprise/update-report-issue.js +69 -0
  129. package/dist/tools/enterprise/update-report-issue.js.map +1 -0
  130. package/dist/tools/generate-diagram.d.ts +6 -0
  131. package/dist/tools/generate-diagram.js +9 -0
  132. package/dist/tools/generate-diagram.js.map +1 -0
  133. package/dist/tools/get-agent-test-results.d.ts +41 -0
  134. package/dist/tools/get-agent-test-results.js +86 -0
  135. package/dist/tools/get-agent-test-results.js.map +1 -0
  136. package/dist/tools/get-application-overview.d.ts +5 -0
  137. package/dist/tools/get-application-overview.js +6 -0
  138. package/dist/tools/get-application-overview.js.map +1 -0
  139. package/dist/tools/get-application.d.ts +5 -0
  140. package/dist/tools/get-application.js +6 -0
  141. package/dist/tools/get-application.js.map +1 -0
  142. package/dist/tools/get-artifact-content.d.ts +29 -0
  143. package/dist/tools/get-artifact-content.js +86 -0
  144. package/dist/tools/get-artifact-content.js.map +1 -0
  145. package/dist/tools/get-diagram.d.ts +5 -0
  146. package/dist/tools/get-diagram.js +11 -1
  147. package/dist/tools/get-diagram.js.map +1 -0
  148. package/dist/tools/get-document.d.ts +5 -0
  149. package/dist/tools/get-document.js +6 -0
  150. package/dist/tools/get-document.js.map +1 -0
  151. package/dist/tools/get-finding-details.d.ts +28 -0
  152. package/dist/tools/get-finding-details.js +43 -0
  153. package/dist/tools/get-finding-details.js.map +1 -0
  154. package/dist/tools/get-findings.d.ts +57 -0
  155. package/dist/tools/get-findings.js +103 -0
  156. package/dist/tools/get-findings.js.map +1 -0
  157. package/dist/tools/get-oss-zat.d.ts +5 -0
  158. package/dist/tools/get-oss-zat.js +7 -0
  159. package/dist/tools/get-oss-zat.js.map +1 -0
  160. package/dist/tools/get-recon-scan.d.ts +27 -0
  161. package/dist/tools/get-recon-scan.js +46 -0
  162. package/dist/tools/get-recon-scan.js.map +1 -0
  163. package/dist/tools/get-scan-output.d.ts +27 -0
  164. package/dist/tools/get-scan-output.js +64 -0
  165. package/dist/tools/get-scan-output.js.map +1 -0
  166. package/dist/tools/get-scenario-details.d.ts +27 -0
  167. package/dist/tools/get-scenario-details.js +46 -0
  168. package/dist/tools/get-scenario-details.js.map +1 -0
  169. package/dist/tools/get-test-case-results.d.ts +37 -0
  170. package/dist/tools/get-test-case-results.js +66 -0
  171. package/dist/tools/get-test-case-results.js.map +1 -0
  172. package/dist/tools/get-test-details.d.ts +29 -0
  173. package/dist/tools/get-test-details.js +49 -0
  174. package/dist/tools/get-test-details.js.map +1 -0
  175. package/dist/tools/get-trust-keys.d.ts +5 -0
  176. package/dist/tools/get-trust-keys.js +6 -0
  177. package/dist/tools/get-trust-keys.js.map +1 -0
  178. package/dist/tools/import-openapi-endpoints.d.ts +5 -0
  179. package/dist/tools/import-openapi-endpoints.js +6 -0
  180. package/dist/tools/import-openapi-endpoints.js.map +1 -0
  181. package/dist/tools/inspect-zat.d.ts +5 -0
  182. package/dist/tools/inspect-zat.js +19 -0
  183. package/dist/tools/inspect-zat.js.map +1 -0
  184. package/dist/tools/list-agent-test-cases.d.ts +41 -0
  185. package/dist/tools/list-agent-test-cases.js +73 -0
  186. package/dist/tools/list-agent-test-cases.js.map +1 -0
  187. package/dist/tools/list-applications.d.ts +6 -1
  188. package/dist/tools/list-applications.js +6 -0
  189. package/dist/tools/list-applications.js.map +1 -0
  190. package/dist/tools/list-diagrams.d.ts +5 -0
  191. package/dist/tools/list-diagrams.js +6 -0
  192. package/dist/tools/list-diagrams.js.map +1 -0
  193. package/dist/tools/list-documents.d.ts +5 -0
  194. package/dist/tools/list-documents.js +6 -0
  195. package/dist/tools/list-documents.js.map +1 -0
  196. package/dist/tools/list-endpoints.d.ts +5 -0
  197. package/dist/tools/list-endpoints.js +6 -0
  198. package/dist/tools/list-endpoints.js.map +1 -0
  199. package/dist/tools/list-recon-scans.d.ts +36 -0
  200. package/dist/tools/list-recon-scans.js +74 -0
  201. package/dist/tools/list-recon-scans.js.map +1 -0
  202. package/dist/tools/list-scan-artifacts.d.ts +41 -0
  203. package/dist/tools/list-scan-artifacts.js +63 -0
  204. package/dist/tools/list-scan-artifacts.js.map +1 -0
  205. package/dist/tools/list-scans.d.ts +44 -0
  206. package/dist/tools/list-scans.js +91 -0
  207. package/dist/tools/list-scans.js.map +1 -0
  208. package/dist/tools/list-test-library.d.ts +44 -0
  209. package/dist/tools/list-test-library.js +83 -0
  210. package/dist/tools/list-test-library.js.map +1 -0
  211. package/dist/tools/list-test-scenarios.d.ts +31 -0
  212. package/dist/tools/list-test-scenarios.js +66 -0
  213. package/dist/tools/list-test-scenarios.js.map +1 -0
  214. package/dist/tools/local-scan.d.ts +40 -0
  215. package/dist/tools/local-scan.js +261 -0
  216. package/dist/tools/local-scan.js.map +1 -0
  217. package/dist/tools/manage-diagram.d.ts +5 -0
  218. package/dist/tools/manage-diagram.js +16 -0
  219. package/dist/tools/manage-diagram.js.map +1 -0
  220. package/dist/tools/open-in-ide.d.ts +13 -1
  221. package/dist/tools/open-in-ide.js +13 -0
  222. package/dist/tools/open-in-ide.js.map +1 -0
  223. package/dist/tools/run-test-scenario.d.ts +37 -0
  224. package/dist/tools/run-test-scenario.js +70 -0
  225. package/dist/tools/run-test-scenario.js.map +1 -0
  226. package/dist/tools/scan-pr.d.ts +27 -0
  227. package/dist/tools/scan-pr.js +51 -0
  228. package/dist/tools/scan-pr.js.map +1 -0
  229. package/dist/tools/security-review.d.ts +16 -0
  230. package/dist/tools/security-review.js +77 -63
  231. package/dist/tools/security-review.js.map +1 -0
  232. package/dist/tools/setup-red-team-target.d.ts +79 -0
  233. package/dist/tools/setup-red-team-target.js +430 -0
  234. package/dist/tools/setup-red-team-target.js.map +1 -0
  235. package/dist/tools/triage-finding.d.ts +47 -0
  236. package/dist/tools/triage-finding.js +116 -0
  237. package/dist/tools/triage-finding.js.map +1 -0
  238. package/dist/tools/update-document.d.ts +5 -0
  239. package/dist/tools/update-document.js +6 -0
  240. package/dist/tools/update-document.js.map +1 -0
  241. package/dist/tools/update-endpoint.d.ts +5 -0
  242. package/dist/tools/update-endpoint.js +7 -0
  243. package/dist/tools/update-endpoint.js.map +1 -0
  244. package/dist/tools/update-mermaid-source.d.ts +13 -0
  245. package/dist/tools/update-mermaid-source.js +14 -0
  246. package/dist/tools/update-mermaid-source.js.map +1 -0
  247. package/dist/tools/verify-trust-mark.d.ts +5 -0
  248. package/dist/tools/verify-trust-mark.js +6 -0
  249. package/dist/tools/verify-trust-mark.js.map +1 -0
  250. package/dist/types.d.ts +14 -14
  251. package/dist/types.js +28 -22
  252. package/dist/types.js.map +1 -0
  253. package/package.json +4 -24
  254. package/LICENSE +0 -201
  255. package/README.md +0 -19
  256. package/dist/lib/inspect-cache.d.ts +0 -10
  257. package/dist/lib/inspect-cache.js +0 -75
  258. package/dist/lib/next-steps.d.ts +0 -27
  259. package/dist/lib/next-steps.js +0 -21
  260. package/dist/matcher/ast-eval.d.ts +0 -8
  261. package/dist/matcher/ast-eval.js +0 -95
  262. package/dist/matcher/finding.d.ts +0 -55
  263. package/dist/matcher/finding.js +0 -1
  264. package/dist/matcher/index.d.ts +0 -8
  265. package/dist/matcher/index.js +0 -202
  266. package/dist/matcher/inference-candidates.d.ts +0 -26
  267. package/dist/matcher/inference-candidates.js +0 -81
  268. package/dist/matcher/walker.d.ts +0 -7
  269. package/dist/matcher/walker.js +0 -71
  270. package/dist/pattern-pack/index.d.ts +0 -125
  271. package/dist/pattern-pack/index.js +0 -189
  272. package/dist/pattern-packs/zivis-public-0.2.0/capsules/agents/privilege-separation.yaml +0 -224
  273. package/dist/pattern-packs/zivis-public-0.2.0/capsules/prompting/self-consistency-no-isolation.yaml +0 -237
  274. package/dist/pattern-packs/zivis-public-0.2.0/capsules/retrieval/context-injection-no-validator.yaml +0 -348
  275. package/dist/pattern-packs/zivis-public-0.2.0/capsules/security/late-org-filter.yaml +0 -266
  276. package/dist/pattern-packs/zivis-public-0.2.0/controls/external_validator_on_facts.yaml +0 -37
  277. package/dist/pattern-packs/zivis-public-0.2.0/controls/fact_validator_present.yaml +0 -68
  278. package/dist/pattern-packs/zivis-public-0.2.0/controls/human_approval_gate.yaml +0 -44
  279. package/dist/pattern-packs/zivis-public-0.2.0/controls/langgraph_state_machine_with_per_node_tools.yaml +0 -35
  280. package/dist/pattern-packs/zivis-public-0.2.0/controls/per_sample_retrieval_diversification.yaml +0 -38
  281. package/dist/pattern-packs/zivis-public-0.2.0/controls/prisma_extension_or_middleware_attaching_org_filter.yaml +0 -31
  282. package/dist/pattern-packs/zivis-public-0.2.0/controls/row_level_security_policy.yaml +0 -37
  283. package/dist/pattern-packs/zivis-public-0.2.0/controls/source_attribution_present.yaml +0 -58
  284. package/dist/pattern-packs/zivis-public-0.2.0/manifest.json +0 -167
  285. package/dist/pattern-packs/zivis-public-0.2.0/prompts/agents/privilege-separation/identify.md +0 -54
  286. package/dist/pattern-packs/zivis-public-0.2.0/prompts/prompting/self-consistency-no-isolation/identify.md +0 -60
  287. package/dist/pattern-packs/zivis-public-0.2.0/prompts/retrieval/context-injection-no-validator/identify.md +0 -109
  288. package/dist/pattern-packs/zivis-public-0.2.0/prompts/security/late-org-filter/identify.md +0 -78
  289. package/dist/prompts/audit-dependencies.d.ts +0 -2
  290. package/dist/prompts/audit-dependencies.js +0 -47
  291. package/dist/prompts/getting-started.d.ts +0 -2
  292. package/dist/prompts/getting-started.js +0 -37
  293. package/dist/prompts/index.d.ts +0 -2
  294. package/dist/prompts/index.js +0 -6
  295. package/dist/tools/enterprise/get-threat-model-artifact.d.ts +0 -24
  296. package/dist/tools/enterprise/get-threat-model-artifact.js +0 -68
  297. package/dist/tools/enterprise/list-attack-scenarios.d.ts +0 -24
  298. package/dist/tools/enterprise/list-attack-scenarios.js +0 -63
  299. package/dist/tools/enterprise/list-attack-step-library-tests.d.ts +0 -24
  300. package/dist/tools/enterprise/list-attack-step-library-tests.js +0 -55
  301. package/dist/tools/enterprise/list-threat-model-artifacts.d.ts +0 -55
  302. package/dist/tools/enterprise/list-threat-model-artifacts.js +0 -108
  303. package/dist/tools/enterprise/list-threat-model-review-items.d.ts +0 -30
  304. package/dist/tools/enterprise/list-threat-model-review-items.js +0 -54
  305. package/dist/tools/enterprise/list-threat-model-versions.d.ts +0 -24
  306. package/dist/tools/enterprise/list-threat-model-versions.js +0 -54
  307. package/dist/tools/enterprise/manage-threat-model-analysis.d.ts +0 -44
  308. package/dist/tools/enterprise/manage-threat-model-analysis.js +0 -83
  309. package/dist/tools/enterprise/manage-threat-model-review.d.ts +0 -38
  310. package/dist/tools/enterprise/manage-threat-model-review.js +0 -72
  311. package/dist/tools/get-started.d.ts +0 -18
  312. package/dist/tools/get-started.js +0 -470
  313. package/dist/tools/inspect.d.ts +0 -21
  314. package/dist/tools/inspect.js +0 -222
  315. package/dist/tools/manage-application.d.ts +0 -64
  316. package/dist/tools/manage-application.js +0 -129
  317. package/dist/tools/manage-endpoint-lifecycle.d.ts +0 -80
  318. package/dist/tools/manage-endpoint-lifecycle.js +0 -180
  319. package/dist/tools/threat-get-capsule.d.ts +0 -15
  320. package/dist/tools/threat-get-capsule.js +0 -53
  321. package/dist/tools/threat-get-inference-prompt.d.ts +0 -15
  322. package/dist/tools/threat-get-inference-prompt.js +0 -73
  323. package/dist/tools/threat-guide.d.ts +0 -28
  324. package/dist/tools/threat-guide.js +0 -175
  325. package/dist/tools/threat-list-relevant-capsules.d.ts +0 -17
  326. package/dist/tools/threat-list-relevant-capsules.js +0 -158
  327. package/dist/tools/threat-run-matcher.d.ts +0 -17
  328. package/dist/tools/threat-run-matcher.js +0 -145
@@ -1,3 +1,15 @@
1
+ /**
2
+ * OS Keychain credential storage
3
+ *
4
+ * Uses native OS CLI commands to store/retrieve credentials securely.
5
+ * No native npm dependencies (no keytar).
6
+ *
7
+ * - macOS: Keychain Services via `security` CLI
8
+ * - Linux: Secret Service API via `secret-tool` CLI
9
+ * - Windows: DPAPI via PowerShell
10
+ *
11
+ * Falls back to encrypted file if keychain CLI is unavailable.
12
+ */
1
13
  import { execFile } from "node:child_process";
2
14
  import { promisify } from "node:util";
3
15
  import * as fs from "node:fs/promises";
@@ -6,49 +18,48 @@ import * as os from "node:os";
6
18
  import * as crypto from "node:crypto";
7
19
  import { ENV_CONFIG } from "../types.js";
8
20
  const execFileAsync = promisify(execFile);
9
- function resolvedStorage(storage) {
10
- return (storage ?? {
11
- keychainPrefix: ENV_CONFIG.keychainPrefix,
12
- configDir: ENV_CONFIG.configDir,
13
- });
14
- }
21
+ // Use environment-aware prefix so staging and production credentials are isolated
22
+ const SERVICE_PREFIX = ENV_CONFIG.keychainPrefix;
23
+ /**
24
+ * Returns the keychain account key for a given session.
25
+ * - No session or undefined → "oauth" (backward compatible)
26
+ * - Named session → "oauth.{session}"
27
+ */
15
28
  export function getSessionAccount(session) {
16
29
  return session ? `oauth.${session}` : "oauth";
17
30
  }
18
- function getServiceName(account, keychainPrefix) {
19
- return `${keychainPrefix}.${account}`;
31
+ function getServiceName(account) {
32
+ return `${SERVICE_PREFIX}.${account}`;
20
33
  }
21
- function getFallbackDir(configDir) {
34
+ function getFallbackDir() {
35
+ // Use environment-aware config dir so staging and production are isolated
36
+ const configDir = ENV_CONFIG.configDir;
22
37
  if (process.platform === "win32") {
23
38
  return path.join(process.env.APPDATA || os.homedir(), configDir);
24
39
  }
25
40
  return path.join(os.homedir(), ".config", configDir);
26
41
  }
27
- function getFallbackPath(account, storage) {
28
- return path.join(getFallbackDir(storage.configDir), `${account}.enc`);
29
- }
30
- async function macosDeleteAll(service) {
31
- for (let i = 0; i < 100; i++) {
32
- try {
33
- await execFileAsync("security", [
34
- "delete-generic-password",
35
- "-a",
36
- "zivis-mcp",
37
- "-s",
38
- service,
39
- ]);
40
- }
41
- catch {
42
- return;
43
- }
44
- }
42
+ function getFallbackPath(account) {
43
+ return path.join(getFallbackDir(), `${account}.enc`);
45
44
  }
46
- async function macosStore(account, value, keychainPrefix) {
47
- const service = getServiceName(account, keychainPrefix);
48
- await macosDeleteAll(service);
45
+ // ── macOS Keychain ──
46
+ async function macosStore(account, value) {
47
+ const service = getServiceName(account);
48
+ // Delete existing entry first (ignore errors if not found)
49
+ try {
50
+ await execFileAsync("security", [
51
+ "delete-generic-password",
52
+ "-a",
53
+ "zivis-mcp",
54
+ "-s",
55
+ service,
56
+ ]);
57
+ }
58
+ catch {
59
+ // Entry didn't exist, that's fine
60
+ }
49
61
  await execFileAsync("security", [
50
62
  "add-generic-password",
51
- "-U",
52
63
  "-a",
53
64
  "zivis-mcp",
54
65
  "-s",
@@ -57,8 +68,8 @@ async function macosStore(account, value, keychainPrefix) {
57
68
  value,
58
69
  ]);
59
70
  }
60
- async function macosRead(account, keychainPrefix) {
61
- const service = getServiceName(account, keychainPrefix);
71
+ async function macosRead(account) {
72
+ const service = getServiceName(account);
62
73
  try {
63
74
  const { stdout } = await execFileAsync("security", [
64
75
  "find-generic-password",
@@ -74,29 +85,43 @@ async function macosRead(account, keychainPrefix) {
74
85
  return null;
75
86
  }
76
87
  }
77
- async function macosDelete(account, keychainPrefix) {
78
- await macosDeleteAll(getServiceName(account, keychainPrefix));
88
+ async function macosDelete(account) {
89
+ const service = getServiceName(account);
90
+ try {
91
+ await execFileAsync("security", [
92
+ "delete-generic-password",
93
+ "-a",
94
+ "zivis-mcp",
95
+ "-s",
96
+ service,
97
+ ]);
98
+ }
99
+ catch {
100
+ // Entry didn't exist
101
+ }
79
102
  }
80
- async function linuxStore(account, value, keychainPrefix) {
103
+ // ── Linux Secret Service ──
104
+ async function linuxStore(account, value) {
81
105
  const child = execFileAsync("secret-tool", [
82
106
  "store",
83
107
  "--label",
84
108
  `ZIVIS MCP ${account}`,
85
109
  "service",
86
- keychainPrefix,
110
+ SERVICE_PREFIX,
87
111
  "account",
88
112
  account,
89
113
  ]);
114
+ // secret-tool reads value from stdin
90
115
  child.child.stdin?.write(value);
91
116
  child.child.stdin?.end();
92
117
  await child;
93
118
  }
94
- async function linuxRead(account, keychainPrefix) {
119
+ async function linuxRead(account) {
95
120
  try {
96
121
  const { stdout } = await execFileAsync("secret-tool", [
97
122
  "lookup",
98
123
  "service",
99
- keychainPrefix,
124
+ SERVICE_PREFIX,
100
125
  "account",
101
126
  account,
102
127
  ]);
@@ -106,39 +131,44 @@ async function linuxRead(account, keychainPrefix) {
106
131
  return null;
107
132
  }
108
133
  }
109
- async function linuxDelete(account, keychainPrefix) {
134
+ async function linuxDelete(account) {
110
135
  try {
111
136
  await execFileAsync("secret-tool", [
112
137
  "clear",
113
138
  "service",
114
- keychainPrefix,
139
+ SERVICE_PREFIX,
115
140
  "account",
116
141
  account,
117
142
  ]);
118
143
  }
119
144
  catch {
145
+ // Entry didn't exist
120
146
  }
121
147
  }
148
+ // ── Encrypted File Fallback (Windows + fallback for all platforms) ──
122
149
  function deriveKey() {
150
+ // Use machine-specific data as encryption key seed
123
151
  const seed = `zivis-mcp:${os.hostname()}:${os.userInfo().username}`;
124
152
  return crypto.createHash("sha256").update(seed).digest();
125
153
  }
126
- async function fileStore(account, value, storage) {
154
+ async function fileStore(account, value) {
127
155
  const key = deriveKey();
128
156
  const iv = crypto.randomBytes(16);
157
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
129
158
  const cipher = crypto.createCipheriv("aes-256-cbc", key, iv);
130
159
  let encrypted = cipher.update(value, "utf8", "hex");
131
160
  encrypted += cipher.final("hex");
132
161
  const data = JSON.stringify({ iv: iv.toString("hex"), data: encrypted });
133
- const dir = getFallbackDir(storage.configDir);
162
+ const dir = getFallbackDir();
134
163
  await fs.mkdir(dir, { recursive: true });
135
- await fs.writeFile(getFallbackPath(account, storage), data, { mode: 0o600 });
164
+ await fs.writeFile(getFallbackPath(account), data, { mode: 0o600 });
136
165
  }
137
- async function fileRead(account, storage) {
166
+ async function fileRead(account) {
138
167
  try {
139
- const raw = await fs.readFile(getFallbackPath(account, storage), "utf8");
168
+ const raw = await fs.readFile(getFallbackPath(account), "utf8");
140
169
  const { iv, data } = JSON.parse(raw);
141
170
  const key = deriveKey();
171
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
172
  const decipher = crypto.createDecipheriv("aes-256-cbc", key, Buffer.from(iv, "hex"));
143
173
  let decrypted = decipher.update(data, "hex", "utf8");
144
174
  decrypted += decipher.final("utf8");
@@ -148,13 +178,15 @@ async function fileRead(account, storage) {
148
178
  return null;
149
179
  }
150
180
  }
151
- async function fileDelete(account, storage) {
181
+ async function fileDelete(account) {
152
182
  try {
153
- await fs.unlink(getFallbackPath(account, storage));
183
+ await fs.unlink(getFallbackPath(account));
154
184
  }
155
185
  catch {
186
+ // File didn't exist
156
187
  }
157
188
  }
189
+ // ── Platform Detection & Dispatch ──
158
190
  async function isKeychainAvailable() {
159
191
  try {
160
192
  if (process.platform === "darwin") {
@@ -178,58 +210,56 @@ async function useKeychain() {
178
210
  }
179
211
  return keychainAvailable;
180
212
  }
181
- export async function keychainStore(account, value, storage) {
182
- const st = resolvedStorage(storage);
183
- await fileStore(account, value, st);
213
+ // ── Public API ──
214
+ export async function keychainStore(account, value) {
215
+ // Always store to encrypted file as fallback (for environments where keychain CLI
216
+ // may not be available, e.g., MCP servers spawned by IDEs with different $PATH)
217
+ await fileStore(account, value);
218
+ // Also store to native keychain if available
184
219
  if (await useKeychain()) {
185
220
  if (process.platform === "darwin") {
186
- await macosStore(account, value, st.keychainPrefix);
221
+ await macosStore(account, value);
187
222
  }
188
223
  else if (process.platform === "linux") {
189
- await linuxStore(account, value, st.keychainPrefix);
224
+ await linuxStore(account, value);
190
225
  }
191
226
  }
192
227
  }
193
- const LEGACY_KEYCHAIN_PREFIX = "io.zivis.mcp";
194
- async function readFromBucket(account, storage) {
228
+ export async function keychainRead(account) {
195
229
  if (await useKeychain()) {
196
230
  if (process.platform === "darwin")
197
- return macosRead(account, storage.keychainPrefix);
231
+ return macosRead(account);
198
232
  if (process.platform === "linux")
199
- return linuxRead(account, storage.keychainPrefix);
200
- }
201
- return fileRead(account, storage);
202
- }
203
- export async function keychainRead(account, storage) {
204
- const st = resolvedStorage(storage);
205
- const primary = await readFromBucket(account, st);
206
- if (primary !== null)
207
- return primary;
208
- if (st.keychainPrefix !== LEGACY_KEYCHAIN_PREFIX) {
209
- return await readFromBucket(account, {
210
- ...st,
211
- keychainPrefix: LEGACY_KEYCHAIN_PREFIX,
212
- });
213
- }
214
- return null;
215
- }
216
- export async function keychainDelete(account, storage) {
217
- const st = resolvedStorage(storage);
218
- await fileDelete(account, st);
233
+ return linuxRead(account);
234
+ }
235
+ return fileRead(account);
236
+ }
237
+ export async function keychainDelete(account) {
219
238
  if (await useKeychain()) {
220
239
  if (process.platform === "darwin")
221
- return macosDelete(account, st.keychainPrefix);
240
+ return macosDelete(account);
222
241
  if (process.platform === "linux")
223
- return linuxDelete(account, st.keychainPrefix);
242
+ return linuxDelete(account);
224
243
  }
244
+ return fileDelete(account);
225
245
  }
226
- export async function keychainClearSession(session, storage) {
227
- await keychainDelete(getSessionAccount(session), storage);
246
+ /**
247
+ * Delete credentials for a specific session
248
+ */
249
+ export async function keychainClearSession(session) {
250
+ await keychainDelete(getSessionAccount(session));
228
251
  }
229
- export async function keychainClearAll(storage) {
230
- await keychainDelete("oauth", storage);
231
- await keychainDelete("apikey", storage);
252
+ /**
253
+ * Delete all stored credentials (default OAuth + API key).
254
+ * Does NOT clear named sessions — use keychainClearSession() for those.
255
+ */
256
+ export async function keychainClearAll() {
257
+ await keychainDelete("oauth");
258
+ await keychainDelete("apikey");
232
259
  }
260
+ /**
261
+ * Returns the storage mechanism name for display purposes
262
+ */
233
263
  export function getStorageName() {
234
264
  if (process.platform === "darwin")
235
265
  return "macOS Keychain";
@@ -239,3 +269,4 @@ export function getStorageName() {
239
269
  return "encrypted file";
240
270
  return "encrypted file";
241
271
  }
272
+ //# sourceMappingURL=keychain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,44 @@
1
+ /**
2
+ * OAuth PKCE Authentication Flow
3
+ *
4
+ * Authorization Code Flow with Proof Key for Code Exchange (PKCE)
5
+ * for native/CLI applications. Uses WorkOS as the identity provider.
6
+ *
7
+ * Flow:
8
+ * 1. Generate PKCE code_verifier + code_challenge
9
+ * 2. Start localhost callback server
10
+ * 3. Open browser to WorkOS authorization URL
11
+ * 4. Receive authorization code via callback
12
+ * 5. Exchange code + verifier for tokens
13
+ * 6. Store tokens in OS keychain
14
+ */
1
15
  import type { OAuthTokens, ZivisConfig } from "../types.js";
16
+ /**
17
+ * Run the full OAuth PKCE login flow.
18
+ *
19
+ * 1. Generate PKCE pair + state
20
+ * 2. Start localhost callback server
21
+ * 3. Open browser to WorkOS
22
+ * 4. Wait for callback
23
+ * 5. Exchange code for tokens
24
+ * 6. Store tokens in keychain (under session-qualified key)
25
+ *
26
+ * @param config - Server configuration
27
+ * @param session - Optional named session for multi-tenant isolation
28
+ * @param organizationId - Optional WorkOS org ID to scope the login to a specific org
29
+ * @param opts - Display and confirmation options
30
+ * @returns The OAuth tokens
31
+ */
2
32
  export interface LoginOptions {
33
+ /** Human-readable org name, shown in the pre-browser confirmation prompt. */
3
34
  orgName?: string;
4
- sessionLabel?: string;
35
+ /** Skip the pre-browser confirmation prompt (for scripted/interactive-wizard callers). */
5
36
  skipConfirm?: boolean;
37
+ /**
38
+ * Instead of auto-opening the browser, print the auth URL and wait for the user
39
+ * to paste it into a private/incognito window manually. Useful when the browser
40
+ * already has a session for a different org that would override the requested org.
41
+ */
6
42
  printUrlOnly?: boolean;
7
- incognito?: boolean;
8
43
  }
9
44
  export declare function login(config?: ZivisConfig, session?: string, organizationId?: string, opts?: LoginOptions): Promise<OAuthTokens>;
@@ -1,3 +1,17 @@
1
+ /**
2
+ * OAuth PKCE Authentication Flow
3
+ *
4
+ * Authorization Code Flow with Proof Key for Code Exchange (PKCE)
5
+ * for native/CLI applications. Uses WorkOS as the identity provider.
6
+ *
7
+ * Flow:
8
+ * 1. Generate PKCE code_verifier + code_challenge
9
+ * 2. Start localhost callback server
10
+ * 3. Open browser to WorkOS authorization URL
11
+ * 4. Receive authorization code via callback
12
+ * 5. Exchange code + verifier for tokens
13
+ * 6. Store tokens in OS keychain
14
+ */
1
15
  import * as crypto from "node:crypto";
2
16
  import * as http from "node:http";
3
17
  import * as readline from "node:readline/promises";
@@ -5,8 +19,8 @@ import { URL } from "node:url";
5
19
  import open from "open";
6
20
  import { keychainStore, getSessionAccount } from "./keychain.js";
7
21
  import { decodeJwtPayload } from "./jwt.js";
8
- import { DEFAULT_CONFIG, credentialStorageFromConfig } from "../types.js";
9
- const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
22
+ import { DEFAULT_CONFIG } from "../types.js";
23
+ const LOGIN_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
10
24
  function generatePKCE() {
11
25
  const verifier = crypto.randomBytes(32).toString("base64url");
12
26
  const challenge = crypto
@@ -28,15 +42,29 @@ function buildAuthUrl(config, codeChallenge, state, organizationId) {
28
42
  state,
29
43
  scope: "openid profile email offline_access",
30
44
  });
45
+ // Scope the OAuth session to a specific org so the JWT has the correct org_id
31
46
  if (organizationId) {
32
47
  params.set("organization_id", organizationId);
33
48
  }
49
+ // Force the WorkOS login screen even when an active session exists.
50
+ // Why: users in multiple orgs must visually confirm which identity/org they're using —
51
+ // silent SSO could let them accidentally bind the wrong org to a project.
34
52
  params.set("prompt", "login");
53
+ // Handle both WorkOS (auth.workos.com -> /authorize) and custom AuthKit (authkit.app -> /oauth2/authorize)
35
54
  const isAuthKit = config.oauthApiUrl.includes("authkit.app");
36
55
  const authPath = isAuthKit ? "/oauth2/authorize" : "/authorize";
37
56
  const authUrl = `${config.oauthApiUrl}${authPath}?${params.toString()}`;
57
+ // We used to chain custom AuthKit hosts through /logout?return_to=... so
58
+ // browser cookies did not override organization_id. AuthKit OIDC metadata
59
+ // does not advertise end_session_endpoint, and *.authkit.app/logout returns
60
+ // 404 — so that redirect is unusable. Rely on prompt=login plus
61
+ // organization_id for org-scoped flows instead.
38
62
  return authUrl;
39
63
  }
64
+ /**
65
+ * Start a localhost HTTP server to receive the OAuth callback.
66
+ * Returns the authorization code on success.
67
+ */
40
68
  function startCallbackServer(port, expectedState) {
41
69
  return new Promise((resolve, reject) => {
42
70
  const server = http.createServer((req, res) => {
@@ -70,6 +98,7 @@ function startCallbackServer(port, expectedState) {
70
98
  resolve(code);
71
99
  }
72
100
  else {
101
+ // 404 for any other path
73
102
  res.writeHead(404, { "Content-Type": "text/html" });
74
103
  res.end(`<!DOCTYPE html>
75
104
  <html>
@@ -85,6 +114,7 @@ function startCallbackServer(port, expectedState) {
85
114
  reject(new Error(`Failed to start callback server on port ${port}: ${err.message}`));
86
115
  });
87
116
  server.listen(port, "127.0.0.1");
117
+ // Timeout
88
118
  setTimeout(() => {
89
119
  server.close();
90
120
  reject(new Error("Authentication timed out after 5 minutes"));
@@ -113,7 +143,11 @@ function callbackHtml(success, errorMessage) {
113
143
  </body>
114
144
  </html>`;
115
145
  }
146
+ /**
147
+ * Exchange authorization code for tokens via WorkOS token endpoint
148
+ */
116
149
  async function exchangeCodeForTokens(config, code, codeVerifier) {
150
+ // Handle both WorkOS (auth.workos.com -> /oauth/token) and custom AuthKit (authkit.app -> /oauth2/token)
117
151
  const tokenPath = config.oauthApiUrl.includes("authkit.app") ? "/oauth2/token" : "/oauth/token";
118
152
  const tokenUrl = `${config.oauthApiUrl}${tokenPath}`;
119
153
  const response = await fetch(tokenUrl, {
@@ -135,14 +169,6 @@ async function exchangeCodeForTokens(config, code, codeVerifier) {
135
169
  throw new Error(errorMsg);
136
170
  }
137
171
  const data = (await response.json());
138
- if (!data.refresh_token) {
139
- console.error("[zivis] WARNING: WorkOS did not return a refresh_token. " +
140
- "Verify the OAuth client has Refresh Tokens / offline_access enabled in the WorkOS dashboard. " +
141
- "Without this, sessions will expire and require manual re-login.");
142
- }
143
- else {
144
- console.error("[zivis] Token exchange complete — refresh_token received, session will auto-renew.");
145
- }
146
172
  return {
147
173
  access_token: data.access_token,
148
174
  refresh_token: data.refresh_token,
@@ -157,12 +183,13 @@ export async function login(config = DEFAULT_CONFIG, session, organizationId, op
157
183
  const { verifier, challenge } = generatePKCE();
158
184
  const state = generateState();
159
185
  const authUrl = buildAuthUrl(config, challenge, state, organizationId);
186
+ // Pre-browser confirmation: only when an org is scoped AND the terminal is interactive.
187
+ // Protects users in multiple orgs from accidentally authenticating to the wrong tenant.
160
188
  if (organizationId && !opts.skipConfirm && process.stderr.isTTY && process.stdin.isTTY) {
161
189
  const orgLabel = opts.orgName
162
190
  ? `${opts.orgName} (${organizationId})`
163
191
  : organizationId;
164
- const displaySession = opts.sessionLabel ?? session;
165
- const sessionLabel = displaySession ? ` as session "${displaySession}"` : "";
192
+ const sessionLabel = session ? ` as session "${session}"` : "";
166
193
  console.error("");
167
194
  console.error(`[zivis] About to authenticate to org: ${orgLabel}${sessionLabel}`);
168
195
  const rl = readline.createInterface({
@@ -182,6 +209,7 @@ export async function login(config = DEFAULT_CONFIG, session, organizationId, op
182
209
  else if (organizationId) {
183
210
  console.error(`[zivis] Login scoped to organization: ${organizationId}`);
184
211
  }
212
+ // Start callback server before opening browser
185
213
  const codePromise = startCallbackServer(config.callbackPort, state);
186
214
  if (opts.printUrlOnly) {
187
215
  console.error("[zivis] Open this URL in a private/incognito browser window:");
@@ -190,38 +218,18 @@ export async function login(config = DEFAULT_CONFIG, session, organizationId, op
190
218
  console.error("");
191
219
  console.error("[zivis] Waiting for login...");
192
220
  }
193
- else if (opts.incognito) {
194
- let opened = false;
195
- for (const app of [
196
- { name: "google chrome", args: ["--incognito"] },
197
- { name: "chromium", args: ["--incognito"] },
198
- { name: "firefox", args: ["-private-window"] },
199
- ]) {
200
- try {
201
- await open(authUrl, { app: { name: app.name, arguments: [authUrl, ...app.args] } });
202
- console.error(`[zivis] Opened private window in ${app.name} — waiting for login...`);
203
- opened = true;
204
- break;
205
- }
206
- catch {
207
- }
208
- }
209
- if (!opened) {
210
- console.error("[zivis] Could not open an incognito window automatically.");
211
- console.error("[zivis] Paste this URL into a private/incognito browser window:");
212
- console.error("");
213
- console.error(` ${authUrl}`);
214
- console.error("");
215
- console.error("[zivis] Waiting for login...");
216
- }
217
- }
218
221
  else {
219
222
  console.error("[zivis] Opening browser for authentication...");
220
223
  await open(authUrl);
221
224
  console.error("[zivis] Waiting for login...");
222
225
  }
226
+ // Wait for the authorization code
223
227
  const code = await codePromise;
228
+ // Exchange code for tokens
224
229
  const tokens = await exchangeCodeForTokens(config, code, verifier);
230
+ // Hard verification: if we requested a specific org, the returned JWT
231
+ // MUST be scoped to that org. Refuse to store mismatched tokens — this is
232
+ // the last-ditch guard against silently binding the wrong tenant.
225
233
  if (organizationId) {
226
234
  const claims = decodeJwtPayload(tokens.access_token);
227
235
  const jwtOrgId = claims?.org_id;
@@ -235,6 +243,8 @@ export async function login(config = DEFAULT_CONFIG, session, organizationId, op
235
243
  }
236
244
  console.error(`[zivis] \u2713 JWT org_id verified: ${jwtOrgId}`);
237
245
  }
238
- await keychainStore(getSessionAccount(session), JSON.stringify(tokens), credentialStorageFromConfig(config));
246
+ // Store in keychain (session-qualified key for multi-tenant isolation)
247
+ await keychainStore(getSessionAccount(session), JSON.stringify(tokens));
239
248
  return tokens;
240
249
  }
250
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,28 @@
1
+ /**
2
+ * Session Index Management
3
+ *
4
+ * Tracks named OAuth sessions in a JSON file so users can list
5
+ * and manage multiple tenant sessions without enumerating keychain entries.
6
+ *
7
+ * Session index file: ~/.config/{configDir}/sessions.json
8
+ */
1
9
  import type { SessionIndex, SessionInfo } from "../types.js";
2
- import { type CredentialStorage } from "../types.js";
3
- export declare function loadSessionIndex(storage?: CredentialStorage): Promise<SessionIndex>;
4
- export declare function saveSessionEntry(name: string, email: string, storage?: CredentialStorage): Promise<void>;
5
- export declare function removeSessionEntry(name: string, storage?: CredentialStorage): Promise<void>;
6
- export declare function listSessions(storage?: CredentialStorage): Promise<Array<{
10
+ /**
11
+ * Load the session index from disk.
12
+ * Returns an empty object if the file doesn't exist.
13
+ */
14
+ export declare function loadSessionIndex(): Promise<SessionIndex>;
15
+ /**
16
+ * Add or update a session entry in the index.
17
+ */
18
+ export declare function saveSessionEntry(name: string, email: string): Promise<void>;
19
+ /**
20
+ * Remove a session entry from the index.
21
+ */
22
+ export declare function removeSessionEntry(name: string): Promise<void>;
23
+ /**
24
+ * List all sessions with their metadata.
25
+ */
26
+ export declare function listSessions(): Promise<Array<{
7
27
  name: string;
8
28
  } & SessionInfo>>;