@the-ai-company/cbio-node-runtime 1.72.0 → 1.74.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 +7 -6
- package/dist/clients/agent/client.js +32 -16
- package/dist/clients/agent/client.js.map +1 -1
- package/dist/clients/agent/contracts.d.ts +9 -4
- package/dist/clients/agent/index.d.ts +1 -1
- package/dist/clients/owner/client.js +19 -19
- package/dist/clients/owner/client.js.map +1 -1
- package/dist/clients/owner/contracts.d.ts +2 -2
- package/dist/public-types.d.ts +3 -3
- package/dist/public-types.js +1 -1
- package/dist/public-types.js.map +1 -1
- package/dist/runtime/bootstrap.js +30 -14
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/index.d.ts +3 -3
- 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 +30 -142
- package/dist/vault-core/contracts.js +0 -20
- package/dist/vault-core/contracts.js.map +1 -1
- package/dist/vault-core/core.d.ts +17 -9
- package/dist/vault-core/core.js +85 -225
- 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 -85
- 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 +3 -2
- package/dist/vault-ingress/defaults.js +6 -3
- package/dist/vault-ingress/defaults.js.map +1 -1
- package/dist/vault-ingress/index.d.ts +14 -5
- package/dist/vault-ingress/index.js +23 -29
- package/dist/vault-ingress/index.js.map +1 -1
- package/dist/vault-ingress/remote-transport.d.ts +3 -2
- package/dist/vault-ingress/remote-transport.js +19 -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 +6 -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 +55 -21
- 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/AgentAuditTestPingInput.md +17 -0
- package/docs/api/interfaces/AgentClient.md +23 -5
- package/docs/api/interfaces/AgentDispatchIntent.md +1 -1
- package/docs/api/interfaces/AgentDispatchTransport.md +21 -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 +5 -5
- 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 +1 -1
- 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 +28 -12
- 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 -107
- 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);
|
|
@@ -165,6 +131,13 @@ export class VaultCore {
|
|
|
165
131
|
const authorization = await this.agentAuthorizeDispatch(request);
|
|
166
132
|
const secret_id = authorization.secret_id;
|
|
167
133
|
await this._recordRequestInternal(request, DispatchStatus.IN_PROGRESS, secret_id);
|
|
134
|
+
await this._appendAuditEntry(request.agent, "agentDispatchSecret", { request_id: request.request_id, root_agent_id: request.agent.id, target: request.target_url, secret_id }, {
|
|
135
|
+
vault_id: this._deps.vault_id,
|
|
136
|
+
request_id: request.request_id,
|
|
137
|
+
status: DispatchStatus.IN_PROGRESS,
|
|
138
|
+
target_url: request.target_url,
|
|
139
|
+
method: request.method,
|
|
140
|
+
});
|
|
168
141
|
if (authorization.decision === "deny") {
|
|
169
142
|
const result = {
|
|
170
143
|
vault_id: this._deps.vault_id,
|
|
@@ -174,13 +147,7 @@ export class VaultCore {
|
|
|
174
147
|
method: request.method,
|
|
175
148
|
error: authorization.reason ?? "denied",
|
|
176
149
|
};
|
|
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
|
-
}));
|
|
150
|
+
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
151
|
await this._updateRequestRecordInternal(request, result, secret_id);
|
|
185
152
|
return result;
|
|
186
153
|
}
|
|
@@ -193,13 +160,7 @@ export class VaultCore {
|
|
|
193
160
|
method: request.method,
|
|
194
161
|
};
|
|
195
162
|
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
|
-
}));
|
|
163
|
+
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
164
|
return result;
|
|
204
165
|
}
|
|
205
166
|
// Proceed with dispatch
|
|
@@ -223,13 +184,7 @@ export class VaultCore {
|
|
|
223
184
|
headers: request.headers,
|
|
224
185
|
body: request.body,
|
|
225
186
|
}, { 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
|
-
}));
|
|
187
|
+
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
188
|
await this._updateRequestRecordInternal(request, result, secret_id);
|
|
234
189
|
return {
|
|
235
190
|
...result,
|
|
@@ -253,19 +208,14 @@ export class VaultCore {
|
|
|
253
208
|
execution: { status: DispatchStatus.DENIED },
|
|
254
209
|
};
|
|
255
210
|
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
|
-
}));
|
|
211
|
+
await this._appendAuditEntry(actor, "ownerApproveDispatch", { request_id, decision, root_agent_id: record.root_agent_id, secret_id: record.request.secret_id }, updated);
|
|
262
212
|
return null;
|
|
263
213
|
}
|
|
264
|
-
const
|
|
265
|
-
if (!
|
|
266
|
-
throw new VaultCoreError("record missing
|
|
214
|
+
const secret_id = record.request.secret_id;
|
|
215
|
+
if (!secret_id) {
|
|
216
|
+
throw new VaultCoreError("record missing secret_id", "VAULT_INTERNAL_ERROR");
|
|
267
217
|
}
|
|
268
|
-
const secret = await this._deps.secrets.
|
|
218
|
+
const secret = await this._deps.secrets.getById(secret_id);
|
|
269
219
|
if (!secret) {
|
|
270
220
|
throw new VaultCoreError("secret not found during approval", "VAULT_SECRET_NOT_FOUND");
|
|
271
221
|
}
|
|
@@ -291,18 +241,7 @@ export class VaultCore {
|
|
|
291
241
|
granted_at: now,
|
|
292
242
|
}),
|
|
293
243
|
]);
|
|
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
|
-
}));
|
|
244
|
+
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
245
|
}
|
|
307
246
|
// Execute
|
|
308
247
|
const plaintext = await this._deps.custody.load(secret.secret_id);
|
|
@@ -329,19 +268,13 @@ export class VaultCore {
|
|
|
329
268
|
execution: { status: result.status },
|
|
330
269
|
};
|
|
331
270
|
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"), {
|
|
271
|
+
await this._appendAuditEntry(actor, "ownerApproveDispatch", { request_id, decision, root_agent_id: record.root_agent_id, secret_id: record.request.secret_id }, result);
|
|
272
|
+
await this._appendAuditEntry({ kind: "agent", id: record.root_agent_id }, "agentDispatchSecret", {
|
|
339
273
|
request_id,
|
|
340
274
|
root_agent_id: record.root_agent_id,
|
|
341
275
|
target: { kind: "http", url: record.request.target_url },
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}));
|
|
276
|
+
secret_id: secret.secret_id,
|
|
277
|
+
}, result);
|
|
345
278
|
return result;
|
|
346
279
|
}
|
|
347
280
|
// ─── Agent Control APIs ───────────────────────────────────────────────────────
|
|
@@ -355,11 +288,11 @@ export class VaultCore {
|
|
|
355
288
|
this._deps.agent_secretGrants.list(this._deps.vault_id, command.agent.id),
|
|
356
289
|
this._deps.secret_destinationGrants.list(this._deps.vault_id),
|
|
357
290
|
]);
|
|
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
|
|
291
|
+
const secret_ids = new Set(agent_secrets.map(g => g.secret_id));
|
|
292
|
+
const relevantDestinations = secret_destinations.filter(d => secret_ids.has(d.secret_id));
|
|
360
293
|
return {
|
|
361
294
|
root_agent_id: command.agent.id,
|
|
362
|
-
vault_id: this._deps.vault_id
|
|
295
|
+
vault_id: this._deps.vault_id,
|
|
363
296
|
issued_at: this._deps.clock.nowIso(),
|
|
364
297
|
agent: {
|
|
365
298
|
root_agent_id: agentRecord.root_agent_id,
|
|
@@ -378,7 +311,7 @@ export class VaultCore {
|
|
|
378
311
|
await this._verifyAgentControlProof(command, "list_secrets");
|
|
379
312
|
const records = await this._deps.secrets.list(this._deps.vault_id);
|
|
380
313
|
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
|
|
314
|
+
const approvedSecretIds = new Set(grants.filter(g => g.status === "approved").map(g => g.secret_id));
|
|
382
315
|
return records.map(record => ({
|
|
383
316
|
vault_id: record.vault_id,
|
|
384
317
|
secret_id: record.secret_id,
|
|
@@ -389,13 +322,13 @@ export class VaultCore {
|
|
|
389
322
|
source: record.source,
|
|
390
323
|
created_at: record.created_at,
|
|
391
324
|
updated_at: record.updated_at,
|
|
392
|
-
granted: approvedSecretIds.has(record.secret_id
|
|
325
|
+
granted: approvedSecretIds.has(record.secret_id),
|
|
393
326
|
}));
|
|
394
327
|
}
|
|
395
328
|
async agentListRequests(command) {
|
|
396
329
|
await this._verifyAgentControlProof(command, "list_requests");
|
|
397
330
|
const records = await this._deps.requests.list(this._deps.vault_id, command.agent.id);
|
|
398
|
-
return records.map(r => this.
|
|
331
|
+
return records.map(r => this.toAgentRequestRecord(r));
|
|
399
332
|
}
|
|
400
333
|
async agentGetRequest(command) {
|
|
401
334
|
await this._verifyAgentControlProof(command, "read_request");
|
|
@@ -403,27 +336,21 @@ export class VaultCore {
|
|
|
403
336
|
if (!record || record.root_agent_id !== command.agent.id) {
|
|
404
337
|
throw new VaultCoreError("request record not found", "VAULT_READ_DENIED");
|
|
405
338
|
}
|
|
406
|
-
return
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
body: record.request.body,
|
|
416
|
-
secret_alias: record.request.secret_alias,
|
|
417
|
-
},
|
|
418
|
-
response: record.response,
|
|
419
|
-
execution_status: record.execution.status,
|
|
420
|
-
};
|
|
339
|
+
return this.toAgentRequestRecord(record);
|
|
340
|
+
}
|
|
341
|
+
async agentAuditTestPing(command) {
|
|
342
|
+
await this._verifyAgentControlProof(command, "agentAuditTestPing");
|
|
343
|
+
return this._appendAuditEntry(command.agent, "agentAuditTestPing", {
|
|
344
|
+
request_id: command.request_id,
|
|
345
|
+
root_agent_id: command.agent.id,
|
|
346
|
+
label: command.label ?? null,
|
|
347
|
+
}, { ok: true });
|
|
421
348
|
}
|
|
422
349
|
// ─── Owner Management APIs ────────────────────────────────────────────────────
|
|
423
350
|
async ownerRegisterAgentIdentity(command) {
|
|
424
351
|
this._assertOwnerPrincipal(command.owner);
|
|
425
352
|
await this._deps.agentRecords.register(command.agentRecord);
|
|
426
|
-
await this.
|
|
353
|
+
await this._appendAuditEntry(command.owner, "ownerRegisterAgentIdentity", { root_agent_id: command.agentRecord.root_agent_id }, undefined);
|
|
427
354
|
}
|
|
428
355
|
async ownerUpdateAgentIdentity(command) {
|
|
429
356
|
this._assertOwnerPrincipal(command.owner);
|
|
@@ -432,13 +359,13 @@ export class VaultCore {
|
|
|
432
359
|
throw new VaultCoreError("agent identity not found", "VAULT_IDENTITY_NOT_FOUND");
|
|
433
360
|
const updated = { ...existing, nickname: command.nickname ?? existing.nickname, metadata: command.metadata ?? existing.metadata };
|
|
434
361
|
await this._deps.agentRecords.register(updated);
|
|
435
|
-
await this.
|
|
362
|
+
await this._appendAuditEntry(command.owner, "ownerUpdateAgentIdentity", { root_agent_id: command.root_agent_id }, updated);
|
|
436
363
|
return updated;
|
|
437
364
|
}
|
|
438
365
|
async ownerCreateSecret(command) {
|
|
439
366
|
this._assertOwnerPrincipal(command.owner);
|
|
440
367
|
await this._deps.policy.authorizeWrite(command);
|
|
441
|
-
const existing = await this._deps.secrets.getByAlias(
|
|
368
|
+
const existing = await this._deps.secrets.getByAlias(command.alias);
|
|
442
369
|
if (existing) {
|
|
443
370
|
throw new VaultCoreError(`secret alias already exists: "${command.alias}"`, "VAULT_ALIAS_ALREADY_EXISTS");
|
|
444
371
|
}
|
|
@@ -447,7 +374,7 @@ export class VaultCore {
|
|
|
447
374
|
const record = {
|
|
448
375
|
vault_id: command.vault_id,
|
|
449
376
|
secret_id,
|
|
450
|
-
alias:
|
|
377
|
+
alias: command.alias,
|
|
451
378
|
version: this._deps.ids.newVersion(),
|
|
452
379
|
lifecycle_status: "ACTIVE",
|
|
453
380
|
issuer_id: null,
|
|
@@ -457,19 +384,19 @@ export class VaultCore {
|
|
|
457
384
|
};
|
|
458
385
|
await this._deps.secrets.save(record);
|
|
459
386
|
await this._deps.custody.store(secret_id, command.plaintext);
|
|
460
|
-
await this.
|
|
387
|
+
await this._appendAuditEntry(command.owner, "ownerCreateSecret", { secret_alias: command.alias, secret_id }, record);
|
|
461
388
|
return record;
|
|
462
389
|
}
|
|
463
390
|
async ownerUpdateSecret(command) {
|
|
464
391
|
this._assertOwnerPrincipal(command.owner);
|
|
465
392
|
await this._deps.policy.authorizeWrite(command);
|
|
466
|
-
const existing = await this._deps.secrets.getByAlias(
|
|
393
|
+
const existing = await this._deps.secrets.getByAlias(command.alias);
|
|
467
394
|
if (!existing)
|
|
468
395
|
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
469
396
|
const finalAlias = command.new_alias && command.new_alias !== command.alias ? command.new_alias : command.alias;
|
|
470
397
|
const isRename = finalAlias !== command.alias;
|
|
471
398
|
if (isRename) {
|
|
472
|
-
const duplicate = await this._deps.secrets.getByAlias(
|
|
399
|
+
const duplicate = await this._deps.secrets.getByAlias(finalAlias);
|
|
473
400
|
if (duplicate) {
|
|
474
401
|
throw new VaultCoreError(`secret alias already exists: "${finalAlias}"`, "VAULT_ALIAS_ALREADY_EXISTS");
|
|
475
402
|
}
|
|
@@ -478,27 +405,24 @@ export class VaultCore {
|
|
|
478
405
|
const now = this._deps.clock.nowIso();
|
|
479
406
|
const record = {
|
|
480
407
|
...existing,
|
|
481
|
-
alias:
|
|
408
|
+
alias: finalAlias,
|
|
482
409
|
version: this._deps.ids.newVersion(),
|
|
483
410
|
updated_at: now,
|
|
484
411
|
};
|
|
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
412
|
if (command.plaintext !== undefined) {
|
|
489
413
|
await this._deps.custody.store(secret_id, command.plaintext);
|
|
490
414
|
}
|
|
491
|
-
await this.
|
|
415
|
+
await this._deps.secrets.save(record);
|
|
416
|
+
await this._appendAuditEntry(command.owner, "ownerUpdateSecret", { secret_alias: finalAlias, secret_id }, record);
|
|
492
417
|
return record;
|
|
493
418
|
}
|
|
494
419
|
async ownerRemoveSecret(command) {
|
|
495
420
|
this._assertOwnerPrincipal(command.owner);
|
|
496
|
-
const record = await this._deps.secrets.getByAlias(
|
|
421
|
+
const record = await this._deps.secrets.getByAlias(command.alias);
|
|
497
422
|
if (!record)
|
|
498
423
|
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
499
424
|
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 }));
|
|
425
|
+
await this._appendAuditEntry(command.owner, "ownerRemoveSecret", { secret_alias: command.alias, secret_id: record.secret_id }, undefined);
|
|
502
426
|
}
|
|
503
427
|
async ownerReadAudit(actor, query) {
|
|
504
428
|
this._assertOwnerPrincipal(actor);
|
|
@@ -507,21 +431,16 @@ export class VaultCore {
|
|
|
507
431
|
async ownerExportSecret(actor, alias) {
|
|
508
432
|
this._assertOwnerPrincipal(actor);
|
|
509
433
|
if (alias) {
|
|
510
|
-
const record = await this._deps.secrets.getByAlias(
|
|
434
|
+
const record = await this._deps.secrets.getByAlias(alias);
|
|
511
435
|
if (!record)
|
|
512
436
|
throw new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
513
437
|
const plaintext = await this._deps.custody.load(record.secret_id);
|
|
514
|
-
|
|
515
|
-
throw new VaultCoreError("secret material not found", "VAULT_SECRET_NOT_FOUND");
|
|
516
|
-
await this._appendAudit(toAuditEntry(this._deps, actor, AuditOperation.SECRET_EXPORT, "allowed", "succeeded", `secret exported as plaintext: "${alias}"`, {
|
|
517
|
-
secret_alias: alias,
|
|
518
|
-
secret_id: record.secret_id.value
|
|
519
|
-
}));
|
|
438
|
+
await this._appendAuditEntry(actor, "ownerExportSecret", { secret_alias: alias, secret_id: record.secret_id }, undefined);
|
|
520
439
|
return [{
|
|
521
440
|
vault_id: this._deps.vault_id,
|
|
522
441
|
secret_id: record.secret_id,
|
|
523
442
|
alias: record.alias,
|
|
524
|
-
plaintext,
|
|
443
|
+
plaintext: plaintext ?? "MISSING",
|
|
525
444
|
exported_at: this._deps.clock.nowIso()
|
|
526
445
|
}];
|
|
527
446
|
}
|
|
@@ -537,7 +456,7 @@ export class VaultCore {
|
|
|
537
456
|
exported_at: this._deps.clock.nowIso()
|
|
538
457
|
};
|
|
539
458
|
}));
|
|
540
|
-
await this.
|
|
459
|
+
await this._appendAuditEntry(actor, "ownerExportSecret_batch", {}, undefined);
|
|
541
460
|
return exports;
|
|
542
461
|
}
|
|
543
462
|
async ownerListAgents(actor) {
|
|
@@ -553,7 +472,7 @@ export class VaultCore {
|
|
|
553
472
|
async ownerListRequests(actor, root_agent_id) {
|
|
554
473
|
this._assertOwnerPrincipal(actor);
|
|
555
474
|
const records = await this._deps.requests.list(this._deps.vault_id, root_agent_id);
|
|
556
|
-
return records.map(r => this.
|
|
475
|
+
return records.map(r => this.toOwnerRequestRecord(r));
|
|
557
476
|
}
|
|
558
477
|
async ownerGetRequest(actor, request_id) {
|
|
559
478
|
this._assertOwnerPrincipal(actor);
|
|
@@ -581,7 +500,7 @@ export class VaultCore {
|
|
|
581
500
|
async ownerIssueSessionToken(request) {
|
|
582
501
|
this._assertOwnerPrincipal(request.actor);
|
|
583
502
|
const token = await this._deps.sessionTokenRegistry.issue(request.root_agent_id);
|
|
584
|
-
await this.
|
|
503
|
+
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() });
|
|
585
504
|
return { token, root_agent_id: request.root_agent_id, issued_at: this._deps.clock.nowIso() };
|
|
586
505
|
}
|
|
587
506
|
async ownerIssueAllAgentSessionTokens(actor) {
|
|
@@ -592,15 +511,16 @@ export class VaultCore {
|
|
|
592
511
|
async ownerRevokeSessionToken(request) {
|
|
593
512
|
this._assertOwnerPrincipal(request.actor);
|
|
594
513
|
await this._deps.sessionTokenRegistry.revoke(request.token);
|
|
595
|
-
await this.
|
|
514
|
+
await this._appendAuditEntry(request.actor, "ownerRevokeSessionToken", { token: request.token }, undefined);
|
|
596
515
|
}
|
|
597
516
|
ownerOnPendingDispatch(subscription) {
|
|
598
517
|
return this._deps.audit.subscribe(this._deps.vault_id, {
|
|
599
|
-
|
|
518
|
+
function_names: ["agentDispatchSecret"],
|
|
600
519
|
onEvent: async (entry) => {
|
|
601
|
-
|
|
520
|
+
const request_id = entry.input?.request_id;
|
|
521
|
+
if (!request_id)
|
|
602
522
|
return;
|
|
603
|
-
const record = await this._deps.requests.get(this._deps.vault_id,
|
|
523
|
+
const record = await this._deps.requests.get(this._deps.vault_id, request_id);
|
|
604
524
|
if (!record || record.execution.status !== DispatchStatus.AWAITING_APPROVAL)
|
|
605
525
|
return;
|
|
606
526
|
const pendingEventId = record.pending_dispatch_event?.event_id ?? entry.event_id;
|
|
@@ -631,7 +551,6 @@ export class VaultCore {
|
|
|
631
551
|
method: request.method,
|
|
632
552
|
headers: request.headers,
|
|
633
553
|
body: request.body,
|
|
634
|
-
secret_alias: request.secret_alias,
|
|
635
554
|
secret_id,
|
|
636
555
|
},
|
|
637
556
|
execution: { status },
|
|
@@ -655,7 +574,6 @@ export class VaultCore {
|
|
|
655
574
|
method: request.method,
|
|
656
575
|
headers: request.headers,
|
|
657
576
|
body: request.body,
|
|
658
|
-
secret_alias: request.secret_alias,
|
|
659
577
|
secret_id: secret_id,
|
|
660
578
|
},
|
|
661
579
|
execution: { status: DispatchStatus.IN_PROGRESS },
|
|
@@ -683,83 +601,25 @@ export class VaultCore {
|
|
|
683
601
|
};
|
|
684
602
|
await this._deps.requests.save(record);
|
|
685
603
|
}
|
|
686
|
-
|
|
687
|
-
return
|
|
688
|
-
request_id: record.request_id,
|
|
689
|
-
created_at: record.created_at,
|
|
690
|
-
reason: record.reason,
|
|
691
|
-
target_url: record.request.target_url,
|
|
692
|
-
execution_status: record.execution.status,
|
|
693
|
-
response_status: record.response?.status,
|
|
694
|
-
error: record.response?.error,
|
|
695
|
-
has_response_body: !!record.response?.body,
|
|
696
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
toOwnerVisibleRequestRecord(record) {
|
|
700
|
-
return {
|
|
701
|
-
request_id: record.request_id,
|
|
702
|
-
created_at: record.created_at,
|
|
703
|
-
root_agent_id: record.root_agent_id,
|
|
704
|
-
reason: record.reason,
|
|
705
|
-
target_url: record.request.target_url,
|
|
706
|
-
execution_status: record.execution.status,
|
|
707
|
-
response_status: record.response?.status,
|
|
708
|
-
error: record.response?.error,
|
|
709
|
-
has_response_body: !!record.response?.body,
|
|
710
|
-
missing_grants: record.missing_grants,
|
|
711
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
712
|
-
};
|
|
604
|
+
toAgentRequestRecord(record) {
|
|
605
|
+
return record;
|
|
713
606
|
}
|
|
714
607
|
toOwnerRequestRecord(record) {
|
|
715
|
-
return
|
|
716
|
-
request_id: record.request_id,
|
|
717
|
-
created_at: record.created_at,
|
|
718
|
-
requested_at: record.requested_at,
|
|
719
|
-
root_agent_id: record.root_agent_id,
|
|
720
|
-
reason: record.reason,
|
|
721
|
-
request: {
|
|
722
|
-
target_url: record.request.target_url,
|
|
723
|
-
method: record.request.method,
|
|
724
|
-
headers: record.request.headers,
|
|
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
|
-
missing_grants: record.missing_grants,
|
|
737
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
738
|
-
};
|
|
608
|
+
return record;
|
|
739
609
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
body: record.request.body,
|
|
751
|
-
secret_alias: record.request.secret_alias,
|
|
752
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
753
|
-
},
|
|
754
|
-
response: record.response ? {
|
|
755
|
-
status: record.response.status,
|
|
756
|
-
headers: record.response.headers,
|
|
757
|
-
body: record.response.body,
|
|
758
|
-
error: record.response.error,
|
|
759
|
-
} : undefined,
|
|
760
|
-
execution_status: record.execution.status,
|
|
761
|
-
secret_id: record.request.secret_id ?? undefined,
|
|
610
|
+
async _appendAuditEntry(actor, functionName, input, output, error) {
|
|
611
|
+
const entry = {
|
|
612
|
+
event_id: this._deps.ids.newAuditEntryId(),
|
|
613
|
+
ts: this._deps.clock.nowIso(),
|
|
614
|
+
vault_id: this._deps.vault_id,
|
|
615
|
+
actor,
|
|
616
|
+
function_name: functionName,
|
|
617
|
+
input,
|
|
618
|
+
output,
|
|
619
|
+
error,
|
|
762
620
|
};
|
|
621
|
+
await this._appendAudit(entry);
|
|
622
|
+
return entry;
|
|
763
623
|
}
|
|
764
624
|
}
|
|
765
625
|
export function createVaultCore(deps) {
|