@cleocode/core 2026.9.16 → 2026.9.18

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 (236) hide show
  1. package/dist/changesets/parser.d.ts.map +1 -1
  2. package/dist/changesets/parser.js +67 -0
  3. package/dist/changesets/parser.js.map +1 -1
  4. package/dist/crypto/credentials.d.ts +128 -26
  5. package/dist/crypto/credentials.d.ts.map +1 -1
  6. package/dist/crypto/credentials.js +183 -142
  7. package/dist/crypto/credentials.js.map +1 -1
  8. package/dist/docs/export-document.js +14705 -12949
  9. package/dist/docs/export-document.js.map +3 -3
  10. package/dist/doctor/index.d.ts +1 -1
  11. package/dist/doctor/index.d.ts.map +1 -1
  12. package/dist/doctor/index.js +1 -1
  13. package/dist/doctor/index.js.map +1 -1
  14. package/dist/doctor/nexus-schema-residency.d.ts +1 -1
  15. package/dist/doctor/nexus-schema-residency.d.ts.map +1 -1
  16. package/dist/doctor/nexus-schema-residency.js +1 -0
  17. package/dist/doctor/nexus-schema-residency.js.map +1 -1
  18. package/dist/doctor/project-identity.d.ts +124 -0
  19. package/dist/doctor/project-identity.d.ts.map +1 -0
  20. package/dist/doctor/project-identity.js +307 -0
  21. package/dist/doctor/project-identity.js.map +1 -0
  22. package/dist/doctor/superseded-store.d.ts +8 -0
  23. package/dist/doctor/superseded-store.d.ts.map +1 -1
  24. package/dist/doctor/superseded-store.js +48 -3
  25. package/dist/doctor/superseded-store.js.map +1 -1
  26. package/dist/init.d.ts +7 -0
  27. package/dist/init.d.ts.map +1 -1
  28. package/dist/init.js +17 -2
  29. package/dist/init.js.map +1 -1
  30. package/dist/internal.d.ts +6 -3
  31. package/dist/internal.d.ts.map +1 -1
  32. package/dist/internal.js +4 -2
  33. package/dist/internal.js.map +1 -1
  34. package/dist/llm/credentials-store.d.ts +10 -0
  35. package/dist/llm/credentials-store.d.ts.map +1 -1
  36. package/dist/llm/credentials-store.js +7 -1
  37. package/dist/llm/credentials-store.js.map +1 -1
  38. package/dist/llm/plugin-facade.js +13368 -1550
  39. package/dist/llm/plugin-facade.js.map +3 -3
  40. package/dist/nexus/analyze-orchestrator.d.ts +20 -3
  41. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  42. package/dist/nexus/analyze-orchestrator.js +210 -16
  43. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  44. package/dist/nexus/assessment-store.d.ts +86 -0
  45. package/dist/nexus/assessment-store.d.ts.map +1 -0
  46. package/dist/nexus/assessment-store.js +113 -0
  47. package/dist/nexus/assessment-store.js.map +1 -0
  48. package/dist/nexus/freshness.d.ts +131 -0
  49. package/dist/nexus/freshness.d.ts.map +1 -0
  50. package/dist/nexus/freshness.js +391 -0
  51. package/dist/nexus/freshness.js.map +1 -0
  52. package/dist/nexus/graph-manifest.d.ts +88 -0
  53. package/dist/nexus/graph-manifest.d.ts.map +1 -0
  54. package/dist/nexus/graph-manifest.js +114 -0
  55. package/dist/nexus/graph-manifest.js.map +1 -0
  56. package/dist/nexus/knowledge.d.ts +21 -1
  57. package/dist/nexus/knowledge.d.ts.map +1 -1
  58. package/dist/nexus/knowledge.js +74 -37
  59. package/dist/nexus/knowledge.js.map +1 -1
  60. package/dist/nexus/path-map.d.ts +55 -0
  61. package/dist/nexus/path-map.d.ts.map +1 -0
  62. package/dist/nexus/path-map.js +87 -0
  63. package/dist/nexus/path-map.js.map +1 -0
  64. package/dist/nexus/projects-clean.d.ts +21 -28
  65. package/dist/nexus/projects-clean.d.ts.map +1 -1
  66. package/dist/nexus/projects-clean.js +168 -85
  67. package/dist/nexus/projects-clean.js.map +1 -1
  68. package/dist/nexus/query.d.ts.map +1 -1
  69. package/dist/nexus/query.js +3 -2
  70. package/dist/nexus/query.js.map +1 -1
  71. package/dist/nexus/registry-hygiene.d.ts +70 -0
  72. package/dist/nexus/registry-hygiene.d.ts.map +1 -0
  73. package/dist/nexus/registry-hygiene.js +113 -0
  74. package/dist/nexus/registry-hygiene.js.map +1 -0
  75. package/dist/nexus/registry.d.ts +2 -2
  76. package/dist/nexus/registry.d.ts.map +1 -1
  77. package/dist/nexus/registry.js +48 -12
  78. package/dist/nexus/registry.js.map +1 -1
  79. package/dist/paths.d.ts +26 -0
  80. package/dist/paths.d.ts.map +1 -1
  81. package/dist/paths.js +99 -6
  82. package/dist/paths.js.map +1 -1
  83. package/dist/release/index.d.ts +1 -1
  84. package/dist/release/index.d.ts.map +1 -1
  85. package/dist/release/index.js.map +1 -1
  86. package/dist/release/plan.d.ts +84 -2
  87. package/dist/release/plan.d.ts.map +1 -1
  88. package/dist/release/plan.js +61 -14
  89. package/dist/release/plan.js.map +1 -1
  90. package/dist/release/pr-evidence.d.ts +81 -1
  91. package/dist/release/pr-evidence.d.ts.map +1 -1
  92. package/dist/release/pr-evidence.js +149 -9
  93. package/dist/release/pr-evidence.js.map +1 -1
  94. package/dist/render/nexus/graph/index.d.ts.map +1 -1
  95. package/dist/render/nexus/graph/index.js +8 -0
  96. package/dist/render/nexus/graph/index.js.map +1 -1
  97. package/dist/scaffold/ensure-config.d.ts +12 -3
  98. package/dist/scaffold/ensure-config.d.ts.map +1 -1
  99. package/dist/scaffold/ensure-config.js +61 -38
  100. package/dist/scaffold/ensure-config.js.map +1 -1
  101. package/dist/scaffold/project-identity.d.ts +136 -0
  102. package/dist/scaffold/project-identity.d.ts.map +1 -0
  103. package/dist/scaffold/project-identity.js +225 -0
  104. package/dist/scaffold/project-identity.js.map +1 -0
  105. package/dist/selfimprove/fix-gen.js +13319 -1556
  106. package/dist/selfimprove/fix-gen.js.map +3 -3
  107. package/dist/store/agent-api-key.d.ts +114 -0
  108. package/dist/store/agent-api-key.d.ts.map +1 -0
  109. package/dist/store/agent-api-key.js +136 -0
  110. package/dist/store/agent-api-key.js.map +1 -0
  111. package/dist/store/agent-registry-accessor.d.ts +4 -2
  112. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  113. package/dist/store/agent-registry-accessor.js +39 -89
  114. package/dist/store/agent-registry-accessor.js.map +1 -1
  115. package/dist/store/api-key-kdf.d.ts +7 -0
  116. package/dist/store/api-key-kdf.d.ts.map +1 -1
  117. package/dist/store/api-key-kdf.js +7 -0
  118. package/dist/store/api-key-kdf.js.map +1 -1
  119. package/dist/store/backup-crypto.d.ts +49 -0
  120. package/dist/store/backup-crypto.d.ts.map +1 -1
  121. package/dist/store/backup-crypto.js +154 -0
  122. package/dist/store/backup-crypto.js.map +1 -1
  123. package/dist/store/credential-transfer.d.ts +303 -0
  124. package/dist/store/credential-transfer.d.ts.map +1 -0
  125. package/dist/store/credential-transfer.js +774 -0
  126. package/dist/store/credential-transfer.js.map +1 -0
  127. package/dist/store/exodus/column-transforms.d.ts +79 -4
  128. package/dist/store/exodus/column-transforms.d.ts.map +1 -1
  129. package/dist/store/exodus/column-transforms.js +121 -4
  130. package/dist/store/exodus/column-transforms.js.map +1 -1
  131. package/dist/store/exodus/index.d.ts +1 -0
  132. package/dist/store/exodus/index.d.ts.map +1 -1
  133. package/dist/store/exodus/index.js +1 -0
  134. package/dist/store/exodus/index.js.map +1 -1
  135. package/dist/store/exodus/migrate.d.ts +17 -1
  136. package/dist/store/exodus/migrate.d.ts.map +1 -1
  137. package/dist/store/exodus/migrate.js +155 -33
  138. package/dist/store/exodus/migrate.js.map +1 -1
  139. package/dist/store/exodus/on-open.d.ts +14 -0
  140. package/dist/store/exodus/on-open.d.ts.map +1 -1
  141. package/dist/store/exodus/on-open.js +115 -6
  142. package/dist/store/exodus/on-open.js.map +1 -1
  143. package/dist/store/exodus/reconcile.d.ts +103 -0
  144. package/dist/store/exodus/reconcile.d.ts.map +1 -0
  145. package/dist/store/exodus/reconcile.js +728 -0
  146. package/dist/store/exodus/reconcile.js.map +1 -0
  147. package/dist/store/exodus/recovery.d.ts.map +1 -1
  148. package/dist/store/exodus/recovery.js +14 -2
  149. package/dist/store/exodus/recovery.js.map +1 -1
  150. package/dist/store/exodus/runtime-targets.d.ts +39 -0
  151. package/dist/store/exodus/runtime-targets.d.ts.map +1 -0
  152. package/dist/store/exodus/runtime-targets.js +63 -0
  153. package/dist/store/exodus/runtime-targets.js.map +1 -0
  154. package/dist/store/exodus/table-name-map.d.ts.map +1 -1
  155. package/dist/store/exodus/table-name-map.js +5 -0
  156. package/dist/store/exodus/table-name-map.js.map +1 -1
  157. package/dist/store/exodus/table-order.d.ts +35 -0
  158. package/dist/store/exodus/table-order.d.ts.map +1 -0
  159. package/dist/store/exodus/table-order.js +62 -0
  160. package/dist/store/exodus/table-order.js.map +1 -0
  161. package/dist/store/exodus/verify-migration.d.ts +4 -1
  162. package/dist/store/exodus/verify-migration.d.ts.map +1 -1
  163. package/dist/store/exodus/verify-migration.js +142 -10
  164. package/dist/store/exodus/verify-migration.js.map +1 -1
  165. package/dist/store/global-salt.d.ts +16 -0
  166. package/dist/store/global-salt.d.ts.map +1 -1
  167. package/dist/store/global-salt.js +22 -7
  168. package/dist/store/global-salt.js.map +1 -1
  169. package/dist/store/legacy-tasks-lineage.d.ts +86 -0
  170. package/dist/store/legacy-tasks-lineage.d.ts.map +1 -0
  171. package/dist/store/legacy-tasks-lineage.js +285 -0
  172. package/dist/store/legacy-tasks-lineage.js.map +1 -0
  173. package/dist/store/migration-manager.d.ts +27 -0
  174. package/dist/store/migration-manager.d.ts.map +1 -1
  175. package/dist/store/migration-manager.js +63 -0
  176. package/dist/store/migration-manager.js.map +1 -1
  177. package/dist/store/portable-bundle-import.d.ts +117 -0
  178. package/dist/store/portable-bundle-import.d.ts.map +1 -0
  179. package/dist/store/portable-bundle-import.js +589 -0
  180. package/dist/store/portable-bundle-import.js.map +1 -0
  181. package/dist/store/portable-bundle-relocate.d.ts +66 -0
  182. package/dist/store/portable-bundle-relocate.d.ts.map +1 -0
  183. package/dist/store/portable-bundle-relocate.js +304 -0
  184. package/dist/store/portable-bundle-relocate.js.map +1 -0
  185. package/dist/store/portable-bundle-scan.d.ts +167 -0
  186. package/dist/store/portable-bundle-scan.d.ts.map +1 -0
  187. package/dist/store/portable-bundle-scan.js +569 -0
  188. package/dist/store/portable-bundle-scan.js.map +1 -0
  189. package/dist/store/portable-bundle.d.ts +146 -0
  190. package/dist/store/portable-bundle.d.ts.map +1 -0
  191. package/dist/store/portable-bundle.js +674 -0
  192. package/dist/store/portable-bundle.js.map +1 -0
  193. package/dist/store/regenerators.d.ts +3 -1
  194. package/dist/store/regenerators.d.ts.map +1 -1
  195. package/dist/store/regenerators.js +6 -2
  196. package/dist/store/regenerators.js.map +1 -1
  197. package/dist/store/schema/cleo-global/nexus.d.ts +98 -0
  198. package/dist/store/schema/cleo-global/nexus.d.ts.map +1 -1
  199. package/dist/store/schema/cleo-global/nexus.js +19 -0
  200. package/dist/store/schema/cleo-global/nexus.js.map +1 -1
  201. package/dist/store/schema/nexus-schema.d.ts +102 -0
  202. package/dist/store/schema/nexus-schema.d.ts.map +1 -1
  203. package/dist/store/schema/nexus-schema.js +24 -0
  204. package/dist/store/schema/nexus-schema.js.map +1 -1
  205. package/dist/store/split-brain-import.d.ts +176 -0
  206. package/dist/store/split-brain-import.d.ts.map +1 -0
  207. package/dist/store/split-brain-import.js +680 -0
  208. package/dist/store/split-brain-import.js.map +1 -0
  209. package/dist/store/sqlite.d.ts +29 -0
  210. package/dist/store/sqlite.d.ts.map +1 -1
  211. package/dist/store/sqlite.js +57 -5
  212. package/dist/store/sqlite.js.map +1 -1
  213. package/dist/system/health.d.ts.map +1 -1
  214. package/dist/system/health.js +30 -5
  215. package/dist/system/health.js.map +1 -1
  216. package/dist/tasks/complete.d.ts.map +1 -1
  217. package/dist/tasks/complete.js +5 -27
  218. package/dist/tasks/complete.js.map +1 -1
  219. package/dist/tasks/evidence.js +1 -1
  220. package/dist/tasks/evidence.js.map +1 -1
  221. package/dist/tasks/verification-policy.d.ts +55 -0
  222. package/dist/tasks/verification-policy.d.ts.map +1 -0
  223. package/dist/tasks/verification-policy.js +75 -0
  224. package/dist/tasks/verification-policy.js.map +1 -0
  225. package/dist/upgrade.d.ts.map +1 -1
  226. package/dist/upgrade.js +60 -0
  227. package/dist/upgrade.js.map +1 -1
  228. package/dist/validation/doctor/checks.d.ts +14 -0
  229. package/dist/validation/doctor/checks.d.ts.map +1 -1
  230. package/dist/validation/doctor/checks.js +33 -0
  231. package/dist/validation/doctor/checks.js.map +1 -1
  232. package/migrations/drizzle-cleo-global/20260924000000_t12354-project-paths/migration.sql +40 -0
  233. package/migrations/drizzle-nexus/20260924000000_t12315-nexus-parse-cache/migration.sql +21 -0
  234. package/package.json +13 -13
  235. package/templates/CLEO-INJECTION.md +3 -3
  236. package/templates/cleo-gitignore +7 -0
@@ -1,15 +1,19 @@
1
1
  /**
2
- * Credential encryption — AES-256-GCM with machine-bound key derivation.
2
+ * Credential encryption — AES-256-GCM with device-bound key derivation.
3
3
  *
4
- * API keys (`sk_live_*`) are encrypted at rest in SQLite using AES-256-GCM.
5
- * The encryption key is derived per-project from a machine-specific secret:
4
+ * Every key derives from the 32-byte `machine-key` in the CLEO home. That key
5
+ * NEVER leaves the device; credentials cross devices only through the
6
+ * passphrase-sealed path in `store/credential-transfer.ts`.
6
7
  *
7
- * machine-key (32 random bytes at ~/.local/share/cleo/machine-key)
8
- * + project path
9
- * = HMAC-SHA256(machine-key, project-path) → per-project AES key
8
+ * Two KDFs:
10
9
  *
11
- * This means credentials are bound to BOTH the machine AND the project.
12
- * Moving `.cleo/tasks.db` to another machine renders stored keys unreadable.
10
+ * - **Project** (T12326): `HMAC-SHA256(machine-key, "cleo:project-credential:v2\0"
11
+ * ‖ projectId)`, ciphertext version `0x02`. Keyed by project IDENTITY, so a
12
+ * moved or renamed project still decrypts. The pre-T12326 path-bound KDF
13
+ * (`HMAC-SHA256(machine-key, projectPath)`, version `0x01`) is read-only and
14
+ * migrated on first successful decrypt ({@link decryptProjectSecret}).
15
+ * - **Global** (ADR-037 §5): `HMAC-SHA256(machine-key ‖ global-salt, id)`,
16
+ * version `0x01`, for project-independent credentials.
13
17
  *
14
18
  * @see docs/specs/SIGNALDOCK-UNIFIED-AGENT-REGISTRY.md Section 3.6
15
19
  * @module crypto/credentials
@@ -18,39 +22,39 @@ import { execFileSync } from 'node:child_process';
18
22
  import { createCipheriv, createDecipheriv, createHmac, randomBytes } from 'node:crypto';
19
23
  import { chmod, mkdir, readFile, stat, writeFile } from 'node:fs/promises';
20
24
  import { dirname, join } from 'node:path';
21
- import { getGlobalSalt } from '../store/global-salt.js';
25
+ import { getCleoHome } from '../paths.js';
26
+ import { getGlobalSalt, loadGlobalSaltAt } from '../store/global-salt.js';
22
27
  /** AES-256-GCM constants. */
23
28
  const ALGORITHM = 'aes-256-gcm';
24
29
  const IV_LENGTH = 12;
25
30
  const AUTH_TAG_LENGTH = 16;
26
31
  const KEY_LENGTH = 32;
27
- /** Version byte prefix for ciphertext format (F-006: enables future algorithm migration). */
32
+ /**
33
+ * Version byte of global-KDF ciphertexts (F-006: enables future algorithm
34
+ * migration). Project ciphertexts carry their own versions — see
35
+ * {@link PROJECT_CIPHERTEXT_VERSION_PROJECT_ID}.
36
+ */
28
37
  const CIPHERTEXT_VERSION = 0x01;
29
38
  /**
30
- * Get the path to the machine key file.
31
- * Uses XDG data dir: `~/.local/share/cleo/machine-key`
39
+ * Absolute path to the machine key file: `<cleoHome>/machine-key`.
40
+ *
41
+ * Resolved through {@link getCleoHome} — the same root as `global-salt` and
42
+ * the agent registry's key reader — so `CLEO_HOME` relocates all of them
43
+ * together. (Before T12326 this function re-derived the XDG path itself and
44
+ * ignored `CLEO_HOME`, so a relocated home read the salt from one directory
45
+ * and the key from another.) On every platform the default resolves to the
46
+ * same file as before.
32
47
  *
33
- * @throws If HOME/USERPROFILE are unset (F-002: never fall back to /tmp).
48
+ * The machine key is DEVICE-LOCAL by design: it is never exported in any
49
+ * backup bundle. Credentials move between devices through
50
+ * `store/credential-transfer.ts` instead.
51
+ *
52
+ * @param cleoHome - CLEO home to resolve against (defaults to the ambient home).
53
+ * @returns Absolute path to the machine key.
54
+ * @task T12326
34
55
  */
35
- function getMachineKeyPath() {
36
- // Use platform-aware data directory: XDG on Linux, Library on macOS, %LOCALAPPDATA% on Windows
37
- if (process.platform === 'win32') {
38
- const appData = process.env['LOCALAPPDATA'] ?? process.env['APPDATA'];
39
- if (appData)
40
- return join(appData, 'cleo', 'Data', 'machine-key');
41
- }
42
- else if (process.platform === 'darwin') {
43
- const home = process.env['HOME'];
44
- if (home)
45
- return join(home, 'Library', 'Application Support', 'cleo', 'machine-key');
46
- }
47
- // Linux / fallback: XDG_DATA_HOME or ~/.local/share
48
- const dataHome = process.env['XDG_DATA_HOME'] ?? join(process.env['HOME'] ?? '', '.local', 'share');
49
- if (!dataHome) {
50
- throw new Error('Cannot determine data directory. Set HOME or XDG_DATA_HOME environment variable. ' +
51
- 'Machine key cannot be stored securely without a persistent data directory.');
52
- }
53
- return join(dataHome, 'cleo', 'machine-key');
56
+ export function getMachineKeyPath(cleoHome = getCleoHome()) {
57
+ return join(cleoHome, 'machine-key');
54
58
  }
55
59
  /**
56
60
  * Read or auto-generate the machine key (32 random bytes).
@@ -58,8 +62,8 @@ function getMachineKeyPath() {
58
62
  *
59
63
  * @throws If the machine key exists but has wrong permissions (not 0600).
60
64
  */
61
- async function getMachineKey() {
62
- const keyPath = getMachineKeyPath();
65
+ async function getMachineKey(cleoHome) {
66
+ const keyPath = getMachineKeyPath(cleoHome);
63
67
  try {
64
68
  // Verify key file permissions
65
69
  const stats = await stat(keyPath);
@@ -122,102 +126,156 @@ async function getMachineKey() {
122
126
  throw err;
123
127
  }
124
128
  }
129
+ // ============================================================================
130
+ // Ciphertext framing (shared by every KDF)
131
+ // ============================================================================
125
132
  /**
126
- * Derive a per-project encryption key from the machine key.
127
- * Uses HMAC-SHA256(machine-key, project-path) to produce a 32-byte AES key.
128
- *
129
- * @remarks
130
- * **KDF COORDINATION NOTE (T380/ADR-041 §D5, ADR-037 §5)**
131
- *
132
- * This KDF is intentionally NOT changed in T380. The current scheme
133
- * (`HMAC-SHA256(machine-key, projectPath)`) is project-path-bound, which is
134
- * correct for the current project-tier signaldock.db layout.
135
- *
136
- * ADR-037 §5 specifies the replacement KDF:
137
- * ```
138
- * apiKey = HMAC-SHA256(machine-key || globalSalt, agentId)
139
- * ```
140
- * where `globalSalt` is a 32-byte per-machine random value stored at
141
- * `$XDG_DATA_HOME/cleo/global-salt`.
142
- *
143
- * The replacement KDF MUST be implemented as part of the global-signaldock
144
- * migration (T310 + T362). Swapping it here, before that migration, would
145
- * silently invalidate all stored encrypted API keys without providing the
146
- * global-salt infrastructure needed to re-encrypt them.
147
- *
148
- * Once T310/T362 land, this function should be REPLACED (not extended) with
149
- * the new `deriveAgentKey(agentId: string)` helper defined in that epic.
150
- * Remove this comment block when the replacement lands.
151
- *
152
- * @see ADR-037 §5 — full KDF design and migration plan
153
- * @see T310 — GlobalAgentRegistryAccessor + KDF refactor
154
- * @see T362 — parallel KDF coordination
155
- * @task T380
156
- */
157
- async function deriveProjectKey(projectPath) {
158
- const machineKey = await getMachineKey();
159
- return createHmac('sha256', machineKey).update(projectPath).digest();
160
- }
161
- /**
162
- * Encrypt a plaintext string using AES-256-GCM with a per-project key.
163
- *
164
- * Output format: base64(version + iv + ciphertext + authTag)
165
- * - version: 1 byte (0x01 = AES-256-GCM)
166
- * - iv: 12 bytes
167
- * - ciphertext: variable length
168
- * - authTag: 16 bytes
169
- *
170
- * @param plaintext - The string to encrypt (e.g. an API key).
171
- * @param projectPath - Absolute path to the project directory (used for key derivation).
172
- * @returns Base64-encoded ciphertext.
133
+ * Encrypt `plaintext` under `key` and frame it as
134
+ * base64(version ‖ iv ‖ ciphertext ‖ authTag).
173
135
  */
174
- export async function encrypt(plaintext, projectPath) {
175
- const key = await deriveProjectKey(projectPath);
136
+ function sealWithKey(plaintext, key, version) {
176
137
  const iv = randomBytes(IV_LENGTH);
177
138
  const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
178
139
  const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
179
140
  const authTag = cipher.getAuthTag();
180
- // Pack: version + iv + ciphertext + authTag (F-006: version byte for future migration)
181
- const version = Buffer.from([CIPHERTEXT_VERSION]);
182
- const packed = Buffer.concat([version, iv, encrypted, authTag]);
183
- return packed.toString('base64');
141
+ return Buffer.concat([Buffer.from([version]), iv, encrypted, authTag]).toString('base64');
184
142
  }
185
143
  /**
186
- * Decrypt a base64-encoded ciphertext using AES-256-GCM with a per-project key.
144
+ * Split a framed ciphertext into its parts.
187
145
  *
188
- * @param ciphertext - Base64-encoded string from `encrypt()`.
189
- * @param projectPath - Absolute path to the project directory (must match the one used for encryption).
190
- * @returns The original plaintext string.
191
- * @throws If decryption fails (wrong key, corrupted data, or machine key mismatch).
146
+ * @throws {Error} If the payload is shorter than the fixed framing.
192
147
  */
193
- export async function decrypt(ciphertext, projectPath) {
194
- const key = await deriveProjectKey(projectPath);
148
+ function unframe(ciphertext) {
195
149
  const packed = Buffer.from(ciphertext, 'base64');
196
150
  if (packed.length < 1 + IV_LENGTH + AUTH_TAG_LENGTH) {
197
151
  throw new Error('Cannot decrypt credentials: ciphertext too short');
198
152
  }
199
- // F-006: check version byte
200
- const version = packed[0];
201
- if (version !== CIPHERTEXT_VERSION) {
202
- throw new Error(`Unknown ciphertext version (${version}). Expected ${CIPHERTEXT_VERSION}. ` +
203
- 'Re-register agents to re-encrypt with the current format.');
204
- }
205
- const iv = packed.subarray(1, 1 + IV_LENGTH);
206
- const authTag = packed.subarray(packed.length - AUTH_TAG_LENGTH);
207
- const encrypted = packed.subarray(1 + IV_LENGTH, packed.length - AUTH_TAG_LENGTH);
208
- const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
209
- decipher.setAuthTag(authTag);
153
+ return {
154
+ version: packed[0] ?? -1,
155
+ iv: packed.subarray(1, 1 + IV_LENGTH),
156
+ encrypted: packed.subarray(1 + IV_LENGTH, packed.length - AUTH_TAG_LENGTH),
157
+ authTag: packed.subarray(packed.length - AUTH_TAG_LENGTH),
158
+ };
159
+ }
160
+ /**
161
+ * Decrypt a framed ciphertext under `key`. Returns `null` when the GCM auth
162
+ * tag rejects the key — the caller decides whether another key is worth trying.
163
+ */
164
+ function openWithKey(parts, key) {
165
+ const decipher = createDecipheriv(ALGORITHM, key, parts.iv, { authTagLength: AUTH_TAG_LENGTH });
166
+ decipher.setAuthTag(parts.authTag);
210
167
  try {
211
- const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
212
- return decrypted.toString('utf8');
168
+ return Buffer.concat([decipher.update(parts.encrypted), decipher.final()]).toString('utf8');
213
169
  }
214
170
  catch {
215
- throw new Error('Cannot decrypt credentials. Machine key mismatch or corrupted data. ' +
216
- 'If this database was moved from another machine, re-register agents: ' +
217
- 'cleo agent register --id <id> --api-key <key>');
171
+ return null;
218
172
  }
219
173
  }
220
174
  // ============================================================================
175
+ // Project KDF — keyed by project IDENTITY, not project path (T12326)
176
+ // ============================================================================
177
+ /**
178
+ * Ciphertext version written by the pre-T12326 project KDF,
179
+ * `HMAC-SHA256(machine-key, projectPath)`. Read-only: decrypted during
180
+ * migration, never written.
181
+ */
182
+ export const PROJECT_CIPHERTEXT_VERSION_LEGACY_PATH = 0x01;
183
+ /**
184
+ * Ciphertext version written by the project-identity KDF,
185
+ * `HMAC-SHA256(machine-key, "cleo:project-credential:v2\0" ‖ projectId)`.
186
+ */
187
+ export const PROJECT_CIPHERTEXT_VERSION_PROJECT_ID = 0x02;
188
+ /** Domain-separation prefix for the project-identity KDF message. */
189
+ const PROJECT_ID_KDF_CONTEXT = 'cleo:project-credential:v2\0';
190
+ /**
191
+ * Derive the project-identity key.
192
+ *
193
+ * @throws {Error} If `projectId` is empty — an empty id would collapse every
194
+ * project onto one key.
195
+ */
196
+ async function deriveProjectIdKey(projectId, cleoHome) {
197
+ if (projectId.length === 0) {
198
+ throw new Error('Cannot derive a project credential key: projectId is empty');
199
+ }
200
+ const machineKey = await getMachineKey(cleoHome);
201
+ return createHmac('sha256', machineKey)
202
+ .update(PROJECT_ID_KDF_CONTEXT + projectId, 'utf8')
203
+ .digest();
204
+ }
205
+ /**
206
+ * Derive the LEGACY path-bound project key, `HMAC-SHA256(machine-key, path)`.
207
+ * Used only to read pre-T12326 ciphertexts during migration.
208
+ */
209
+ async function deriveLegacyPathKey(projectPath, cleoHome) {
210
+ const machineKey = await getMachineKey(cleoHome);
211
+ return createHmac('sha256', machineKey).update(projectPath).digest();
212
+ }
213
+ /**
214
+ * Encrypt a project-scoped secret under the project-identity KDF.
215
+ *
216
+ * The key is `HMAC-SHA256(machine-key, "cleo:project-credential:v2\0" ‖
217
+ * projectId)`: bound to this device (machine-key) and to the project's
218
+ * identity, but NOT to where the project directory lives. Moving or renaming
219
+ * the checkout keeps the key; a different device does not (see
220
+ * `store/credential-transfer.ts` for the portable path).
221
+ *
222
+ * @param plaintext - The secret (e.g. an agent API key).
223
+ * @param projectId - Stable project identity.
224
+ * @param options - Key options (which CLEO home's machine-key).
225
+ * @returns Base64 ciphertext, version byte {@link PROJECT_CIPHERTEXT_VERSION_PROJECT_ID}.
226
+ * @task T12326
227
+ */
228
+ export async function encryptProjectSecret(plaintext, projectId, options = {}) {
229
+ const key = await deriveProjectIdKey(projectId, options.cleoHome);
230
+ return sealWithKey(plaintext, key, PROJECT_CIPHERTEXT_VERSION_PROJECT_ID);
231
+ }
232
+ /**
233
+ * Decrypt a project-scoped secret, migrating legacy ciphertexts on the way.
234
+ *
235
+ * - Version `0x02` ciphertexts open with the project-identity key.
236
+ * - Version `0x01` (legacy, path-bound) ciphertexts are tried against each of
237
+ * `legacyProjectPaths`; the first that authenticates wins and the secret is
238
+ * re-encrypted under the project-identity KDF and returned as `rewrapped`
239
+ * for the caller to persist. The legacy ciphertext is never needed again.
240
+ *
241
+ * @param ciphertext - Base64 ciphertext from either KDF.
242
+ * @param context - Project identity plus legacy path candidates.
243
+ * @returns The plaintext, which KDF opened it, and any re-wrapped ciphertext.
244
+ * @throws {Error} If no key authenticates. The message names the paths tried
245
+ * so the caller can report which credential to re-enter.
246
+ * @task T12326
247
+ */
248
+ export async function decryptProjectSecret(ciphertext, context) {
249
+ const parts = unframe(ciphertext);
250
+ if (parts.version === PROJECT_CIPHERTEXT_VERSION_PROJECT_ID) {
251
+ const plaintext = openWithKey(parts, await deriveProjectIdKey(context.projectId, context.cleoHome));
252
+ if (plaintext === null) {
253
+ throw new Error(`Cannot decrypt project credential for project ${context.projectId}: ` +
254
+ 'the machine key differs from the one that encrypted it (another device, or a ' +
255
+ 'regenerated machine-key), or the data is corrupted.');
256
+ }
257
+ return { plaintext, kdf: 'project-id', rewrapped: null };
258
+ }
259
+ if (parts.version === PROJECT_CIPHERTEXT_VERSION_LEGACY_PATH) {
260
+ const candidates = [...new Set(context.legacyProjectPaths ?? [])];
261
+ for (const candidate of candidates) {
262
+ const plaintext = openWithKey(parts, await deriveLegacyPathKey(candidate, context.cleoHome));
263
+ if (plaintext !== null) {
264
+ return {
265
+ plaintext,
266
+ kdf: 'legacy-path',
267
+ rewrapped: await encryptProjectSecret(plaintext, context.projectId, context),
268
+ };
269
+ }
270
+ }
271
+ throw new Error('Cannot decrypt legacy path-bound project credential: none of the candidate project ' +
272
+ `paths opened it (${candidates.length === 0 ? 'none supplied' : candidates.join(', ')}). ` +
273
+ 'It was encrypted at a path this device no longer knows, or on another device.');
274
+ }
275
+ throw new Error(`Unknown project ciphertext version (${parts.version}). Expected ` +
276
+ `${PROJECT_CIPHERTEXT_VERSION_PROJECT_ID} or ${PROJECT_CIPHERTEXT_VERSION_LEGACY_PATH}.`);
277
+ }
278
+ // ============================================================================
221
279
  // Global (project-independent) KDF — ADR-037 §5
222
280
  // ============================================================================
223
281
  /**
@@ -247,9 +305,9 @@ export async function decrypt(ciphertext, projectPath) {
247
305
  * @see getGlobalSalt — global-salt source of truth (store/global-salt.ts)
248
306
  * @task T11710
249
307
  */
250
- async function deriveGlobalKey(id) {
251
- const machineKey = await getMachineKey();
252
- const globalSalt = getGlobalSalt();
308
+ async function deriveGlobalKey(id, cleoHome) {
309
+ const machineKey = await getMachineKey(cleoHome);
310
+ const globalSalt = cleoHome === undefined ? getGlobalSalt() : loadGlobalSaltAt(cleoHome);
253
311
  // HMAC key = machine-key || globalSalt (concatenation); message = id.
254
312
  const hmacKey = Buffer.concat([machineKey, globalSalt]);
255
313
  return createHmac('sha256', hmacKey).update(id).digest();
@@ -270,21 +328,15 @@ async function deriveGlobalKey(id) {
270
328
  *
271
329
  * @param plaintext - The string to encrypt (e.g. an LLM API key).
272
330
  * @param id - The stable identity used for key derivation (e.g. an agentId).
331
+ * @param options - Key options (which CLEO home's machine-key + salt).
273
332
  * @returns Base64-encoded ciphertext.
274
333
  *
275
334
  * @see decryptGlobal — the inverse operation.
276
335
  * @task T11710
277
336
  */
278
- export async function encryptGlobal(plaintext, id) {
279
- const key = await deriveGlobalKey(id);
280
- const iv = randomBytes(IV_LENGTH);
281
- const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
282
- const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
283
- const authTag = cipher.getAuthTag();
284
- // Pack: version + iv + ciphertext + authTag (matches encrypt() format exactly).
285
- const version = Buffer.from([CIPHERTEXT_VERSION]);
286
- const packed = Buffer.concat([version, iv, encrypted, authTag]);
287
- return packed.toString('base64');
337
+ export async function encryptGlobal(plaintext, id, options = {}) {
338
+ const key = await deriveGlobalKey(id, options.cleoHome);
339
+ return sealWithKey(plaintext, key, CIPHERTEXT_VERSION);
288
340
  }
289
341
  /**
290
342
  * Decrypt a base64-encoded ciphertext produced by {@link encryptGlobal} using
@@ -293,6 +345,7 @@ export async function encryptGlobal(plaintext, id) {
293
345
  * @param ciphertext - Base64-encoded string from {@link encryptGlobal}.
294
346
  * @param id - The identity used at encryption time. A mismatched `id` derives a
295
347
  * different key and fails the GCM auth tag (throws).
348
+ * @param options - Key options (which CLEO home's machine-key + salt).
296
349
  * @returns The original plaintext string.
297
350
  * @throws If decryption fails (wrong id, corrupted data, or machine-key/
298
351
  * global-salt mismatch).
@@ -300,30 +353,18 @@ export async function encryptGlobal(plaintext, id) {
300
353
  * @see encryptGlobal — the inverse operation.
301
354
  * @task T11710
302
355
  */
303
- export async function decryptGlobal(ciphertext, id) {
304
- const key = await deriveGlobalKey(id);
305
- const packed = Buffer.from(ciphertext, 'base64');
306
- if (packed.length < 1 + IV_LENGTH + AUTH_TAG_LENGTH) {
307
- throw new Error('Cannot decrypt credentials: ciphertext too short');
308
- }
309
- const version = packed[0];
310
- if (version !== CIPHERTEXT_VERSION) {
311
- throw new Error(`Unknown ciphertext version (${version}). Expected ${CIPHERTEXT_VERSION}. ` +
356
+ export async function decryptGlobal(ciphertext, id, options = {}) {
357
+ const parts = unframe(ciphertext);
358
+ if (parts.version !== CIPHERTEXT_VERSION) {
359
+ throw new Error(`Unknown ciphertext version (${parts.version}). Expected ${CIPHERTEXT_VERSION}. ` +
312
360
  'Re-register agents to re-encrypt with the current format.');
313
361
  }
314
- const iv = packed.subarray(1, 1 + IV_LENGTH);
315
- const authTag = packed.subarray(packed.length - AUTH_TAG_LENGTH);
316
- const encrypted = packed.subarray(1 + IV_LENGTH, packed.length - AUTH_TAG_LENGTH);
317
- const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
318
- decipher.setAuthTag(authTag);
319
- try {
320
- const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
321
- return decrypted.toString('utf8');
322
- }
323
- catch {
362
+ const plaintext = openWithKey(parts, await deriveGlobalKey(id, options.cleoHome));
363
+ if (plaintext === null) {
324
364
  throw new Error('Cannot decrypt global credentials. Machine key / global-salt mismatch, ' +
325
365
  'wrong id, or corrupted data. If this database was moved from another ' +
326
366
  'machine, re-register the credential under its original id.');
327
367
  }
368
+ return plaintext;
328
369
  }
329
370
  //# sourceMappingURL=credentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/crypto/credentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/crypto/credentials.ts"],"names":[],"mappings":"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"}