@the-ai-company/cbio-node-runtime 1.71.0 → 1.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -35
- package/dist/clients/agent/client.d.ts +3 -6
- package/dist/clients/agent/client.js +15 -11
- package/dist/clients/agent/client.js.map +1 -1
- package/dist/clients/agent/contracts.d.ts +4 -4
- package/dist/clients/agent/index.d.ts +1 -1
- package/dist/clients/owner/client.js +12 -10
- package/dist/clients/owner/client.js.map +1 -1
- package/dist/clients/owner/contracts.d.ts +4 -4
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.js +1 -1
- package/dist/public-types.js.map +1 -1
- package/dist/runtime/bootstrap.js +22 -12
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/storage/prefix.d.ts +1 -1
- package/dist/storage/prefix.js +2 -2
- package/dist/storage/prefix.js.map +1 -1
- package/dist/vault-core/contracts.d.ts +21 -142
- package/dist/vault-core/contracts.js +0 -19
- package/dist/vault-core/contracts.js.map +1 -1
- package/dist/vault-core/core.d.ts +9 -10
- package/dist/vault-core/core.js +93 -224
- package/dist/vault-core/core.js.map +1 -1
- package/dist/vault-core/defaults.d.ts +2 -4
- package/dist/vault-core/defaults.js +50 -47
- package/dist/vault-core/defaults.js.map +1 -1
- package/dist/vault-core/index.d.ts +2 -2
- package/dist/vault-core/index.js +1 -1
- package/dist/vault-core/index.js.map +1 -1
- package/dist/vault-core/persistence.d.ts +2 -4
- package/dist/vault-core/persistence.js +82 -55
- package/dist/vault-core/persistence.js.map +1 -1
- package/dist/vault-core/ports.d.ts +2 -4
- package/dist/vault-ingress/defaults.d.ts +2 -2
- package/dist/vault-ingress/defaults.js +3 -3
- package/dist/vault-ingress/defaults.js.map +1 -1
- package/dist/vault-ingress/index.d.ts +6 -6
- package/dist/vault-ingress/index.js +17 -29
- package/dist/vault-ingress/index.js.map +1 -1
- package/dist/vault-ingress/remote-transport.d.ts +2 -2
- package/dist/vault-ingress/remote-transport.js +7 -7
- package/dist/vault-ingress/remote-transport.js.map +1 -1
- package/dist/vault-ingress/server-utils.d.ts +1 -2
- package/dist/vault-ingress/server-utils.js +1 -1
- package/dist/vault-ingress/server-utils.js.map +1 -1
- package/docs/ARCHITECTURE.md +16 -14
- package/docs/REFERENCE.md +20 -37
- package/docs/api/README.md +5 -9
- package/docs/api/classes/IdentityError.md +1 -1
- package/docs/api/classes/OwnerClientError.md +1 -1
- package/docs/api/classes/PersistentVaultAgentIdentityRegistry.md +3 -3
- package/docs/api/classes/PersistentVaultAgentSecretGrantRegistry.md +6 -6
- package/docs/api/classes/PersistentVaultAuditLog.md +2 -2
- package/docs/api/classes/PersistentVaultSecretCustody.md +4 -4
- package/docs/api/classes/PersistentVaultSecretDestinationGrantRegistry.md +7 -7
- package/docs/api/classes/PersistentVaultSecretRepository.md +4 -6
- package/docs/api/classes/VaultCore.md +24 -24
- package/docs/api/classes/VaultCoreError.md +1 -1
- package/docs/api/enumerations/DispatchStatus.md +1 -1
- package/docs/api/enumerations/IdentityErrorCode.md +1 -1
- package/docs/api/enumerations/OwnerClientErrorCode.md +1 -1
- package/docs/api/functions/createAgentClient.md +1 -3
- package/docs/api/functions/createIdentity.md +1 -1
- package/docs/api/functions/createOwnerClient.md +1 -1
- package/docs/api/functions/createPersistentVaultCoreDependencies.md +1 -1
- package/docs/api/functions/createVault.md +1 -1
- package/docs/api/functions/createVaultCore.md +1 -1
- package/docs/api/functions/createVaultCoreDependencies.md +1 -1
- package/docs/api/functions/createVaultService.md +1 -1
- package/docs/api/functions/createWorkspaceStorage.md +1 -1
- package/docs/api/functions/deriveRootAgentId.md +1 -1
- package/docs/api/functions/deriveVaultWorkingKeyFromPassword.md +1 -1
- package/docs/api/functions/getDefaultWorkspaceDir.md +1 -1
- package/docs/api/functions/handleVaultAgentControlHttp.md +1 -1
- package/docs/api/functions/handleVaultAuditSse.md +1 -1
- package/docs/api/functions/handleVaultHttpDispatch.md +1 -1
- package/docs/api/functions/handleVaultPendingDispatchSse.md +1 -1
- package/docs/api/functions/initializeVaultCustody.md +1 -1
- package/docs/api/functions/listVaults.md +1 -1
- package/docs/api/functions/openOwnerSession.md +1 -1
- package/docs/api/functions/readVaultProfile.md +1 -1
- package/docs/api/functions/recoverVault.md +1 -1
- package/docs/api/functions/recoverVaultWorkingKey.md +1 -1
- package/docs/api/functions/restoreIdentity.md +1 -1
- package/docs/api/functions/updateVaultMetadata.md +1 -1
- package/docs/api/functions/writeVaultProfile.md +1 -1
- package/docs/api/interfaces/AgentClient.md +5 -5
- package/docs/api/interfaces/AgentDispatchIntent.md +1 -1
- package/docs/api/interfaces/AgentDispatchTransport.md +5 -5
- package/docs/api/interfaces/AgentIdentity.md +1 -1
- package/docs/api/interfaces/AgentIdentityRecord.md +2 -2
- package/docs/api/interfaces/AgentRequestRecord.md +93 -11
- package/docs/api/interfaces/AgentRuntimeManifest.md +1 -1
- package/docs/api/interfaces/AgentSecretGrant.md +3 -3
- package/docs/api/interfaces/AgentSigner.md +1 -1
- package/docs/api/interfaces/AuditEntry.md +9 -59
- package/docs/api/interfaces/CbioRuntime.md +1 -3
- package/docs/api/interfaces/CreateAgentClientOptions.md +1 -1
- package/docs/api/interfaces/CreateIdentityOptions.md +1 -1
- package/docs/api/interfaces/CreateOwnerClientOptions.md +1 -1
- package/docs/api/interfaces/CreatePersistentVaultCoreDependenciesOptions.md +1 -1
- package/docs/api/interfaces/CreateVaultOptions.md +1 -1
- package/docs/api/interfaces/CreatedVault.md +1 -1
- package/docs/api/interfaces/DefaultPolicyEngineOptions.md +1 -1
- package/docs/api/interfaces/DispatchAuthorization.md +3 -3
- package/docs/api/interfaces/DispatchInstruction.md +3 -3
- package/docs/api/interfaces/DispatchRequest.md +4 -4
- package/docs/api/interfaces/DispatchResult.md +2 -2
- package/docs/api/interfaces/IStorageProvider.md +1 -1
- package/docs/api/interfaces/InitializeVaultCustodyOptions.md +1 -1
- package/docs/api/interfaces/InitializedVaultCustody.md +1 -1
- package/docs/api/interfaces/OpenOwnerSessionOptions.md +1 -1
- package/docs/api/interfaces/OwnerAgentProvisionResult.md +1 -1
- package/docs/api/interfaces/OwnerAuditSubscription.md +3 -3
- package/docs/api/interfaces/OwnerClient.md +7 -7
- package/docs/api/interfaces/OwnerCreateSecretInput.md +1 -1
- package/docs/api/interfaces/OwnerPendingDispatchSubscription.md +1 -1
- package/docs/api/interfaces/OwnerRemoveSecretInput.md +1 -1
- package/docs/api/interfaces/OwnerRequestRecord.md +73 -11
- package/docs/api/interfaces/OwnerSensitiveActionConfirmation.md +1 -1
- package/docs/api/interfaces/OwnerSensitiveActionContext.md +1 -1
- package/docs/api/interfaces/OwnerSession.md +1 -1
- package/docs/api/interfaces/OwnerUpdateSecretInput.md +1 -1
- package/docs/api/interfaces/PendingDispatchEvent.md +1 -1
- package/docs/api/interfaces/RecoverVaultOptions.md +1 -1
- package/docs/api/interfaces/RecoveredVault.md +1 -1
- package/docs/api/interfaces/RequestRecord.md +8 -7
- package/docs/api/interfaces/RestoreIdentityOptions.md +1 -1
- package/docs/api/interfaces/SecretDestinationGrant.md +3 -3
- package/docs/api/interfaces/SecretRecord.md +7 -7
- package/docs/api/interfaces/Signer.md +1 -1
- package/docs/api/interfaces/VaultApproveDispatchInput.md +1 -1
- package/docs/api/interfaces/VaultAuditQueryInput.md +1 -1
- package/docs/api/interfaces/VaultCoreDependenciesOptions.md +1 -1
- package/docs/api/interfaces/VaultCreateAgentInput.md +1 -1
- package/docs/api/interfaces/VaultExportSecretInput.md +3 -3
- package/docs/api/interfaces/VaultGetRequestInput.md +1 -1
- package/docs/api/interfaces/VaultGrantAgentSecretInput.md +1 -1
- package/docs/api/interfaces/VaultGrantSecretDestinationInput.md +1 -1
- package/docs/api/interfaces/VaultImportAgentInput.md +1 -1
- package/docs/api/interfaces/VaultIssueSessionTokenInput.md +1 -1
- package/docs/api/interfaces/VaultListAgentsInput.md +1 -1
- package/docs/api/interfaces/VaultListGrantsInput.md +1 -1
- package/docs/api/interfaces/VaultListRequestsInput.md +1 -1
- package/docs/api/interfaces/VaultListSecretsInput.md +1 -1
- package/docs/api/interfaces/VaultMetadata.md +1 -1
- package/docs/api/interfaces/VaultObject.md +1 -1
- package/docs/api/interfaces/VaultPrincipal.md +1 -1
- package/docs/api/interfaces/VaultProfile.md +1 -1
- package/docs/api/interfaces/VaultReadAgentPrivateKeyInput.md +1 -1
- package/docs/api/interfaces/VaultReadSecretPlaintextInput.md +1 -1
- package/docs/api/interfaces/VaultRevokeAgentSecretInput.md +1 -1
- package/docs/api/interfaces/VaultRevokeSecretDestinationInput.md +1 -1
- package/docs/api/interfaces/VaultRevokeSessionTokenInput.md +1 -1
- package/docs/api/interfaces/VaultService.md +14 -14
- package/docs/api/interfaces/VaultUpdateAgentInput.md +1 -1
- package/docs/api/type-aliases/AgentId.md +1 -1
- package/docs/api/type-aliases/AgentRequestResult.md +1 -1
- package/docs/api/type-aliases/CbioRuntimeModule.md +1 -1
- package/docs/api/type-aliases/DispatchApprovalDecision.md +1 -1
- package/docs/api/type-aliases/GrantStatus.md +1 -1
- package/docs/api/type-aliases/SecretAlias.md +7 -0
- package/docs/api/type-aliases/SecretId.md +7 -0
- package/docs/api/type-aliases/SecretLifecycleStatus.md +1 -1
- package/docs/api/type-aliases/VaultId.md +7 -0
- package/docs/api/type-aliases/VaultPrincipalKind.md +1 -1
- package/docs/api/variables/DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY.md +1 -1
- package/docs/zh/README.md +33 -66
- package/package.json +1 -1
- package/docs/api/enumerations/AuditOperation.md +0 -101
- package/docs/api/interfaces/AgentVisibleRequestRecord.md +0 -59
- package/docs/api/interfaces/AgentVisibleSecretRecord.md +0 -65
- package/docs/api/interfaces/OwnerVisibleRequestRecord.md +0 -79
- package/docs/api/interfaces/SecretAlias.md +0 -11
- package/docs/api/interfaces/SecretId.md +0 -11
- package/docs/api/interfaces/VaultId.md +0 -11
package/dist/vault-core/core.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DispatchStatus, } from "./contracts.js";
|
|
2
2
|
import { VaultCoreError } from "./errors.js";
|
|
3
3
|
import { getAgentToolbox } from "./tool-metadata.js";
|
|
4
4
|
import { InMemoryRequestRecordRegistry } from "./defaults.js";
|
|
@@ -17,19 +17,6 @@ function extractDomain(url) {
|
|
|
17
17
|
return url;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
function toAuditEntry(deps, actor, operation, decision, execution_status, detail, extra = {}) {
|
|
21
|
-
return {
|
|
22
|
-
event_id: deps.ids.newAuditEntryId(),
|
|
23
|
-
ts: deps.clock.nowIso(),
|
|
24
|
-
vault_id: deps.vault_id.value,
|
|
25
|
-
actor,
|
|
26
|
-
operation,
|
|
27
|
-
decision,
|
|
28
|
-
execution_status,
|
|
29
|
-
detail,
|
|
30
|
-
...extra,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
20
|
export class VaultCore {
|
|
34
21
|
_deps;
|
|
35
22
|
constructor(deps) {
|
|
@@ -52,13 +39,8 @@ export class VaultCore {
|
|
|
52
39
|
await this._deps.replayGuard.assertNotReplayed(command);
|
|
53
40
|
}
|
|
54
41
|
catch (error) {
|
|
55
|
-
const
|
|
56
|
-
await this.
|
|
57
|
-
request_id: command.request_id,
|
|
58
|
-
root_agent_id: command.agent.id,
|
|
59
|
-
secret_alias: command.secret_alias,
|
|
60
|
-
...extraAudit,
|
|
61
|
-
}));
|
|
42
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
43
|
+
await this._appendAuditEntry(command.agent, actionName, { ...command, ...extraAudit }, undefined, errorMsg);
|
|
62
44
|
throw error;
|
|
63
45
|
}
|
|
64
46
|
}
|
|
@@ -75,11 +57,7 @@ export class VaultCore {
|
|
|
75
57
|
granted_at: now,
|
|
76
58
|
};
|
|
77
59
|
await this._deps.agent_secretGrants.upsert(grant);
|
|
78
|
-
await this.
|
|
79
|
-
request_id: request?.request_id,
|
|
80
|
-
root_agent_id,
|
|
81
|
-
secret_id: secret_id.value,
|
|
82
|
-
}));
|
|
60
|
+
await this._appendAuditEntry(actor, "ownerGrantAgentSecret", { root_agent_id, secret_id, request_id: request?.request_id }, grant);
|
|
83
61
|
return grant;
|
|
84
62
|
}
|
|
85
63
|
async ownerGrantSecretDestination(actor, secret_id, site_id, request) {
|
|
@@ -94,30 +72,18 @@ export class VaultCore {
|
|
|
94
72
|
granted_at: now,
|
|
95
73
|
};
|
|
96
74
|
await this._deps.secret_destinationGrants.upsert(grant);
|
|
97
|
-
await this.
|
|
98
|
-
request_id: request?.request_id,
|
|
99
|
-
secret_id: secret_id.value,
|
|
100
|
-
site_id,
|
|
101
|
-
}));
|
|
75
|
+
await this._appendAuditEntry(actor, "ownerGrantSecretDestination", { secret_id, site_id, request_id: request?.request_id }, grant);
|
|
102
76
|
return grant;
|
|
103
77
|
}
|
|
104
78
|
async ownerRevokeAgentSecret(actor, root_agent_id, secret_id, request) {
|
|
105
79
|
this._assertOwnerPrincipal(actor);
|
|
106
80
|
await this._deps.agent_secretGrants.delete(this._deps.vault_id, root_agent_id, secret_id);
|
|
107
|
-
await this.
|
|
108
|
-
request_id: request?.request_id,
|
|
109
|
-
root_agent_id,
|
|
110
|
-
secret_id: secret_id.value,
|
|
111
|
-
}));
|
|
81
|
+
await this._appendAuditEntry(actor, "ownerRevokeAgentSecret", { root_agent_id, secret_id, request_id: request?.request_id }, undefined);
|
|
112
82
|
}
|
|
113
83
|
async ownerRevokeSecretDestination(actor, secret_id, site_id, request) {
|
|
114
84
|
this._assertOwnerPrincipal(actor);
|
|
115
85
|
await this._deps.secret_destinationGrants.delete(this._deps.vault_id, secret_id, site_id);
|
|
116
|
-
await this.
|
|
117
|
-
request_id: request?.request_id,
|
|
118
|
-
secret_id: secret_id.value,
|
|
119
|
-
site_id,
|
|
120
|
-
}));
|
|
86
|
+
await this._appendAuditEntry(actor, "ownerRevokeSecretDestination", { secret_id, site_id, request_id: request?.request_id }, undefined);
|
|
121
87
|
}
|
|
122
88
|
async ownerListGrants(actor, root_agent_id, secret_id) {
|
|
123
89
|
this._assertOwnerPrincipal(actor);
|
|
@@ -129,13 +95,13 @@ export class VaultCore {
|
|
|
129
95
|
}
|
|
130
96
|
// ─── Dispatch Authorization ───────────────────────────────────────────────────
|
|
131
97
|
async agentAuthorizeDispatch(request) {
|
|
132
|
-
const { agent,
|
|
133
|
-
if (!
|
|
134
|
-
return { vault_id: this._deps.vault_id, decision: "deny", reason: "
|
|
98
|
+
const { agent, secret_id, target_url } = request;
|
|
99
|
+
if (!secret_id) {
|
|
100
|
+
return { vault_id: this._deps.vault_id, decision: "deny", reason: "secret_id required", secret_id: null };
|
|
135
101
|
}
|
|
136
|
-
const secret = await this._deps.secrets.
|
|
102
|
+
const secret = await this._deps.secrets.getById(secret_id);
|
|
137
103
|
if (!secret) {
|
|
138
|
-
return { vault_id: this._deps.vault_id, decision: "deny", reason: `secret not found: ${
|
|
104
|
+
return { vault_id: this._deps.vault_id, decision: "deny", reason: `secret not found: ${secret_id}`, secret_id: null };
|
|
139
105
|
}
|
|
140
106
|
// 1. Check Agent-Secret Grant
|
|
141
107
|
const agent_secretGrant = await this._deps.agent_secretGrants.get(this._deps.vault_id, agent.id, secret.secret_id);
|
|
@@ -174,13 +140,7 @@ export class VaultCore {
|
|
|
174
140
|
method: request.method,
|
|
175
141
|
error: authorization.reason ?? "denied",
|
|
176
142
|
};
|
|
177
|
-
await this.
|
|
178
|
-
request_id: request.request_id,
|
|
179
|
-
root_agent_id: request.agent.id,
|
|
180
|
-
target: { kind: "http", url: request.target_url },
|
|
181
|
-
secret_alias: request.secret_alias,
|
|
182
|
-
secret_id: secret_id?.value,
|
|
183
|
-
}));
|
|
143
|
+
await this._appendAuditEntry(request.agent, "agentDispatchSecret", { request_id: request.request_id, root_agent_id: request.agent.id, target: request.target_url, secret_id }, result);
|
|
184
144
|
await this._updateRequestRecordInternal(request, result, secret_id);
|
|
185
145
|
return result;
|
|
186
146
|
}
|
|
@@ -193,13 +153,7 @@ export class VaultCore {
|
|
|
193
153
|
method: request.method,
|
|
194
154
|
};
|
|
195
155
|
await this._updateRequestRecordInternal(request, result, secret_id, authorization.missing_grants);
|
|
196
|
-
await this.
|
|
197
|
-
request_id: request.request_id,
|
|
198
|
-
root_agent_id: request.agent.id,
|
|
199
|
-
target: { kind: "http", url: request.target_url },
|
|
200
|
-
secret_alias: request.secret_alias,
|
|
201
|
-
secret_id: secret_id?.value,
|
|
202
|
-
}));
|
|
156
|
+
await this._appendAuditEntry(request.agent, "agentDispatchSecret", { request_id: request.request_id, root_agent_id: request.agent.id, target: request.target_url, secret_id }, result);
|
|
203
157
|
return result;
|
|
204
158
|
}
|
|
205
159
|
// Proceed with dispatch
|
|
@@ -223,13 +177,7 @@ export class VaultCore {
|
|
|
223
177
|
headers: request.headers,
|
|
224
178
|
body: request.body,
|
|
225
179
|
}, { record: secretRecord, plaintext });
|
|
226
|
-
await this.
|
|
227
|
-
request_id: request.request_id,
|
|
228
|
-
root_agent_id: request.agent.id,
|
|
229
|
-
target: { kind: "http", url: request.target_url },
|
|
230
|
-
secret_alias: request.secret_alias,
|
|
231
|
-
secret_id: secret_id.value,
|
|
232
|
-
}));
|
|
180
|
+
await this._appendAuditEntry(request.agent, "agentDispatchSecret", { request_id: request.request_id, root_agent_id: request.agent.id, target: request.target_url, secret_id }, result);
|
|
233
181
|
await this._updateRequestRecordInternal(request, result, secret_id);
|
|
234
182
|
return {
|
|
235
183
|
...result,
|
|
@@ -253,19 +201,14 @@ export class VaultCore {
|
|
|
253
201
|
execution: { status: DispatchStatus.DENIED },
|
|
254
202
|
};
|
|
255
203
|
await this._deps.requests.save(updated);
|
|
256
|
-
await this.
|
|
257
|
-
request_id,
|
|
258
|
-
root_agent_id: record.root_agent_id,
|
|
259
|
-
secret_alias: record.request.secret_alias,
|
|
260
|
-
secret_id: record.request.secret_id?.value,
|
|
261
|
-
}));
|
|
204
|
+
await this._appendAuditEntry(actor, "ownerApproveDispatch", { request_id, decision, root_agent_id: record.root_agent_id, secret_id: record.request.secret_id }, updated);
|
|
262
205
|
return null;
|
|
263
206
|
}
|
|
264
|
-
const
|
|
265
|
-
if (!
|
|
266
|
-
throw new VaultCoreError("record missing
|
|
207
|
+
const secret_id = record.request.secret_id;
|
|
208
|
+
if (!secret_id) {
|
|
209
|
+
throw new VaultCoreError("record missing secret_id", "VAULT_INTERNAL_ERROR");
|
|
267
210
|
}
|
|
268
|
-
const secret = await this._deps.secrets.
|
|
211
|
+
const secret = await this._deps.secrets.getById(secret_id);
|
|
269
212
|
if (!secret) {
|
|
270
213
|
throw new VaultCoreError("secret not found during approval", "VAULT_SECRET_NOT_FOUND");
|
|
271
214
|
}
|
|
@@ -291,18 +234,7 @@ export class VaultCore {
|
|
|
291
234
|
granted_at: now,
|
|
292
235
|
}),
|
|
293
236
|
]);
|
|
294
|
-
await this.
|
|
295
|
-
request_id,
|
|
296
|
-
root_agent_id: record.root_agent_id,
|
|
297
|
-
secret_alias: secret_alias,
|
|
298
|
-
secret_id: secret.secret_id.value,
|
|
299
|
-
}));
|
|
300
|
-
await this._appendAudit(toAuditEntry(this._deps, actor, AuditOperation.GRANT_DESTINATION, "allowed", "succeeded", "granted during dispatch approval", {
|
|
301
|
-
request_id,
|
|
302
|
-
secret_alias: secret_alias,
|
|
303
|
-
secret_id: secret.secret_id.value,
|
|
304
|
-
site_id,
|
|
305
|
-
}));
|
|
237
|
+
await this._appendAuditEntry(actor, "ownerApproveDispatch_grant", { request_id, root_agent_id: record.root_agent_id, secret_id: secret.secret_id, site_id }, { status: "granted", request_id });
|
|
306
238
|
}
|
|
307
239
|
// Execute
|
|
308
240
|
const plaintext = await this._deps.custody.load(secret.secret_id);
|
|
@@ -329,19 +261,13 @@ export class VaultCore {
|
|
|
329
261
|
execution: { status: result.status },
|
|
330
262
|
};
|
|
331
263
|
await this._deps.requests.save(finalRecord);
|
|
332
|
-
await this.
|
|
333
|
-
|
|
334
|
-
root_agent_id: record.root_agent_id,
|
|
335
|
-
secret_alias: record.request.secret_alias,
|
|
336
|
-
secret_id: record.request.secret_id?.value,
|
|
337
|
-
}));
|
|
338
|
-
await this._appendAudit(toAuditEntry(this._deps, { kind: "agent", id: record.root_agent_id }, AuditOperation.SECRET_DISPATCH, "allowed", result.status === DispatchStatus.SUCCEEDED ? "succeeded" : "failed", result.status === DispatchStatus.SUCCEEDED ? "dispatch completed" : (result.error ?? "dispatch failed"), {
|
|
264
|
+
await this._appendAuditEntry(actor, "ownerApproveDispatch", { request_id, decision, root_agent_id: record.root_agent_id, secret_id: record.request.secret_id }, result);
|
|
265
|
+
await this._appendAuditEntry({ kind: "agent", id: record.root_agent_id }, "agentDispatchSecret", {
|
|
339
266
|
request_id,
|
|
340
267
|
root_agent_id: record.root_agent_id,
|
|
341
268
|
target: { kind: "http", url: record.request.target_url },
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}));
|
|
269
|
+
secret_id: secret.secret_id,
|
|
270
|
+
}, result);
|
|
345
271
|
return result;
|
|
346
272
|
}
|
|
347
273
|
// ─── Agent Control APIs ───────────────────────────────────────────────────────
|
|
@@ -355,11 +281,11 @@ export class VaultCore {
|
|
|
355
281
|
this._deps.agent_secretGrants.list(this._deps.vault_id, command.agent.id),
|
|
356
282
|
this._deps.secret_destinationGrants.list(this._deps.vault_id),
|
|
357
283
|
]);
|
|
358
|
-
const secret_ids = new Set(agent_secrets.map(g => g.secret_id
|
|
359
|
-
const relevantDestinations = secret_destinations.filter(d => secret_ids.has(d.secret_id
|
|
284
|
+
const secret_ids = new Set(agent_secrets.map(g => g.secret_id));
|
|
285
|
+
const relevantDestinations = secret_destinations.filter(d => secret_ids.has(d.secret_id));
|
|
360
286
|
return {
|
|
361
287
|
root_agent_id: command.agent.id,
|
|
362
|
-
vault_id: this._deps.vault_id
|
|
288
|
+
vault_id: this._deps.vault_id,
|
|
363
289
|
issued_at: this._deps.clock.nowIso(),
|
|
364
290
|
agent: {
|
|
365
291
|
root_agent_id: agentRecord.root_agent_id,
|
|
@@ -378,7 +304,7 @@ export class VaultCore {
|
|
|
378
304
|
await this._verifyAgentControlProof(command, "list_secrets");
|
|
379
305
|
const records = await this._deps.secrets.list(this._deps.vault_id);
|
|
380
306
|
const grants = await this._deps.agent_secretGrants.list(this._deps.vault_id, command.agent.id);
|
|
381
|
-
const approvedSecretIds = new Set(grants.filter(g => g.status === "approved").map(g => g.secret_id
|
|
307
|
+
const approvedSecretIds = new Set(grants.filter(g => g.status === "approved").map(g => g.secret_id));
|
|
382
308
|
return records.map(record => ({
|
|
383
309
|
vault_id: record.vault_id,
|
|
384
310
|
secret_id: record.secret_id,
|
|
@@ -389,13 +315,13 @@ export class VaultCore {
|
|
|
389
315
|
source: record.source,
|
|
390
316
|
created_at: record.created_at,
|
|
391
317
|
updated_at: record.updated_at,
|
|
392
|
-
granted: approvedSecretIds.has(record.secret_id
|
|
318
|
+
granted: approvedSecretIds.has(record.secret_id),
|
|
393
319
|
}));
|
|
394
320
|
}
|
|
395
321
|
async agentListRequests(command) {
|
|
396
322
|
await this._verifyAgentControlProof(command, "list_requests");
|
|
397
323
|
const records = await this._deps.requests.list(this._deps.vault_id, command.agent.id);
|
|
398
|
-
return records.map(r => this.
|
|
324
|
+
return records.map(r => this.toAgentRequestRecord(r));
|
|
399
325
|
}
|
|
400
326
|
async agentGetRequest(command) {
|
|
401
327
|
await this._verifyAgentControlProof(command, "read_request");
|
|
@@ -403,27 +329,13 @@ export class VaultCore {
|
|
|
403
329
|
if (!record || record.root_agent_id !== command.agent.id) {
|
|
404
330
|
throw new VaultCoreError("request record not found", "VAULT_READ_DENIED");
|
|
405
331
|
}
|
|
406
|
-
return
|
|
407
|
-
request_id: record.request_id,
|
|
408
|
-
created_at: record.created_at,
|
|
409
|
-
requested_at: record.requested_at,
|
|
410
|
-
reason: record.reason,
|
|
411
|
-
request: {
|
|
412
|
-
target_url: record.request.target_url,
|
|
413
|
-
method: record.request.method,
|
|
414
|
-
headers: record.request.headers,
|
|
415
|
-
body: record.request.body,
|
|
416
|
-
secret_alias: record.request.secret_alias,
|
|
417
|
-
},
|
|
418
|
-
response: record.response,
|
|
419
|
-
execution_status: record.execution.status,
|
|
420
|
-
};
|
|
332
|
+
return this.toAgentRequestRecord(record);
|
|
421
333
|
}
|
|
422
334
|
// ─── Owner Management APIs ────────────────────────────────────────────────────
|
|
423
335
|
async ownerRegisterAgentIdentity(command) {
|
|
424
336
|
this._assertOwnerPrincipal(command.owner);
|
|
425
337
|
await this._deps.agentRecords.register(command.agentRecord);
|
|
426
|
-
await this.
|
|
338
|
+
await this._appendAuditEntry(command.owner, "ownerRegisterAgentIdentity", { root_agent_id: command.agentRecord.root_agent_id }, undefined);
|
|
427
339
|
}
|
|
428
340
|
async ownerUpdateAgentIdentity(command) {
|
|
429
341
|
this._assertOwnerPrincipal(command.owner);
|
|
@@ -432,13 +344,13 @@ export class VaultCore {
|
|
|
432
344
|
throw new VaultCoreError("agent identity not found", "VAULT_IDENTITY_NOT_FOUND");
|
|
433
345
|
const updated = { ...existing, nickname: command.nickname ?? existing.nickname, metadata: command.metadata ?? existing.metadata };
|
|
434
346
|
await this._deps.agentRecords.register(updated);
|
|
435
|
-
await this.
|
|
347
|
+
await this._appendAuditEntry(command.owner, "ownerUpdateAgentIdentity", { root_agent_id: command.root_agent_id }, updated);
|
|
436
348
|
return updated;
|
|
437
349
|
}
|
|
438
350
|
async ownerCreateSecret(command) {
|
|
439
351
|
this._assertOwnerPrincipal(command.owner);
|
|
440
352
|
await this._deps.policy.authorizeWrite(command);
|
|
441
|
-
const existing = await this._deps.secrets.getByAlias(
|
|
353
|
+
const existing = await this._deps.secrets.getByAlias(command.alias);
|
|
442
354
|
if (existing) {
|
|
443
355
|
throw new VaultCoreError(`secret alias already exists: "${command.alias}"`, "VAULT_ALIAS_ALREADY_EXISTS");
|
|
444
356
|
}
|
|
@@ -447,7 +359,7 @@ export class VaultCore {
|
|
|
447
359
|
const record = {
|
|
448
360
|
vault_id: command.vault_id,
|
|
449
361
|
secret_id,
|
|
450
|
-
alias:
|
|
362
|
+
alias: command.alias,
|
|
451
363
|
version: this._deps.ids.newVersion(),
|
|
452
364
|
lifecycle_status: "ACTIVE",
|
|
453
365
|
issuer_id: null,
|
|
@@ -457,19 +369,19 @@ export class VaultCore {
|
|
|
457
369
|
};
|
|
458
370
|
await this._deps.secrets.save(record);
|
|
459
371
|
await this._deps.custody.store(secret_id, command.plaintext);
|
|
460
|
-
await this.
|
|
372
|
+
await this._appendAuditEntry(command.owner, "ownerCreateSecret", { secret_alias: command.alias, secret_id }, record);
|
|
461
373
|
return record;
|
|
462
374
|
}
|
|
463
375
|
async ownerUpdateSecret(command) {
|
|
464
376
|
this._assertOwnerPrincipal(command.owner);
|
|
465
377
|
await this._deps.policy.authorizeWrite(command);
|
|
466
|
-
const existing = await this._deps.secrets.getByAlias(
|
|
378
|
+
const existing = await this._deps.secrets.getByAlias(command.alias);
|
|
467
379
|
if (!existing)
|
|
468
380
|
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
469
381
|
const finalAlias = command.new_alias && command.new_alias !== command.alias ? command.new_alias : command.alias;
|
|
470
382
|
const isRename = finalAlias !== command.alias;
|
|
471
383
|
if (isRename) {
|
|
472
|
-
const duplicate = await this._deps.secrets.getByAlias(
|
|
384
|
+
const duplicate = await this._deps.secrets.getByAlias(finalAlias);
|
|
473
385
|
if (duplicate) {
|
|
474
386
|
throw new VaultCoreError(`secret alias already exists: "${finalAlias}"`, "VAULT_ALIAS_ALREADY_EXISTS");
|
|
475
387
|
}
|
|
@@ -478,27 +390,24 @@ export class VaultCore {
|
|
|
478
390
|
const now = this._deps.clock.nowIso();
|
|
479
391
|
const record = {
|
|
480
392
|
...existing,
|
|
481
|
-
alias:
|
|
393
|
+
alias: finalAlias,
|
|
482
394
|
version: this._deps.ids.newVersion(),
|
|
483
395
|
updated_at: now,
|
|
484
396
|
};
|
|
485
|
-
// No migration needed! Grants and pending requests are already tied to secret_id
|
|
486
|
-
// or resolved via alias lookup at runtime.
|
|
487
|
-
await this._deps.secrets.save(record);
|
|
488
397
|
if (command.plaintext !== undefined) {
|
|
489
398
|
await this._deps.custody.store(secret_id, command.plaintext);
|
|
490
399
|
}
|
|
491
|
-
await this.
|
|
400
|
+
await this._deps.secrets.save(record);
|
|
401
|
+
await this._appendAuditEntry(command.owner, "ownerUpdateSecret", { secret_alias: finalAlias, secret_id }, record);
|
|
492
402
|
return record;
|
|
493
403
|
}
|
|
494
404
|
async ownerRemoveSecret(command) {
|
|
495
405
|
this._assertOwnerPrincipal(command.owner);
|
|
496
|
-
const record = await this._deps.secrets.getByAlias(
|
|
406
|
+
const record = await this._deps.secrets.getByAlias(command.alias);
|
|
497
407
|
if (!record)
|
|
498
408
|
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
499
409
|
await this._deps.secrets.delete(record.secret_id);
|
|
500
|
-
await this.
|
|
501
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditOperation.SECRET_DELETE, "allowed", "succeeded", `secret deleted: "${command.alias}"`, { secret_alias: command.alias, secret_id: record.secret_id.value }));
|
|
410
|
+
await this._appendAuditEntry(command.owner, "ownerRemoveSecret", { secret_alias: command.alias, secret_id: record.secret_id }, undefined);
|
|
502
411
|
}
|
|
503
412
|
async ownerReadAudit(actor, query) {
|
|
504
413
|
this._assertOwnerPrincipal(actor);
|
|
@@ -506,14 +415,34 @@ export class VaultCore {
|
|
|
506
415
|
}
|
|
507
416
|
async ownerExportSecret(actor, alias) {
|
|
508
417
|
this._assertOwnerPrincipal(actor);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
418
|
+
if (alias) {
|
|
419
|
+
const record = await this._deps.secrets.getByAlias(alias);
|
|
420
|
+
if (!record)
|
|
421
|
+
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
422
|
+
const plaintext = await this._deps.custody.load(record.secret_id);
|
|
423
|
+
await this._appendAuditEntry(actor, "ownerExportSecret", { secret_alias: alias, secret_id: record.secret_id }, undefined);
|
|
424
|
+
return [{
|
|
425
|
+
vault_id: this._deps.vault_id,
|
|
426
|
+
secret_id: record.secret_id,
|
|
427
|
+
alias: record.alias,
|
|
428
|
+
plaintext: plaintext ?? "MISSING",
|
|
429
|
+
exported_at: this._deps.clock.nowIso()
|
|
430
|
+
}];
|
|
431
|
+
}
|
|
432
|
+
// Full Vault Export
|
|
433
|
+
const records = await this._deps.secrets.list(this._deps.vault_id);
|
|
434
|
+
const exports = await Promise.all(records.map(async (record) => {
|
|
435
|
+
const plaintext = await this._deps.custody.load(record.secret_id);
|
|
436
|
+
return {
|
|
437
|
+
vault_id: this._deps.vault_id,
|
|
438
|
+
secret_id: record.secret_id,
|
|
439
|
+
alias: record.alias,
|
|
440
|
+
plaintext: plaintext ?? "MISSING", // Should not happen in healthy vault
|
|
441
|
+
exported_at: this._deps.clock.nowIso()
|
|
442
|
+
};
|
|
443
|
+
}));
|
|
444
|
+
await this._appendAuditEntry(actor, "ownerExportSecret_batch", {}, undefined);
|
|
445
|
+
return exports;
|
|
517
446
|
}
|
|
518
447
|
async ownerListAgents(actor) {
|
|
519
448
|
this._assertOwnerPrincipal(actor);
|
|
@@ -528,7 +457,7 @@ export class VaultCore {
|
|
|
528
457
|
async ownerListRequests(actor, root_agent_id) {
|
|
529
458
|
this._assertOwnerPrincipal(actor);
|
|
530
459
|
const records = await this._deps.requests.list(this._deps.vault_id, root_agent_id);
|
|
531
|
-
return records.map(r => this.
|
|
460
|
+
return records.map(r => this.toOwnerRequestRecord(r));
|
|
532
461
|
}
|
|
533
462
|
async ownerGetRequest(actor, request_id) {
|
|
534
463
|
this._assertOwnerPrincipal(actor);
|
|
@@ -556,7 +485,7 @@ export class VaultCore {
|
|
|
556
485
|
async ownerIssueSessionToken(request) {
|
|
557
486
|
this._assertOwnerPrincipal(request.actor);
|
|
558
487
|
const token = await this._deps.sessionTokenRegistry.issue(request.root_agent_id);
|
|
559
|
-
await this.
|
|
488
|
+
await this._appendAuditEntry(request.actor, "ownerIssueSessionToken", { root_agent_id: request.root_agent_id }, { root_agent_id: request.root_agent_id, issued_at: this._deps.clock.nowIso() });
|
|
560
489
|
return { token, root_agent_id: request.root_agent_id, issued_at: this._deps.clock.nowIso() };
|
|
561
490
|
}
|
|
562
491
|
async ownerIssueAllAgentSessionTokens(actor) {
|
|
@@ -567,15 +496,16 @@ export class VaultCore {
|
|
|
567
496
|
async ownerRevokeSessionToken(request) {
|
|
568
497
|
this._assertOwnerPrincipal(request.actor);
|
|
569
498
|
await this._deps.sessionTokenRegistry.revoke(request.token);
|
|
570
|
-
await this.
|
|
499
|
+
await this._appendAuditEntry(request.actor, "ownerRevokeSessionToken", { token: request.token }, undefined);
|
|
571
500
|
}
|
|
572
501
|
ownerOnPendingDispatch(subscription) {
|
|
573
502
|
return this._deps.audit.subscribe(this._deps.vault_id, {
|
|
574
|
-
|
|
503
|
+
function_names: ["agentDispatchSecret"],
|
|
575
504
|
onEvent: async (entry) => {
|
|
576
|
-
|
|
505
|
+
const request_id = entry.input?.request_id;
|
|
506
|
+
if (!request_id)
|
|
577
507
|
return;
|
|
578
|
-
const record = await this._deps.requests.get(this._deps.vault_id,
|
|
508
|
+
const record = await this._deps.requests.get(this._deps.vault_id, request_id);
|
|
579
509
|
if (!record || record.execution.status !== DispatchStatus.AWAITING_APPROVAL)
|
|
580
510
|
return;
|
|
581
511
|
const pendingEventId = record.pending_dispatch_event?.event_id ?? entry.event_id;
|
|
@@ -606,7 +536,6 @@ export class VaultCore {
|
|
|
606
536
|
method: request.method,
|
|
607
537
|
headers: request.headers,
|
|
608
538
|
body: request.body,
|
|
609
|
-
secret_alias: request.secret_alias,
|
|
610
539
|
secret_id,
|
|
611
540
|
},
|
|
612
541
|
execution: { status },
|
|
@@ -630,7 +559,6 @@ export class VaultCore {
|
|
|
630
559
|
method: request.method,
|
|
631
560
|
headers: request.headers,
|
|
632
561
|
body: request.body,
|
|
633
|
-
secret_alias: request.secret_alias,
|
|
634
562
|
secret_id: secret_id,
|
|
635
563
|
},
|
|
636
564
|
execution: { status: DispatchStatus.IN_PROGRESS },
|
|
@@ -658,83 +586,24 @@ export class VaultCore {
|
|
|
658
586
|
};
|
|
659
587
|
await this._deps.requests.save(record);
|
|
660
588
|
}
|
|
661
|
-
|
|
662
|
-
return
|
|
663
|
-
request_id: record.request_id,
|
|
664
|
-
created_at: record.created_at,
|
|
665
|
-
reason: record.reason,
|
|
666
|
-
target_url: record.request.target_url,
|
|
667
|
-
execution_status: record.execution.status,
|
|
668
|
-
response_status: record.response?.status,
|
|
669
|
-
error: record.response?.error,
|
|
670
|
-
has_response_body: !!record.response?.body,
|
|
671
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
toOwnerVisibleRequestRecord(record) {
|
|
675
|
-
return {
|
|
676
|
-
request_id: record.request_id,
|
|
677
|
-
created_at: record.created_at,
|
|
678
|
-
root_agent_id: record.root_agent_id,
|
|
679
|
-
reason: record.reason,
|
|
680
|
-
target_url: record.request.target_url,
|
|
681
|
-
execution_status: record.execution.status,
|
|
682
|
-
response_status: record.response?.status,
|
|
683
|
-
error: record.response?.error,
|
|
684
|
-
has_response_body: !!record.response?.body,
|
|
685
|
-
missing_grants: record.missing_grants,
|
|
686
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
687
|
-
};
|
|
589
|
+
toAgentRequestRecord(record) {
|
|
590
|
+
return record;
|
|
688
591
|
}
|
|
689
592
|
toOwnerRequestRecord(record) {
|
|
690
|
-
return
|
|
691
|
-
request_id: record.request_id,
|
|
692
|
-
created_at: record.created_at,
|
|
693
|
-
requested_at: record.requested_at,
|
|
694
|
-
root_agent_id: record.root_agent_id,
|
|
695
|
-
reason: record.reason,
|
|
696
|
-
request: {
|
|
697
|
-
target_url: record.request.target_url,
|
|
698
|
-
method: record.request.method,
|
|
699
|
-
headers: record.request.headers,
|
|
700
|
-
body: record.request.body,
|
|
701
|
-
secret_alias: record.request.secret_alias,
|
|
702
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
703
|
-
},
|
|
704
|
-
response: record.response ? {
|
|
705
|
-
status: record.response.status,
|
|
706
|
-
headers: record.response.headers,
|
|
707
|
-
body: record.response.body,
|
|
708
|
-
error: record.response.error,
|
|
709
|
-
} : undefined,
|
|
710
|
-
execution_status: record.execution.status,
|
|
711
|
-
missing_grants: record.missing_grants,
|
|
712
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
713
|
-
};
|
|
593
|
+
return record;
|
|
714
594
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
body: record.request.body,
|
|
726
|
-
secret_alias: record.request.secret_alias,
|
|
727
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
728
|
-
},
|
|
729
|
-
response: record.response ? {
|
|
730
|
-
status: record.response.status,
|
|
731
|
-
headers: record.response.headers,
|
|
732
|
-
body: record.response.body,
|
|
733
|
-
error: record.response.error,
|
|
734
|
-
} : undefined,
|
|
735
|
-
execution_status: record.execution.status,
|
|
736
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
595
|
+
async _appendAuditEntry(actor, functionName, input, output, error) {
|
|
596
|
+
const entry = {
|
|
597
|
+
event_id: this._deps.ids.newAuditEntryId(),
|
|
598
|
+
ts: this._deps.clock.nowIso(),
|
|
599
|
+
vault_id: this._deps.vault_id,
|
|
600
|
+
actor,
|
|
601
|
+
function_name: functionName,
|
|
602
|
+
input,
|
|
603
|
+
output,
|
|
604
|
+
error,
|
|
737
605
|
};
|
|
606
|
+
await this._appendAudit(entry);
|
|
738
607
|
}
|
|
739
608
|
}
|
|
740
609
|
export function createVaultCore(deps) {
|