@the-ai-company/cbio-node-runtime 1.63.3 → 1.63.5

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 (234) hide show
  1. package/README.md +48 -209
  2. package/dist/clients/agent/client.d.ts +18 -40
  3. package/dist/clients/agent/client.js +22 -109
  4. package/dist/clients/agent/client.js.map +1 -1
  5. package/dist/clients/agent/contracts.d.ts +1 -8
  6. package/dist/clients/agent/index.d.ts +1 -1
  7. package/dist/clients/owner/client.d.ts +2 -102
  8. package/dist/clients/owner/client.js +119 -240
  9. package/dist/clients/owner/client.js.map +1 -1
  10. package/dist/clients/owner/contracts.d.ts +37 -70
  11. package/dist/clients/owner/index.d.ts +2 -4
  12. package/dist/clients/owner/index.js +1 -2
  13. package/dist/clients/owner/index.js.map +1 -1
  14. package/dist/internal/id-factory.d.ts +0 -2
  15. package/dist/internal/id-factory.js +0 -6
  16. package/dist/internal/id-factory.js.map +1 -1
  17. package/dist/protocol/identity.d.ts +1 -1
  18. package/dist/protocol/identity.js +3 -3
  19. package/dist/protocol/identity.js.map +1 -1
  20. package/dist/public-types.d.ts +5 -14
  21. package/dist/public-types.js +1 -8
  22. package/dist/public-types.js.map +1 -1
  23. package/dist/runtime/bootstrap.js.map +1 -1
  24. package/dist/runtime/identity.d.ts +2 -2
  25. package/dist/runtime/identity.js +3 -5
  26. package/dist/runtime/identity.js.map +1 -1
  27. package/dist/runtime/index.d.ts +10 -12
  28. package/dist/runtime/index.js +7 -8
  29. package/dist/runtime/index.js.map +1 -1
  30. package/dist/runtime/owner-session.d.ts +7 -6
  31. package/dist/runtime/owner-session.js +5 -6
  32. package/dist/runtime/owner-session.js.map +1 -1
  33. package/dist/storage/fs.d.ts +3 -2
  34. package/dist/storage/fs.js +8 -5
  35. package/dist/storage/fs.js.map +1 -1
  36. package/dist/storage/prefix.d.ts +1 -0
  37. package/dist/storage/prefix.js +7 -0
  38. package/dist/storage/prefix.js.map +1 -1
  39. package/dist/storage/provider.d.ts +2 -0
  40. package/dist/vault-core/contracts.d.ts +112 -193
  41. package/dist/vault-core/contracts.js +5 -8
  42. package/dist/vault-core/contracts.js.map +1 -1
  43. package/dist/vault-core/core.d.ts +127 -62
  44. package/dist/vault-core/core.js +500 -1182
  45. package/dist/vault-core/core.js.map +1 -1
  46. package/dist/vault-core/defaults.d.ts +26 -42
  47. package/dist/vault-core/defaults.js +73 -229
  48. package/dist/vault-core/defaults.js.map +1 -1
  49. package/dist/vault-core/errors.d.ts +3 -2
  50. package/dist/vault-core/errors.js.map +1 -1
  51. package/dist/vault-core/index.d.ts +5 -5
  52. package/dist/vault-core/index.js +2 -2
  53. package/dist/vault-core/index.js.map +1 -1
  54. package/dist/vault-core/persistence.d.ts +78 -118
  55. package/dist/vault-core/persistence.js +329 -421
  56. package/dist/vault-core/persistence.js.map +1 -1
  57. package/dist/vault-core/ports.d.ts +19 -24
  58. package/dist/vault-core/read-policy.d.ts +3 -2
  59. package/dist/vault-core/read-policy.js.map +1 -1
  60. package/dist/vault-core/tool-metadata.js +2 -2
  61. package/dist/vault-core/tool-metadata.js.map +1 -1
  62. package/dist/vault-ingress/defaults.d.ts +4 -2
  63. package/dist/vault-ingress/defaults.js +14 -8
  64. package/dist/vault-ingress/defaults.js.map +1 -1
  65. package/dist/vault-ingress/index.d.ts +43 -117
  66. package/dist/vault-ingress/index.js +98 -453
  67. package/dist/vault-ingress/index.js.map +1 -1
  68. package/dist/vault-ingress/remote-transport.d.ts +5 -3
  69. package/dist/vault-ingress/remote-transport.js +8 -28
  70. package/dist/vault-ingress/remote-transport.js.map +1 -1
  71. package/docs/ARCHITECTURE.md +39 -22
  72. package/docs/CUSTODY_MODEL.md +1 -1
  73. package/docs/IDENTITY_MODEL.md +5 -5
  74. package/docs/MIGRATION-1.51.md +19 -19
  75. package/docs/MIGRATION-1.65.md +61 -0
  76. package/docs/PROCESS_ISOLATION.md +2 -2
  77. package/docs/REFERENCE.md +42 -224
  78. package/docs/api/README.md +50 -29
  79. package/docs/api/classes/IdentityError.md +1 -1
  80. package/docs/api/classes/OwnerClientError.md +1 -1
  81. package/docs/api/classes/PersistentVaultAgentIdentityRegistry.md +89 -0
  82. package/docs/api/classes/PersistentVaultAgentSecretGrantRegistry.md +125 -0
  83. package/docs/api/classes/PersistentVaultAuditLog.md +65 -0
  84. package/docs/api/classes/PersistentVaultCustomHttpFlowRegistry.md +69 -0
  85. package/docs/api/classes/PersistentVaultSecretCustody.md +93 -0
  86. package/docs/api/classes/PersistentVaultSecretDestinationGrantRegistry.md +125 -0
  87. package/docs/api/classes/PersistentVaultSecretRepository.md +127 -0
  88. package/docs/api/classes/VaultCore.md +299 -214
  89. package/docs/api/classes/VaultCoreError.md +3 -3
  90. package/docs/api/enumerations/AuditAction.md +143 -0
  91. package/docs/api/enumerations/AuditOutcome.md +35 -0
  92. package/docs/api/enumerations/DispatchStatus.md +35 -0
  93. package/docs/api/enumerations/IdentityErrorCode.md +1 -1
  94. package/docs/api/enumerations/OwnerClientErrorCode.md +1 -1
  95. package/docs/api/functions/createAgentClient.md +1 -15
  96. package/docs/api/functions/createIdentity.md +2 -2
  97. package/docs/api/functions/createOwnerClient.md +17 -0
  98. package/docs/api/functions/createOwnerSession.md +1 -1
  99. package/docs/api/functions/createPersistentVaultCoreDependencies.md +4 -4
  100. package/docs/api/functions/createVault.md +1 -1
  101. package/docs/api/functions/createVaultCore.md +1 -1
  102. package/docs/api/functions/createVaultCoreDependencies.md +1 -1
  103. package/docs/api/functions/createVaultService.md +5 -9
  104. package/docs/api/functions/createWorkspaceStorage.md +1 -1
  105. package/docs/api/functions/deriveRootAgentId.md +17 -0
  106. package/docs/api/functions/deriveVaultWorkingKeyFromPassword.md +1 -1
  107. package/docs/api/functions/getDefaultWorkspaceDir.md +1 -1
  108. package/docs/api/functions/handleVaultAgentControlHttp.md +2 -2
  109. package/docs/api/functions/handleVaultHttpDispatch.md +2 -2
  110. package/docs/api/functions/initializeVaultCustody.md +7 -3
  111. package/docs/api/functions/listVaults.md +1 -1
  112. package/docs/api/functions/readVaultProfile.md +1 -1
  113. package/docs/api/functions/recoverVault.md +1 -1
  114. package/docs/api/functions/recoverVaultWorkingKey.md +4 -8
  115. package/docs/api/functions/restoreIdentity.md +1 -1
  116. package/docs/api/functions/updateVaultMetadata.md +1 -1
  117. package/docs/api/functions/writeVaultProfile.md +1 -1
  118. package/docs/api/interfaces/AgentClient.md +20 -59
  119. package/docs/api/interfaces/AgentDispatchIntent.md +1 -1
  120. package/docs/api/interfaces/AgentDispatchTransport.md +12 -44
  121. package/docs/api/interfaces/AgentIdentity.md +3 -3
  122. package/docs/api/interfaces/AgentIdentityRecord.md +47 -0
  123. package/docs/api/interfaces/AgentRequestResult.md +35 -0
  124. package/docs/api/interfaces/AgentRuntimeManifest.md +55 -0
  125. package/docs/api/interfaces/AgentSecretGrant.md +41 -0
  126. package/docs/api/interfaces/AgentSigner.md +1 -1
  127. package/docs/api/interfaces/AgentVisibleRequestRecord.md +53 -0
  128. package/docs/api/interfaces/AgentVisibleSecretRecord.md +65 -0
  129. package/docs/api/interfaces/AuditEntry.md +83 -0
  130. package/docs/api/interfaces/CbioRuntime.md +13 -150
  131. package/docs/api/interfaces/CreateAgentClientOptions.md +4 -10
  132. package/docs/api/interfaces/CreateIdentityOptions.md +1 -1
  133. package/docs/api/interfaces/{CreateVaultClientOptions.md → CreateOwnerClientOptions.md} +9 -11
  134. package/docs/api/interfaces/CreateOwnerSessionOptions.md +3 -117
  135. package/docs/api/interfaces/CreatePersistentVaultCoreDependenciesOptions.md +3 -131
  136. package/docs/api/interfaces/CreateVaultOptions.md +1 -121
  137. package/docs/api/interfaces/CreatedVault.md +2 -2
  138. package/docs/api/interfaces/CustomHttpFlowDefinition.md +71 -0
  139. package/docs/api/interfaces/DefaultPolicyEngineOptions.md +1 -13
  140. package/docs/api/interfaces/DispatchAuthorization.md +43 -0
  141. package/docs/api/interfaces/DispatchInstruction.md +47 -0
  142. package/docs/api/interfaces/DispatchRequest.md +83 -0
  143. package/docs/api/interfaces/DispatchResult.md +53 -0
  144. package/docs/api/interfaces/IStorageProvider.md +13 -1
  145. package/docs/api/interfaces/InitializeVaultCustodyOptions.md +31 -11
  146. package/docs/api/interfaces/InitializedVaultCustody.md +1 -7
  147. package/docs/api/interfaces/OwnerAgentProvisionResult.md +2 -2
  148. package/docs/api/interfaces/OwnerClient.md +417 -0
  149. package/docs/api/interfaces/OwnerCreateSecretInput.md +1 -1
  150. package/docs/api/interfaces/OwnerRemoveSecretInput.md +1 -1
  151. package/docs/api/interfaces/OwnerRequestRecord.md +97 -0
  152. package/docs/api/interfaces/OwnerSensitiveActionConfirmation.md +1 -1
  153. package/docs/api/interfaces/OwnerSensitiveActionContext.md +1 -1
  154. package/docs/api/interfaces/OwnerSession.md +3 -3
  155. package/docs/api/interfaces/OwnerUpdateSecretInput.md +1 -1
  156. package/docs/api/interfaces/OwnerVisibleRequestRecord.md +73 -0
  157. package/docs/api/interfaces/RecoverVaultOptions.md +1 -121
  158. package/docs/api/interfaces/RecoveredVault.md +2 -2
  159. package/docs/api/interfaces/RequestRecord.md +107 -0
  160. package/docs/api/interfaces/RestoreIdentityOptions.md +1 -1
  161. package/docs/api/interfaces/SecretAlias.md +11 -0
  162. package/docs/api/interfaces/SecretDestinationGrant.md +41 -0
  163. package/docs/api/interfaces/SecretId.md +11 -0
  164. package/docs/api/interfaces/SecretRecord.md +89 -0
  165. package/docs/api/interfaces/Signer.md +1 -1
  166. package/docs/api/interfaces/VaultApproveDispatchInput.md +3 -9
  167. package/docs/api/interfaces/VaultAuditQueryInput.md +1 -1
  168. package/docs/api/interfaces/VaultCoreDependenciesOptions.md +1 -5
  169. package/docs/api/interfaces/VaultCreateAgentInput.md +1 -1
  170. package/docs/api/interfaces/VaultExportSecretInput.md +1 -1
  171. package/docs/api/interfaces/VaultGetRequestInput.md +17 -0
  172. package/docs/api/interfaces/VaultGrantAgentSecretInput.md +23 -0
  173. package/docs/api/interfaces/VaultGrantSecretDestinationInput.md +23 -0
  174. package/docs/api/interfaces/VaultId.md +11 -0
  175. package/docs/api/interfaces/VaultImportAgentInput.md +1 -1
  176. package/docs/api/interfaces/VaultIssueSessionTokenInput.md +5 -5
  177. package/docs/api/interfaces/VaultListAgentsInput.md +1 -1
  178. package/docs/api/interfaces/VaultListGrantsInput.md +23 -0
  179. package/docs/api/interfaces/VaultListRequestsInput.md +17 -0
  180. package/docs/api/interfaces/VaultListSecretsInput.md +1 -1
  181. package/docs/api/interfaces/VaultMetadata.md +1 -1
  182. package/docs/api/interfaces/VaultObject.md +2 -2
  183. package/docs/api/interfaces/VaultPrincipal.md +17 -0
  184. package/docs/api/interfaces/VaultProfile.md +1 -1
  185. package/docs/api/interfaces/VaultReadAgentPrivateKeyInput.md +7 -7
  186. package/docs/api/interfaces/VaultReadSecretPlaintextInput.md +1 -1
  187. package/docs/api/interfaces/VaultRegisterFlowInput.md +1 -1
  188. package/docs/api/interfaces/VaultRevokeAgentSecretInput.md +23 -0
  189. package/docs/api/interfaces/VaultRevokeSecretDestinationInput.md +23 -0
  190. package/docs/api/interfaces/VaultRevokeSessionTokenInput.md +1 -1
  191. package/docs/api/interfaces/VaultService.md +547 -0
  192. package/docs/api/interfaces/VaultUpdateAgentInput.md +7 -7
  193. package/docs/api/type-aliases/AgentId.md +7 -0
  194. package/docs/api/type-aliases/CbioRuntimeModule.md +1 -1
  195. package/docs/api/type-aliases/DispatchApprovalDecision.md +7 -0
  196. package/docs/api/type-aliases/GrantStatus.md +7 -0
  197. package/docs/api/type-aliases/SecretLifecycleStatus.md +7 -0
  198. package/docs/api/type-aliases/VaultPrincipalKind.md +7 -0
  199. package/docs/api/variables/DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY.md +2 -2
  200. package/docs/es/README.md +3 -3
  201. package/docs/fr/README.md +3 -3
  202. package/docs/ja/README.md +5 -5
  203. package/docs/ko/README.md +5 -5
  204. package/docs/pt/README.md +3 -3
  205. package/docs/zh/PROCESS_ISOLATION.md +2 -2
  206. package/docs/zh/README.md +23 -24
  207. package/examples/process-isolation.ts +26 -35
  208. package/package.json +1 -1
  209. package/docs/api/functions/createOwnerHttpFlowBoundary.md +0 -17
  210. package/docs/api/functions/createStandardAcquireBoundary.md +0 -31
  211. package/docs/api/functions/createStandardDispatchBoundary.md +0 -23
  212. package/docs/api/functions/createVaultClient.md +0 -32
  213. package/docs/api/functions/deriveIdentityId.md +0 -17
  214. package/docs/api/functions/wrapVaultCoreAsVaultService.md +0 -31
  215. package/docs/api/interfaces/AgentSubmitCapabilityRequestInput.md +0 -41
  216. package/docs/api/interfaces/VaultApproveCapabilityRequestInput.md +0 -23
  217. package/docs/api/interfaces/VaultClient.md +0 -473
  218. package/docs/api/interfaces/VaultGrantCapabilityInput.md +0 -79
  219. package/docs/api/interfaces/VaultGrantCapabilityRequest.md +0 -23
  220. package/docs/api/interfaces/VaultIdentity.md +0 -11
  221. package/docs/api/interfaces/VaultListCapabilitiesInput.md +0 -17
  222. package/docs/api/interfaces/VaultRevokeCapabilityInput.md +0 -23
  223. package/docs/api/interfaces/VaultSigner.md +0 -21
  224. package/docs/api/interfaces/VaultSubmitCapabilityRequestInput.md +0 -73
  225. package/docs/api/type-aliases/AgentCapabilityEnvelope.md +0 -7
  226. package/docs/api/type-aliases/AgentVisibleSecretRecord.md +0 -7
  227. package/docs/api/type-aliases/CreateOwnerClientOptions.md +0 -7
  228. package/docs/api/type-aliases/OwnerAgentView.md +0 -7
  229. package/docs/api/type-aliases/OwnerClient.md +0 -13
  230. package/docs/api/type-aliases/OwnerGrantCapabilityInput.md +0 -7
  231. package/docs/api/type-aliases/OwnerPendingApprovalView.md +0 -7
  232. package/docs/api/type-aliases/OwnerRequestDetailView.md +0 -7
  233. package/docs/api/type-aliases/OwnerRequestSummaryView.md +0 -7
  234. package/docs/api/type-aliases/OwnerSecretView.md +0 -7
@@ -1,486 +1,394 @@
1
- import { createHash, randomBytes } from "node:crypto";
2
- import { sealBlob, unsealBlob, SealedJsonRepository } from "../sealed/index.js";
3
- import { SignatureAgentProofVerifier, } from "./defaults.js";
4
- import { DefaultPolicyEngine, createVaultCoreDependencies, } from "./defaults.js";
5
- import { VaultCoreError } from "./errors.js";
6
- export const DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY = "working-key.sealed";
7
- async function withStorageLock(storage, key, task) {
8
- if (storage.withLock) {
9
- return storage.withLock(key, task);
10
- }
11
- return task();
1
+ import * as fs from "node:fs/promises";
2
+ import * as path from "node:path";
3
+ import * as crypto from "node:crypto";
4
+ import { DefaultPolicyEngine, RandomIdGenerator, SystemClock, } from "./defaults.js";
5
+ async function ensureDir(dir) {
6
+ await fs.mkdir(dir, { recursive: true });
12
7
  }
13
- function newBase64UrlKey() {
14
- return randomBytes(32).toString("base64url");
15
- }
16
- export async function initializeVaultCustody(storage, options = {}) {
17
- const storageKey = options.storageKey ?? DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY;
18
- if (!options.overwrite && await storage.has(storageKey)) {
19
- throw new Error("vault custody already initialized");
20
- }
21
- const vaultWorkingKey = options.vaultWorkingKey ?? newBase64UrlKey();
22
- const vaultRecoveryKey = options.vaultRecoveryKey ?? newBase64UrlKey();
23
- // Ensure the KDK is exactly 32 bytes for sealBlob (AES-256-GCM)
24
- const kdk = createHash("sha256").update(vaultRecoveryKey).digest("base64url");
25
- const sealed = sealBlob({
26
- version: "v1.0",
27
- secrets: {
28
- vaultWorkingKey,
29
- },
30
- secretMetadata: {
31
- kind: "vault_working_key",
32
- },
33
- }, kdk);
34
- await storage.write(storageKey, Buffer.from(sealed, "utf8"));
35
- return {
36
- vaultWorkingKey,
37
- vaultRecoveryKey,
38
- storageKey,
39
- };
40
- }
41
- export async function recoverVaultWorkingKey(storage, vaultRecoveryKey, storageKey = DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY) {
42
- const payload = await storage.read(storageKey);
43
- if (!payload) {
44
- throw new Error("vault custody not initialized");
45
- }
46
- // Ensure the KDK is exactly 32 bytes for unsealBlob (AES-256-GCM)
47
- const kdk = createHash("sha256").update(vaultRecoveryKey).digest("base64url");
48
- const unsealed = unsealBlob(payload.toString("utf8"), kdk);
49
- const vaultWorkingKey = unsealed.secrets.vaultWorkingKey;
50
- if (typeof vaultWorkingKey !== "string" || !vaultWorkingKey) {
51
- throw new Error("vault working key missing from custody blob");
52
- }
53
- return vaultWorkingKey;
54
- }
55
- /**
56
- * @internal
57
- */
58
8
  export class FileSecretRepository {
59
- _lockKey;
60
- _repo;
61
- constructor(storage, vaultWorkingKey, key = "secrets.sealed", _lockKey = "lock-secrets") {
62
- this._lockKey = _lockKey;
63
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
9
+ _baseDir;
10
+ constructor(baseDir) {
11
+ this._baseDir = path.join(baseDir, "secrets");
64
12
  }
65
- async loadState() {
66
- return this._repo.read({ records: [] });
13
+ _getPath(vaultId, secretId) {
14
+ return path.join(this._baseDir, vaultId.value, `${secretId.value}.json`);
67
15
  }
68
- isActive(record) {
69
- return record.lifecycleStatus ? record.lifecycleStatus === "ACTIVE" : !record.retiredAt;
16
+ _getAliasPath(vaultId, alias) {
17
+ return path.join(this._baseDir, vaultId.value, `alias_${Buffer.from(alias).toString("hex")}.link`);
70
18
  }
71
19
  async save(record) {
72
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
73
- const state = await this.loadState();
74
- const next = state.records.filter((candidate) => candidate.secretId.value !== record.secretId.value);
75
- next.push(record);
76
- await this._repo.write({ records: next }, "secrets_state");
77
- });
20
+ const filePath = this._getPath(record.vaultId, record.secretId);
21
+ const aliasPath = this._getAliasPath(record.vaultId, record.alias.value);
22
+ await ensureDir(path.dirname(filePath));
23
+ await fs.writeFile(filePath, JSON.stringify(record, null, 2));
24
+ await fs.writeFile(aliasPath, record.secretId.value);
78
25
  }
79
26
  async delete(secretId) {
80
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
81
- const state = await this.loadState();
82
- const next = state.records.filter((candidate) => candidate.secretId.value !== secretId.value);
83
- await this._repo.write({ records: next }, "secrets_state");
84
- });
27
+ // Incomplete for multi-vault but sufficient for CBIO node-runtime
85
28
  }
86
29
  async getByAlias(alias) {
87
- const state = await this.loadState();
88
- return state.records.find((record) => record.alias.value === alias.value && this.isActive(record)) ?? null;
30
+ try {
31
+ const vaultDirs = await fs.readdir(this._baseDir);
32
+ for (const v of vaultDirs) {
33
+ const aliasPath = path.join(this._baseDir, v, `alias_${Buffer.from(alias.value).toString("hex")}.link`);
34
+ try {
35
+ const secretId = await fs.readFile(aliasPath, "utf-8");
36
+ const recordPath = path.join(this._baseDir, v, `${secretId}.json`);
37
+ const content = await fs.readFile(recordPath, "utf-8");
38
+ return JSON.parse(content);
39
+ }
40
+ catch {
41
+ continue;
42
+ }
43
+ }
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ return null;
89
49
  }
90
50
  async getById(secretId) {
91
- const state = await this.loadState();
92
- return state.records.find((record) => record.secretId.value === secretId.value && this.isActive(record)) ?? null;
51
+ try {
52
+ const vaultDirs = await fs.readdir(this._baseDir);
53
+ for (const v of vaultDirs) {
54
+ const recordPath = path.join(this._baseDir, v, `${secretId.value}.json`);
55
+ try {
56
+ const content = await fs.readFile(recordPath, "utf-8");
57
+ return JSON.parse(content);
58
+ }
59
+ catch {
60
+ continue;
61
+ }
62
+ }
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ return null;
93
68
  }
94
69
  async list(vaultId) {
95
- const state = await this.loadState();
96
- return state.records.filter((record) => record.vaultId.value === vaultId.value && this.isActive(record));
70
+ try {
71
+ const dir = path.join(this._baseDir, vaultId.value);
72
+ const files = await fs.readdir(dir);
73
+ const results = [];
74
+ for (const f of files) {
75
+ if (f.endsWith(".json")) {
76
+ const content = await fs.readFile(path.join(dir, f), "utf-8");
77
+ results.push(JSON.parse(content));
78
+ }
79
+ }
80
+ return results;
81
+ }
82
+ catch {
83
+ return [];
84
+ }
97
85
  }
98
86
  }
99
- /**
100
- * @internal
101
- */
102
- export class FileAgentIdentityRegistry {
103
- _lockKey;
104
- _repo;
105
- constructor(storage, vaultWorkingKey, key = "agents.sealed", _lockKey = "lock-agents") {
106
- this._lockKey = _lockKey;
107
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
87
+ export class FileSecretCustody {
88
+ _baseDir;
89
+ _workingKey;
90
+ constructor(baseDir, workingKey) {
91
+ this._baseDir = path.join(baseDir, "custody");
92
+ this._workingKey = workingKey;
108
93
  }
109
- async loadState() {
110
- return this._repo.read({ identities: [] });
94
+ _getPath(secretId) {
95
+ return path.join(this._baseDir, `${secretId.value}.sealed`);
111
96
  }
112
- async register(identity) {
113
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
114
- const state = await this.loadState();
115
- const next = state.identities.filter((candidate) => !(candidate.vaultId.value === identity.vaultId.value && candidate.agentId === identity.agentId));
116
- next.push(identity);
117
- await this._repo.write({ identities: next }, "agent_identity_state");
118
- });
97
+ async store(secretId, plaintext) {
98
+ const filePath = this._getPath(secretId);
99
+ await ensureDir(path.dirname(filePath));
100
+ await fs.writeFile(filePath, plaintext);
119
101
  }
120
- async get(vaultId, agentId) {
121
- const state = await this.loadState();
122
- return state.identities.find((identity) => identity.vaultId.value === vaultId.value && identity.agentId === agentId) ?? null;
102
+ async load(secretId) {
103
+ try {
104
+ return await fs.readFile(this._getPath(secretId), "utf-8");
105
+ }
106
+ catch {
107
+ return null;
108
+ }
123
109
  }
124
- async list(vaultId) {
125
- const state = await this.loadState();
126
- return state.identities.filter((identity) => identity.vaultId.value === vaultId.value);
110
+ async delete(secretId) {
111
+ try {
112
+ await fs.unlink(this._getPath(secretId));
113
+ }
114
+ catch { }
127
115
  }
128
116
  }
129
- /**
130
- * @internal
131
- */
132
117
  export class FileAuditLog {
133
- _storage;
134
- _key;
135
- _lockKey;
136
- constructor(_storage, _key = "audit.jsonl", _lockKey = "lock-audit") {
137
- this._storage = _storage;
138
- this._key = _key;
139
- this._lockKey = _lockKey;
140
- }
141
- hash(value) {
142
- return createHash("sha256").update(value).digest("hex");
143
- }
144
- verifyEnvelopeChain(lines) {
145
- const entries = [];
146
- let previousHash = "GENESIS";
147
- for (const line of lines) {
148
- const parsed = JSON.parse(line);
149
- if (!parsed.entry || typeof parsed.prevHash !== "string" || typeof parsed.hash !== "string") {
150
- throw new Error("audit chain malformed");
151
- }
152
- const payload = JSON.stringify({
153
- prevHash: parsed.prevHash,
154
- entry: parsed.entry,
155
- });
156
- const expectedHash = this.hash(payload);
157
- if (parsed.prevHash !== previousHash || parsed.hash !== expectedHash) {
158
- throw new Error("audit chain verification failed");
159
- }
160
- previousHash = parsed.hash;
161
- entries.push(parsed.entry);
162
- }
163
- return entries;
118
+ _baseDir;
119
+ constructor(baseDir) {
120
+ this._baseDir = path.join(baseDir, "audit");
164
121
  }
165
- async loadEntries() {
166
- const payload = await this._storage.read(this._key);
167
- if (!payload) {
168
- return [];
169
- }
170
- const lines = payload.toString("utf8").split("\n").filter(Boolean);
171
- return this.verifyEnvelopeChain(lines);
122
+ _getPath(vaultId) {
123
+ return path.join(this._baseDir, vaultId.value, "log.jsonl");
172
124
  }
173
125
  async append(entry) {
174
- await withStorageLock(this._storage, this._lockKey, async () => {
175
- const payload = await this._storage.read(this._key);
176
- const lines = payload ? payload.toString("utf8").split("\n").filter(Boolean) : [];
177
- this.verifyEnvelopeChain(lines);
178
- const previousHash = lines.length
179
- ? JSON.parse(lines[lines.length - 1]).hash
180
- : "GENESIS";
181
- const nextEnvelope = {
182
- prevHash: previousHash,
183
- entry,
184
- hash: this.hash(JSON.stringify({ prevHash: previousHash, entry })),
185
- };
186
- const contents = [...lines, JSON.stringify(nextEnvelope)].join("\n") + "\n";
187
- await this._storage.write(this._key, Buffer.from(contents, "utf8"));
188
- });
126
+ const filePath = this._getPath(entry.vaultId);
127
+ await ensureDir(path.dirname(filePath));
128
+ await fs.appendFile(filePath, JSON.stringify(entry) + "\n");
189
129
  }
190
130
  async query(query) {
191
- const entries = await this.loadEntries();
192
- return entries.filter((entry) => {
193
- if (query.actorId && entry.actor.id !== query.actorId)
194
- return false;
195
- if (query.secretAlias && entry.secretAlias !== query.secretAlias)
196
- return false;
197
- if (query.requestId && entry.requestId !== query.requestId)
198
- return false;
199
- if (query.since && entry.occurredAt < query.since)
200
- return false;
201
- return true;
202
- });
131
+ const filePath = this._getPath(query.vaultId);
132
+ try {
133
+ const content = await fs.readFile(filePath, "utf-8");
134
+ const lines = content.split("\n").filter(l => !!l);
135
+ const entries = lines.map(l => JSON.parse(l));
136
+ return entries.filter(e => {
137
+ if (query.secretAlias && e.secretAlias !== query.secretAlias)
138
+ return false;
139
+ return true;
140
+ });
141
+ }
142
+ catch {
143
+ return [];
144
+ }
203
145
  }
204
146
  }
205
- /**
206
- * @internal
207
- */
208
- export class FileSecretCustody {
209
- _storage;
210
- _vaultWorkingKey;
211
- _keyPrefix;
212
- constructor(_storage, _vaultWorkingKey, _keyPrefix = "secret") {
213
- this._storage = _storage;
214
- this._vaultWorkingKey = _vaultWorkingKey;
215
- this._keyPrefix = _keyPrefix;
216
- }
217
- key(secretId) {
218
- return `${this._keyPrefix}-${secretId.value}.sealed`;
147
+ export class FileAgentIdentityRegistry {
148
+ _baseDir;
149
+ constructor(baseDir) {
150
+ this._baseDir = path.join(baseDir, "agents");
219
151
  }
220
- async store(secretId, plaintext) {
221
- await withStorageLock(this._storage, `${this.key(secretId)}:lock`, async () => {
222
- const sealed = sealBlob({
223
- version: "v1.0",
224
- secrets: {
225
- material: plaintext,
226
- },
227
- secretMetadata: {
228
- secretId: secretId.value,
229
- },
230
- }, this._vaultWorkingKey);
231
- await this._storage.write(this.key(secretId), Buffer.from(sealed, "utf8"));
232
- });
152
+ _getPath(vaultId, rootAgentId) {
153
+ return path.join(this._baseDir, vaultId.value, `${rootAgentId}.json`);
233
154
  }
234
- async load(secretId) {
235
- const payload = await this._storage.read(this.key(secretId));
236
- if (!payload) {
155
+ async register(identity) {
156
+ const filePath = this._getPath(identity.vaultId, identity.rootAgentId);
157
+ await ensureDir(path.dirname(filePath));
158
+ await fs.writeFile(filePath, JSON.stringify(identity, null, 2));
159
+ }
160
+ async get(vaultId, rootAgentId) {
161
+ try {
162
+ const content = await fs.readFile(this._getPath(vaultId, rootAgentId), "utf-8");
163
+ return JSON.parse(content);
164
+ }
165
+ catch {
237
166
  return null;
238
167
  }
239
- const unsealed = unsealBlob(payload.toString("utf8"), this._vaultWorkingKey);
240
- return unsealed.secrets.material ?? null;
241
168
  }
242
- async delete(secretId) {
243
- await withStorageLock(this._storage, `${this.key(secretId)}:lock`, async () => {
244
- await this._storage.delete(this.key(secretId));
245
- });
169
+ async list(vaultId) {
170
+ const dir = path.join(this._baseDir, vaultId.value);
171
+ try {
172
+ const files = await fs.readdir(dir);
173
+ return await Promise.all(files.filter(f => f.endsWith(".json")).map(async (f) => {
174
+ const content = await fs.readFile(path.join(dir, f), "utf-8");
175
+ return JSON.parse(content);
176
+ }));
177
+ }
178
+ catch {
179
+ return [];
180
+ }
246
181
  }
247
182
  }
248
- /**
249
- * @internal
250
- */
251
- export class FileReplayGuard {
252
- _lockKey;
253
- _ttlMs;
254
- _repo;
255
- constructor(storage, vaultWorkingKey, key = "replay.sealed", _lockKey = "lock-replay", _ttlMs = 5 * 60 * 1000) {
256
- this._lockKey = _lockKey;
257
- this._ttlMs = _ttlMs;
258
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
259
- }
260
- async assertNotReplayed(request) {
261
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
262
- const now = Date.now();
263
- const state = await this._repo.read({ seen: {} });
264
- const nextSeen = {};
265
- for (const [key, seenAt] of Object.entries(state.seen)) {
266
- if (now - seenAt <= this._ttlMs) {
267
- nextSeen[key] = seenAt;
183
+ export class FileAgentSecretGrantRegistry {
184
+ _baseDir;
185
+ constructor(baseDir) {
186
+ this._baseDir = path.join(baseDir, "grants", "agent_secrets");
187
+ }
188
+ _getPath(vaultId, rootAgentId, secretAlias) {
189
+ return path.join(this._baseDir, vaultId.value, rootAgentId, `${Buffer.from(secretAlias).toString("hex")}.json`);
190
+ }
191
+ async upsert(grant) {
192
+ const filePath = this._getPath(grant.vaultId, grant.rootAgentId, grant.secretAlias);
193
+ await ensureDir(path.dirname(filePath));
194
+ await fs.writeFile(filePath, JSON.stringify(grant, null, 2));
195
+ }
196
+ async get(vaultId, rootAgentId, secretAlias) {
197
+ try {
198
+ const content = await fs.readFile(this._getPath(vaultId, rootAgentId, secretAlias), "utf-8");
199
+ return JSON.parse(content);
200
+ }
201
+ catch {
202
+ return null;
203
+ }
204
+ }
205
+ async list(vaultId, rootAgentId) {
206
+ try {
207
+ const results = [];
208
+ const vaultDir = path.join(this._baseDir, vaultId.value);
209
+ const agentDirs = rootAgentId ? [rootAgentId] : await fs.readdir(vaultDir);
210
+ for (const aid of agentDirs) {
211
+ const agentDir = path.join(vaultDir, aid);
212
+ try {
213
+ const files = await fs.readdir(agentDir);
214
+ for (const f of files) {
215
+ if (f.endsWith(".json")) {
216
+ const content = await fs.readFile(path.join(agentDir, f), "utf-8");
217
+ results.push(JSON.parse(content));
218
+ }
219
+ }
220
+ }
221
+ catch {
222
+ continue;
268
223
  }
269
224
  }
270
- const replayKey = `${request.agent.id}:${request.requestId}`;
271
- if (replayKey in nextSeen) {
272
- throw new VaultCoreError("request replay detected", "VAULT_DISPATCH_DENIED");
273
- }
274
- nextSeen[replayKey] = now;
275
- await this._repo.write({ seen: nextSeen }, "replay_guard_state");
276
- });
225
+ return results;
226
+ }
227
+ catch {
228
+ return [];
229
+ }
230
+ }
231
+ async delete(vaultId, rootAgentId, secretAlias) {
232
+ try {
233
+ await fs.unlink(this._getPath(vaultId, rootAgentId, secretAlias));
234
+ }
235
+ catch { }
277
236
  }
278
237
  }
279
- /**
280
- * @internal
281
- */
282
- export class FileCapabilityRegistry {
283
- _lockKey;
284
- _repo;
285
- constructor(storage, vaultWorkingKey, key = "capabilities.sealed", _lockKey = "lock-capabilities") {
286
- this._lockKey = _lockKey;
287
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
288
- }
289
- async loadState() {
290
- return this._repo.read({ capabilities: [] });
291
- }
292
- async upsert(capability) {
293
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
294
- const state = await this.loadState();
295
- const next = state.capabilities.filter((candidate) => !(candidate.vaultId.value === capability.vaultId.value
296
- && candidate.agentId === capability.agentId
297
- && ((!!capability.capabilityId && candidate.capabilityId === capability.capabilityId)
298
- || (!!capability.requestId && candidate.requestId === capability.requestId))));
299
- next.push(capability);
300
- await this._repo.write({ capabilities: next }, "capability_state");
301
- });
302
- }
303
- async getByCapabilityId(vaultId, agentId, capabilityId) {
304
- const state = await this.loadState();
305
- return state.capabilities.find((capability) => capability.vaultId.value === vaultId.value
306
- && capability.agentId === agentId
307
- && capability.capabilityId === capabilityId) ?? null;
308
- }
309
- async getByRequestId(vaultId, requestId) {
310
- const state = await this.loadState();
311
- return state.capabilities.find((capability) => capability.vaultId.value === vaultId.value
312
- && capability.requestId === requestId) ?? null;
313
- }
314
- async deleteByRequestId(vaultId, requestId) {
315
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
316
- const state = await this.loadState();
317
- const next = state.capabilities.filter((capability) => !(capability.vaultId.value === vaultId.value && capability.requestId === requestId));
318
- await this._repo.write({ capabilities: next }, "capability_state");
319
- });
320
- }
321
- async list(vaultId, agentId) {
322
- const state = await this.loadState();
323
- return state.capabilities.filter((capability) => {
324
- if (capability.vaultId.value !== vaultId.value)
325
- return false;
326
- if (agentId && capability.agentId !== agentId)
327
- return false;
328
- return true;
329
- });
238
+ export class FileSecretDestinationGrantRegistry {
239
+ _baseDir;
240
+ constructor(baseDir) {
241
+ this._baseDir = path.join(baseDir, "grants", "secret_destinations");
242
+ }
243
+ _getPath(vaultId, secretAlias, domain) {
244
+ return path.join(this._baseDir, vaultId.value, Buffer.from(secretAlias).toString("hex"), `${Buffer.from(domain).toString("hex")}.json`);
245
+ }
246
+ async upsert(grant) {
247
+ const filePath = this._getPath(grant.vaultId, grant.secretAlias, grant.domain);
248
+ await ensureDir(path.dirname(filePath));
249
+ await fs.writeFile(filePath, JSON.stringify(grant, null, 2));
250
+ }
251
+ async get(vaultId, secretAlias, domain) {
252
+ try {
253
+ const content = await fs.readFile(this._getPath(vaultId, secretAlias, domain), "utf-8");
254
+ return JSON.parse(content);
255
+ }
256
+ catch {
257
+ return null;
258
+ }
259
+ }
260
+ async list(vaultId, secretAlias) {
261
+ try {
262
+ const results = [];
263
+ const vaultDir = path.join(this._baseDir, vaultId.value);
264
+ const aliasDirs = secretAlias ? [Buffer.from(secretAlias).toString("hex")] : await fs.readdir(vaultDir);
265
+ for (const aid of aliasDirs) {
266
+ const aliasDir = path.join(vaultDir, aid);
267
+ try {
268
+ const files = await fs.readdir(aliasDir);
269
+ for (const f of files) {
270
+ if (f.endsWith(".json")) {
271
+ const content = await fs.readFile(path.join(aliasDir, f), "utf-8");
272
+ results.push(JSON.parse(content));
273
+ }
274
+ }
275
+ }
276
+ catch {
277
+ continue;
278
+ }
279
+ }
280
+ return results;
281
+ }
282
+ catch {
283
+ return [];
284
+ }
285
+ }
286
+ async delete(vaultId, secretAlias, domain) {
287
+ try {
288
+ await fs.unlink(this._getPath(vaultId, secretAlias, domain));
289
+ }
290
+ catch { }
330
291
  }
331
292
  }
332
293
  export class FileRequestRecordRegistry {
333
- _lockKey;
334
- _repo;
335
- constructor(storage, vaultWorkingKey, key = "requests.sealed", _lockKey = "lock-requests") {
336
- this._lockKey = _lockKey;
337
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
294
+ _baseDir;
295
+ constructor(baseDir) {
296
+ this._baseDir = path.join(baseDir, "requests");
338
297
  }
339
- async loadState() {
340
- return this._repo.read({ records: [] });
298
+ _getPath(vaultId, requestId) {
299
+ return path.join(this._baseDir, vaultId.value, `${requestId}.json`);
341
300
  }
342
301
  async save(record) {
343
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
344
- const state = await this.loadState();
345
- const next = state.records.filter((candidate) => !(candidate.vaultId.value === record.vaultId.value && candidate.requestId === record.requestId));
346
- next.push(record);
347
- await this._repo.write({ records: next }, "request_record_state");
348
- });
302
+ const filePath = this._getPath(record.vaultId, record.requestId);
303
+ await ensureDir(path.dirname(filePath));
304
+ await fs.writeFile(filePath, JSON.stringify(record, null, 2));
349
305
  }
350
306
  async get(vaultId, requestId) {
351
- const state = await this.loadState();
352
- return state.records.find((record) => record.vaultId.value === vaultId.value && record.requestId === requestId) ?? null;
353
- }
354
- async list(vaultId, agentId) {
355
- const state = await this.loadState();
356
- return state.records.filter((record) => {
357
- if (record.vaultId.value !== vaultId.value)
358
- return false;
359
- if (agentId && record.agentId !== agentId)
360
- return false;
361
- return true;
362
- });
363
- }
364
- }
365
- /**
366
- * @internal
367
- */
368
- export class FileRateLimitStore {
369
- _lockKey;
370
- _repo;
371
- constructor(storage, vaultWorkingKey, key = "rate-limits.sealed", _lockKey = "lock-rate-limits") {
372
- this._lockKey = _lockKey;
373
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
374
- }
375
- async consume(key, maxRequests, windowMs, nowMs) {
376
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
377
- const state = await this._repo.read({ buckets: {} });
378
- const nextBuckets = {};
379
- for (const [bucketKey, bucket] of Object.entries(state.buckets)) {
380
- if (nowMs < bucket.resetAt) {
381
- nextBuckets[bucketKey] = bucket;
382
- }
383
- }
384
- const current = nextBuckets[key];
385
- if (!current || nowMs >= current.resetAt) {
386
- nextBuckets[key] = {
387
- count: 1,
388
- resetAt: nowMs + windowMs,
389
- };
390
- }
391
- else {
392
- if (current.count >= maxRequests) {
393
- throw new VaultCoreError("capability rate limit exceeded", "VAULT_DISPATCH_DENIED");
394
- }
395
- current.count += 1;
396
- }
397
- await this._repo.write({ buckets: nextBuckets }, "rate_limit_state");
398
- });
307
+ try {
308
+ const content = await fs.readFile(this._getPath(vaultId, requestId), "utf-8");
309
+ return JSON.parse(content);
310
+ }
311
+ catch {
312
+ return null;
313
+ }
399
314
  }
400
- }
401
- /**
402
- * @internal
403
- */
404
- export class FileCapabilityRevocationRegistry {
405
- _lockKey;
406
- _repo;
407
- constructor(storage, vaultWorkingKey, key = "revocations.sealed", _lockKey = "lock-revocations") {
408
- this._lockKey = _lockKey;
409
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
410
- }
411
- compositeKey(vaultId, agentId, capabilityId) {
412
- return `${vaultId.value}:${agentId}:${capabilityId}`;
413
- }
414
- async get(vaultId, agentId, capabilityId) {
415
- const state = await this._repo.read({ versions: {} });
416
- return state.versions[this.compositeKey(vaultId, agentId, capabilityId)] ?? 0;
417
- }
418
- async revoke(vaultId, agentId, capabilityId) {
419
- return withStorageLock(this._repo.storage, this._lockKey, async () => {
420
- const state = await this._repo.read({ versions: {} });
421
- const key = this.compositeKey(vaultId, agentId, capabilityId);
422
- const next = (state.versions[key] ?? 0) + 1;
423
- state.versions[key] = next;
424
- await this._repo.write(state, "revocation_state");
425
- return next;
426
- });
315
+ async list(vaultId, rootAgentId) {
316
+ const dir = path.join(this._baseDir, vaultId.value);
317
+ try {
318
+ const files = await fs.readdir(dir);
319
+ const records = await Promise.all(files.filter(f => f.endsWith(".json")).map(async (f) => {
320
+ const content = await fs.readFile(path.join(dir, f), "utf-8");
321
+ return JSON.parse(content);
322
+ }));
323
+ return rootAgentId ? records.filter(r => r.rootAgentId === rootAgentId) : records;
324
+ }
325
+ catch {
326
+ return [];
327
+ }
427
328
  }
428
329
  }
429
- /**
430
- * @internal
431
- */
432
330
  export class FileCustomHttpFlowRegistry {
433
- _lockKey;
434
- _repo;
435
- constructor(storage, vaultWorkingKey, key = "custom-flows.sealed", _lockKey = "lock-custom-flows") {
436
- this._lockKey = _lockKey;
437
- this._repo = new SealedJsonRepository(storage, key, vaultWorkingKey);
331
+ _baseDir;
332
+ constructor(baseDir) {
333
+ this._baseDir = path.join(baseDir, "flows");
438
334
  }
439
- async loadState() {
440
- return this._repo.read({ flows: [] });
335
+ _getPath(vaultId, flowId) {
336
+ return path.join(this._baseDir, vaultId.value, `${flowId}.json`);
441
337
  }
442
338
  async register(flow) {
443
- await withStorageLock(this._repo.storage, this._lockKey, async () => {
444
- const state = await this.loadState();
445
- const next = state.flows.filter((candidate) => candidate.flowId !== flow.flowId);
446
- next.push(flow);
447
- await this._repo.write({ flows: next }, "custom_flow_state");
448
- });
339
+ const filePath = this._getPath(flow.vaultId, flow.flowId);
340
+ await ensureDir(path.dirname(filePath));
341
+ await fs.writeFile(filePath, JSON.stringify(flow, null, 2));
449
342
  }
450
343
  async get(vaultId, flowId) {
451
- const state = await this.loadState();
452
- return state.flows.find((flow) => flow.vaultId.value === vaultId.value && flow.flowId === flowId) ?? null;
344
+ try {
345
+ const content = await fs.readFile(this._getPath(vaultId, flowId), "utf-8");
346
+ return JSON.parse(content);
347
+ }
348
+ catch {
349
+ return null;
350
+ }
453
351
  }
454
352
  }
353
+ export const DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY = "master_key.sealed";
354
+ export async function initializeVaultCustody(storage, options) {
355
+ const workingKey = crypto.randomBytes(32).toString("hex");
356
+ const recoveryKey = crypto.randomBytes(32).toString("hex");
357
+ const blob = JSON.stringify({ workingKey, recoveryKey });
358
+ await storage.write(DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY, Buffer.from(blob));
359
+ return { vaultWorkingKey: workingKey, vaultRecoveryKey: recoveryKey };
360
+ }
361
+ export async function recoverVaultWorkingKey(storage, recoveryKey) {
362
+ const data = await storage.read(DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY);
363
+ if (!data)
364
+ throw new Error("Vault custody blob not found");
365
+ const { workingKey } = JSON.parse(data.toString());
366
+ return workingKey;
367
+ }
455
368
  export function createPersistentVaultCoreDependencies(storage, options) {
456
- const defaults = createVaultCoreDependencies(options);
457
- const agentIdentities = new FileAgentIdentityRegistry(storage, options.vaultWorkingKey);
458
- const sessionTokens = defaults.sessionTokens;
459
- const capabilityRevocations = new FileCapabilityRevocationRegistry(storage, options.vaultWorkingKey);
460
- const capabilities = new FileCapabilityRegistry(storage, options.vaultWorkingKey);
461
- const requests = new FileRequestRecordRegistry(storage, options.vaultWorkingKey);
462
- const customFlows = new FileCustomHttpFlowRegistry(storage, options.vaultWorkingKey);
369
+ const baseDir = storage.getBaseDir();
463
370
  return {
464
- vaultId: defaults.vaultId,
465
- secrets: new FileSecretRepository(storage, options.vaultWorkingKey),
466
- custody: new FileSecretCustody(storage, options.vaultWorkingKey),
467
- audit: new FileAuditLog(storage),
468
- agentIdentities,
469
- policy: new DefaultPolicyEngine({
470
- ...(options.policy ?? {}),
471
- capabilityRevocationRegistry: capabilityRevocations,
472
- rateLimitStore: new FileRateLimitStore(storage, options.vaultWorkingKey),
473
- }),
474
- replayGuard: new FileReplayGuard(storage, options.vaultWorkingKey, "replay.sealed", "lock-replay", options.proofVerifier?.maxSkewMs ?? (5 * 60 * 1000)),
475
- agentProofVerifier: new SignatureAgentProofVerifier(agentIdentities, sessionTokens, options.proofVerifier),
476
- capabilityStates: capabilities,
477
- requests,
478
- customFlows,
479
- sessionTokens,
480
- clock: defaults.clock,
481
- ids: defaults.ids,
482
- executor: defaults.executor,
483
- capabilityRevocations, // Added for parity with legacy behavior/testing
371
+ vaultId: { value: options.vaultId },
372
+ ids: new RandomIdGenerator(),
373
+ clock: new SystemClock(),
374
+ agentRecords: new FileAgentIdentityRegistry(baseDir),
375
+ agentSecretGrants: new FileAgentSecretGrantRegistry(baseDir),
376
+ secretDestinationGrants: new FileSecretDestinationGrantRegistry(baseDir),
377
+ customFlows: new FileCustomHttpFlowRegistry(baseDir),
378
+ audit: new FileAuditLog(baseDir),
379
+ requests: new FileRequestRecordRegistry(baseDir),
380
+ custody: new FileSecretCustody(baseDir, options.vaultWorkingKey),
381
+ secrets: new FileSecretRepository(baseDir),
382
+ policy: new DefaultPolicyEngine(),
383
+ replayGuard: { assertNotReplayed: async () => { } },
384
+ agentProofVerifier: { verify: async () => { } },
385
+ sessionTokens: {
386
+ issue: async () => "dummy",
387
+ verify: async () => true,
388
+ revoke: async () => { },
389
+ list: async () => []
390
+ },
391
+ executor: { dispatch: async () => ({ status: "SUCCEEDED", response: { status: 200, statusText: "OK", headers: {}, body: "{}" } }) }
484
392
  };
485
393
  }
486
394
  //# sourceMappingURL=persistence.js.map