@the-ai-company/cbio-node-runtime 1.56.0 → 1.58.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 +27 -28
- package/dist/clients/agent/client.d.ts +2 -2
- package/dist/clients/agent/contracts.d.ts +3 -2
- package/dist/clients/owner/client.d.ts +8 -15
- package/dist/clients/owner/client.js +18 -51
- package/dist/clients/owner/client.js.map +1 -1
- package/dist/clients/owner/contracts.d.ts +11 -23
- package/dist/clients/owner/index.d.ts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/vault-core/contracts.d.ts +61 -57
- package/dist/vault-core/contracts.js +0 -1
- package/dist/vault-core/contracts.js.map +1 -1
- package/dist/vault-core/core.d.ts +15 -22
- package/dist/vault-core/core.js +222 -211
- package/dist/vault-core/core.js.map +1 -1
- package/dist/vault-core/defaults.d.ts +8 -22
- package/dist/vault-core/defaults.js +18 -97
- package/dist/vault-core/defaults.js.map +1 -1
- package/dist/vault-core/index.d.ts +3 -3
- package/dist/vault-core/index.js +1 -1
- package/dist/vault-core/index.js.map +1 -1
- package/dist/vault-core/persistence.d.ts +8 -6
- package/dist/vault-core/persistence.js +16 -8
- package/dist/vault-core/persistence.js.map +1 -1
- package/dist/vault-core/ports.d.ts +8 -21
- package/dist/vault-ingress/defaults.d.ts +2 -2
- package/dist/vault-ingress/index.d.ts +14 -34
- package/dist/vault-ingress/index.js +20 -42
- 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.map +1 -1
- package/docs/MIGRATION-1.51.md +1 -1
- package/docs/REFERENCE.md +26 -28
- package/docs/api/README.md +2 -4
- package/docs/api/classes/IdentityError.md +1 -1
- package/docs/api/classes/OwnerClientError.md +1 -1
- package/docs/api/classes/VaultCore.md +29 -105
- package/docs/api/classes/VaultCoreError.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 -1
- package/docs/api/functions/createIdentity.md +1 -1
- package/docs/api/functions/createOwnerHttpFlowBoundary.md +1 -1
- package/docs/api/functions/createOwnerSession.md +1 -1
- package/docs/api/functions/createPersistentVaultCoreDependencies.md +1 -1
- package/docs/api/functions/createStandardAcquireBoundary.md +1 -1
- package/docs/api/functions/createStandardDispatchBoundary.md +1 -1
- package/docs/api/functions/createVault.md +1 -1
- package/docs/api/functions/createVaultClient.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/deriveIdentityId.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/handleVaultHttpDispatch.md +1 -1
- package/docs/api/functions/initializeVaultCustody.md +1 -1
- package/docs/api/functions/listVaults.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/wrapVaultCoreAsVaultService.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/AgentSigner.md +1 -1
- package/docs/api/interfaces/AgentSubmitCapabilityRequestInput.md +1 -1
- package/docs/api/interfaces/CbioRuntime.md +1 -1
- package/docs/api/interfaces/CreateAgentClientOptions.md +1 -1
- package/docs/api/interfaces/CreateIdentityOptions.md +1 -1
- package/docs/api/interfaces/CreateOwnerSessionOptions.md +1 -1
- package/docs/api/interfaces/CreatePersistentVaultCoreDependenciesOptions.md +1 -1
- package/docs/api/interfaces/CreateVaultClientOptions.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/IStorageProvider.md +1 -1
- package/docs/api/interfaces/InitializeVaultCustodyOptions.md +1 -1
- package/docs/api/interfaces/InitializedVaultCustody.md +1 -1
- package/docs/api/interfaces/OwnerAgentProvisionResult.md +1 -1
- 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/OwnerStoreSecretInput.md +1 -1
- package/docs/api/interfaces/OwnerWriteSecretInput.md +1 -7
- package/docs/api/interfaces/RecoverVaultOptions.md +1 -1
- package/docs/api/interfaces/RecoveredVault.md +1 -1
- package/docs/api/interfaces/RestoreIdentityOptions.md +1 -1
- package/docs/api/interfaces/Signer.md +1 -1
- package/docs/api/interfaces/VaultApproveCapabilityRequestInput.md +1 -1
- package/docs/api/interfaces/VaultApproveDispatchInput.md +1 -1
- package/docs/api/interfaces/VaultAuditQueryInput.md +1 -1
- package/docs/api/interfaces/VaultClient.md +34 -88
- package/docs/api/interfaces/VaultCoreDependenciesOptions.md +1 -1
- package/docs/api/interfaces/VaultCreateAgentInput.md +1 -1
- package/docs/api/interfaces/VaultDeleteSecretInput.md +1 -1
- package/docs/api/interfaces/VaultExportSecretInput.md +1 -1
- package/docs/api/interfaces/VaultGrantCapabilityInput.md +1 -1
- package/docs/api/interfaces/VaultGrantCapabilityRequest.md +1 -1
- package/docs/api/interfaces/VaultIdentity.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/VaultListCapabilitiesInput.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/VaultProfile.md +1 -1
- package/docs/api/interfaces/VaultReadAgentPrivateKeyInput.md +1 -1
- package/docs/api/interfaces/VaultReadSecretPlaintextInput.md +1 -1
- package/docs/api/interfaces/VaultRegisterFlowInput.md +1 -1
- package/docs/api/interfaces/VaultRevokeCapabilityInput.md +1 -1
- package/docs/api/interfaces/VaultRevokeSessionTokenInput.md +1 -1
- package/docs/api/interfaces/VaultSigner.md +1 -1
- package/docs/api/interfaces/VaultSubmitCapabilityRequestInput.md +1 -1
- package/docs/api/interfaces/VaultUpdateAgentInput.md +1 -1
- package/docs/api/type-aliases/AgentCapabilityEnvelope.md +1 -1
- package/docs/api/type-aliases/AgentVisibleSecretRecord.md +1 -1
- package/docs/api/type-aliases/CbioRuntimeModule.md +1 -1
- package/docs/api/type-aliases/OwnerGrantCapabilityInput.md +1 -1
- package/docs/api/variables/DEFAULT_VAULT_KEY_CUSTODY_BLOB_KEY.md +1 -1
- package/docs/zh/README.md +20 -14
- package/examples/process-isolation.ts +1 -1
- package/package.json +1 -1
- package/docs/api/interfaces/OwnerDefineSecretTargetsInput.md +0 -23
- package/docs/api/interfaces/OwnerSecretTargetBinding.md +0 -35
package/dist/vault-core/core.js
CHANGED
|
@@ -23,15 +23,16 @@ function toAuditEntry(deps, actor, action, outcome, detail, options) {
|
|
|
23
23
|
}
|
|
24
24
|
function buildSecretRecord(deps, command) {
|
|
25
25
|
const now = deps.clock.nowIso();
|
|
26
|
+
const source = command.source?.kind === "request" && command.source.requestId
|
|
27
|
+
? { kind: "request", requestId: command.source.requestId }
|
|
28
|
+
: { kind: "manual" };
|
|
26
29
|
return {
|
|
27
30
|
vaultId: deps.vaultId,
|
|
28
31
|
secretId: deps.ids.newSecretId(),
|
|
29
32
|
alias: { value: command.alias },
|
|
30
33
|
version: deps.ids.newVersion(),
|
|
31
34
|
issuerId: command.kind === "issuer.write_secret" ? command.issuerSiteId : null,
|
|
32
|
-
|
|
33
|
-
? [...(command.targetBindings ?? [{ kind: "site", targetId: command.issuerSiteId }])]
|
|
34
|
-
: [...(command.targetBindings ?? [])],
|
|
35
|
+
source,
|
|
35
36
|
createdAt: now,
|
|
36
37
|
updatedAt: now,
|
|
37
38
|
};
|
|
@@ -83,8 +84,7 @@ function createAgentControlBinding(requestId, requestedAt, agentId, action, payl
|
|
|
83
84
|
*/
|
|
84
85
|
export class VaultCore {
|
|
85
86
|
_deps;
|
|
86
|
-
|
|
87
|
-
_pendingCapabilityObservers = new Set();
|
|
87
|
+
_capabilityStateObservers = new Set();
|
|
88
88
|
constructor(_deps) {
|
|
89
89
|
this._deps = _deps;
|
|
90
90
|
}
|
|
@@ -93,6 +93,128 @@ export class VaultCore {
|
|
|
93
93
|
throw new VaultCoreError("owner access denied", code);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
+
_stateToGrantedCapability(state) {
|
|
97
|
+
return {
|
|
98
|
+
vaultId: state.vaultId,
|
|
99
|
+
capabilityId: state.capabilityId ?? "",
|
|
100
|
+
agentId: state.agentId,
|
|
101
|
+
secretIds: state.secretIds ? [...state.secretIds] : undefined,
|
|
102
|
+
secretAliases: state.secretAliases ? [...state.secretAliases] : undefined,
|
|
103
|
+
operation: state.operation,
|
|
104
|
+
customFlowId: state.customFlowId,
|
|
105
|
+
scope: state.scope,
|
|
106
|
+
methods: [...state.methods],
|
|
107
|
+
issuedAt: state.issuedAt ?? state.requestedAt,
|
|
108
|
+
expiresAt: state.expiresAt,
|
|
109
|
+
rateLimit: state.rateLimit,
|
|
110
|
+
skipAudit: state.skipAudit,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async _buildAgentCapabilityStates(agentId) {
|
|
114
|
+
return (await this._deps.capabilityStates.list(this._deps.vaultId, agentId)).map((state) => ({
|
|
115
|
+
status: state.status,
|
|
116
|
+
source: state.source,
|
|
117
|
+
agentId: state.agentId,
|
|
118
|
+
requestId: state.requestId,
|
|
119
|
+
capabilityId: state.capabilityId,
|
|
120
|
+
operation: state.operation,
|
|
121
|
+
secretIds: state.secretIds ? [...state.secretIds] : undefined,
|
|
122
|
+
secretAliases: state.secretAliases ? [...state.secretAliases] : undefined,
|
|
123
|
+
customFlowId: state.customFlowId,
|
|
124
|
+
scope: state.scope,
|
|
125
|
+
methods: [...state.methods],
|
|
126
|
+
issuedAt: state.issuedAt,
|
|
127
|
+
requestedAt: state.requestedAt,
|
|
128
|
+
expiresAt: state.expiresAt,
|
|
129
|
+
rateLimit: state.rateLimit,
|
|
130
|
+
skipAudit: state.skipAudit,
|
|
131
|
+
justification: state.justification,
|
|
132
|
+
secretAlias: state.secretAlias,
|
|
133
|
+
targetUrl: state.targetUrl,
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
_isExecutablePendingState(state) {
|
|
137
|
+
return !!(state.requestId && state.targetUrl && state.secretAlias && state.proof);
|
|
138
|
+
}
|
|
139
|
+
async _executePendingCapabilityState(command, mode) {
|
|
140
|
+
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
141
|
+
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
142
|
+
}
|
|
143
|
+
const pending = await this._deps.capabilityStates.getByRequestId(command.vaultId, command.requestId);
|
|
144
|
+
if (!pending || pending.status !== "PENDING") {
|
|
145
|
+
throw new VaultCoreError("pending capability state not found", "VAULT_REQUEST_NOT_FOUND");
|
|
146
|
+
}
|
|
147
|
+
const issuedAt = this._deps.clock.nowIso();
|
|
148
|
+
const capability = {
|
|
149
|
+
vaultId: this._deps.vaultId,
|
|
150
|
+
agentId: pending.agentId,
|
|
151
|
+
capabilityId: pending.capabilityId ?? this._deps.ids.newCapabilityId(),
|
|
152
|
+
secretIds: pending.secretIds ? [...pending.secretIds] : undefined,
|
|
153
|
+
secretAliases: pending.secretAliases ? [...pending.secretAliases] : (pending.secretAlias ? [pending.secretAlias] : []),
|
|
154
|
+
operation: pending.operation,
|
|
155
|
+
customFlowId: pending.customFlowId,
|
|
156
|
+
scope: pending.targetUrl ?? pending.scope,
|
|
157
|
+
methods: [...pending.methods],
|
|
158
|
+
issuedAt,
|
|
159
|
+
expiresAt: pending.expiresAt,
|
|
160
|
+
rateLimit: pending.rateLimit,
|
|
161
|
+
skipAudit: pending.skipAudit,
|
|
162
|
+
};
|
|
163
|
+
let result;
|
|
164
|
+
if (this._isExecutablePendingState(pending)) {
|
|
165
|
+
result = await this.agentDispatchSecret({
|
|
166
|
+
vaultId: this._deps.vaultId,
|
|
167
|
+
agent: { kind: "agent", id: pending.agentId },
|
|
168
|
+
capability,
|
|
169
|
+
secretAlias: pending.secretAlias === "unknown" ? undefined : pending.secretAlias,
|
|
170
|
+
targetUrl: pending.targetUrl,
|
|
171
|
+
method: pending.methods[0] ?? "POST",
|
|
172
|
+
headers: pending.headers,
|
|
173
|
+
body: pending.body,
|
|
174
|
+
proof: pending.proof,
|
|
175
|
+
requestId: pending.requestId,
|
|
176
|
+
requestedAt: pending.requestedAt,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else if (mode === "grant") {
|
|
180
|
+
result = {
|
|
181
|
+
vaultId: this._deps.vaultId,
|
|
182
|
+
requestId: pending.requestId ?? command.requestId,
|
|
183
|
+
status: DispatchStatus.SUCCEEDED,
|
|
184
|
+
targetUrl: pending.scope,
|
|
185
|
+
method: pending.methods[0] ?? "POST",
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
throw new VaultCoreError("pending capability state is not executable", "VAULT_WRITE_DENIED");
|
|
190
|
+
}
|
|
191
|
+
if (mode === "grant") {
|
|
192
|
+
await this._deps.capabilityStates.upsert({
|
|
193
|
+
...pending,
|
|
194
|
+
capabilityId: capability.capabilityId,
|
|
195
|
+
status: "GRANTED",
|
|
196
|
+
source: "owner_grant",
|
|
197
|
+
issuedAt,
|
|
198
|
+
decidedAt: issuedAt,
|
|
199
|
+
});
|
|
200
|
+
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.APPROVE_CAPABILITY_REQUEST, AuditOutcome.SUCCEEDED, `executed and granted capability state ${command.requestId}`, {
|
|
201
|
+
requestId: command.requestId,
|
|
202
|
+
agentId: pending.agentId,
|
|
203
|
+
capabilityId: capability.capabilityId,
|
|
204
|
+
operation: capability.operation,
|
|
205
|
+
}));
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
await this._deps.capabilityStates.deleteByRequestId(command.vaultId, command.requestId);
|
|
209
|
+
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.APPROVE_CAPABILITY_REQUEST, AuditOutcome.SUCCEEDED, `executed once and deleted capability state ${command.requestId}`, {
|
|
210
|
+
requestId: command.requestId,
|
|
211
|
+
agentId: pending.agentId,
|
|
212
|
+
capabilityId: capability.capabilityId,
|
|
213
|
+
operation: capability.operation,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
96
218
|
get vaultId() {
|
|
97
219
|
return this._deps.vaultId;
|
|
98
220
|
}
|
|
@@ -142,7 +264,9 @@ export class VaultCore {
|
|
|
142
264
|
}
|
|
143
265
|
}
|
|
144
266
|
async _listVisibleSecretsForAgent(agentId) {
|
|
145
|
-
const capabilities = await this._deps.
|
|
267
|
+
const capabilities = (await this._deps.capabilityStates.list(this._deps.vaultId, agentId))
|
|
268
|
+
.filter((state) => state.status === "GRANTED")
|
|
269
|
+
.map((state) => this._stateToGrantedCapability(state));
|
|
146
270
|
const capabilityMap = new Map();
|
|
147
271
|
for (const capability of capabilities) {
|
|
148
272
|
for (const alias of capability.secretAliases ?? []) {
|
|
@@ -163,7 +287,7 @@ export class VaultCore {
|
|
|
163
287
|
secretId: record.secretId,
|
|
164
288
|
alias: record.alias,
|
|
165
289
|
issuerId: record.issuerId,
|
|
166
|
-
|
|
290
|
+
source: record.source,
|
|
167
291
|
createdAt: record.createdAt,
|
|
168
292
|
updatedAt: record.updatedAt,
|
|
169
293
|
isAuthorizedForAgent: authorizedCapabilities.length > 0,
|
|
@@ -171,16 +295,10 @@ export class VaultCore {
|
|
|
171
295
|
};
|
|
172
296
|
});
|
|
173
297
|
}
|
|
174
|
-
|
|
175
|
-
this.
|
|
298
|
+
ownerOnCapabilityState(callback) {
|
|
299
|
+
this._capabilityStateObservers.add(callback);
|
|
176
300
|
return () => {
|
|
177
|
-
this.
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
ownerOnPendingCapabilityRequest(callback) {
|
|
181
|
-
this._pendingCapabilityObservers.add(callback);
|
|
182
|
-
return () => {
|
|
183
|
-
this._pendingCapabilityObservers.delete(callback);
|
|
301
|
+
this._capabilityStateObservers.delete(callback);
|
|
184
302
|
};
|
|
185
303
|
}
|
|
186
304
|
async ownerRegisterAgentIdentity(command) {
|
|
@@ -245,7 +363,13 @@ export class VaultCore {
|
|
|
245
363
|
throw new VaultCoreError("capability id required", "VAULT_IDENTITY_DENIED");
|
|
246
364
|
}
|
|
247
365
|
try {
|
|
248
|
-
await this._deps.
|
|
366
|
+
await this._deps.capabilityStates.upsert({
|
|
367
|
+
...command.capability,
|
|
368
|
+
status: "GRANTED",
|
|
369
|
+
source: "owner_grant",
|
|
370
|
+
requestId: undefined,
|
|
371
|
+
requestedAt: command.capability.issuedAt,
|
|
372
|
+
});
|
|
249
373
|
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.REGISTER_CAPABILITY, AuditOutcome.SUCCEEDED, `capability registered: ${command.capability.capabilityId}`, {
|
|
250
374
|
capabilityId: command.capability.capabilityId,
|
|
251
375
|
operation: command.capability.operation,
|
|
@@ -275,28 +399,27 @@ export class VaultCore {
|
|
|
275
399
|
}
|
|
276
400
|
const pendingRecord = {
|
|
277
401
|
vaultId: this._deps.vaultId,
|
|
402
|
+
status: "PENDING",
|
|
403
|
+
source: "explicit_request",
|
|
278
404
|
requestId: command.requestId,
|
|
279
|
-
requester: command.requester,
|
|
280
405
|
agentId: command.agentId,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
expiresAt: command.scope.expiresAt,
|
|
289
|
-
},
|
|
406
|
+
operation: command.scope.operation,
|
|
407
|
+
secretAliases: command.scope.secretAliases ? [...command.scope.secretAliases] : [],
|
|
408
|
+
scope: command.scope.scope,
|
|
409
|
+
methods: [...command.scope.methods],
|
|
410
|
+
rateLimit: command.scope.rateLimit,
|
|
411
|
+
skipAudit: command.scope.skipAudit,
|
|
412
|
+
expiresAt: command.scope.expiresAt,
|
|
290
413
|
justification: command.justification,
|
|
291
414
|
requestedAt: command.requestedAt,
|
|
292
415
|
};
|
|
293
|
-
await this._deps.
|
|
294
|
-
for (const observer of this.
|
|
416
|
+
await this._deps.capabilityStates.upsert(pendingRecord);
|
|
417
|
+
for (const observer of this._capabilityStateObservers) {
|
|
295
418
|
try {
|
|
296
419
|
observer(pendingRecord);
|
|
297
420
|
}
|
|
298
421
|
catch (error) {
|
|
299
|
-
console.error("VaultCore: error in
|
|
422
|
+
console.error("VaultCore: error in capability state observer:", error);
|
|
300
423
|
}
|
|
301
424
|
}
|
|
302
425
|
await this._appendAudit(toAuditEntry(this._deps, command.requester, AuditAction.SUBMIT_CAPABILITY_REQUEST, AuditOutcome.PENDING, `capability request submitted for agent: ${command.agentId}`, {
|
|
@@ -310,7 +433,8 @@ export class VaultCore {
|
|
|
310
433
|
if (vaultId.value !== this._deps.vaultId.value) {
|
|
311
434
|
throw new VaultCoreError("capability lookup vault mismatch", "VAULT_IDENTITY_DENIED");
|
|
312
435
|
}
|
|
313
|
-
|
|
436
|
+
const state = await this._deps.capabilityStates.getByCapabilityId(vaultId, agentId, capabilityId);
|
|
437
|
+
return state && state.status === "GRANTED" ? this._stateToGrantedCapability(state) : null;
|
|
314
438
|
}
|
|
315
439
|
async ownerRegisterCustomFlow(command) {
|
|
316
440
|
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
@@ -344,13 +468,7 @@ export class VaultCore {
|
|
|
344
468
|
}
|
|
345
469
|
async _storeCustomFlowSecret(flow, alias, plaintext) {
|
|
346
470
|
const actor = { kind: "owner", id: flow.ownerId };
|
|
347
|
-
const
|
|
348
|
-
kind: "site",
|
|
349
|
-
targetId: flow.flowId,
|
|
350
|
-
targetUrl: flow.targetUrl,
|
|
351
|
-
methods: [flow.method],
|
|
352
|
-
paths: [new URL(flow.targetUrl).pathname || "/"],
|
|
353
|
-
}];
|
|
471
|
+
const requestId = this._deps.ids.newRequestId("custom_flow_store");
|
|
354
472
|
const existing = await this._deps.secrets.getByAlias({ value: alias });
|
|
355
473
|
if (existing) {
|
|
356
474
|
await this._appendAudit(toAuditEntry(this._deps, actor, AuditAction.REASSIGN_ALIAS, AuditOutcome.DENIED, "alias already bound to existing secret; explicit alias lifecycle required", {
|
|
@@ -362,11 +480,14 @@ export class VaultCore {
|
|
|
362
480
|
const record = buildSecretRecord(this._deps, {
|
|
363
481
|
kind: "owner.write_secret",
|
|
364
482
|
vaultId: this._deps.vaultId,
|
|
365
|
-
requestId
|
|
483
|
+
requestId,
|
|
366
484
|
owner: actor,
|
|
367
485
|
alias,
|
|
368
486
|
plaintext,
|
|
369
|
-
|
|
487
|
+
source: {
|
|
488
|
+
kind: "request",
|
|
489
|
+
requestId,
|
|
490
|
+
},
|
|
370
491
|
requestedAt: this._deps.clock.nowIso(),
|
|
371
492
|
});
|
|
372
493
|
try {
|
|
@@ -443,41 +564,6 @@ export class VaultCore {
|
|
|
443
564
|
secretId: record.secretId.value,
|
|
444
565
|
}));
|
|
445
566
|
}
|
|
446
|
-
async ownerDefineSecretTargets(command) {
|
|
447
|
-
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
448
|
-
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
449
|
-
}
|
|
450
|
-
try {
|
|
451
|
-
await this._deps.policy.authorizeDefineSecretTargets(command);
|
|
452
|
-
}
|
|
453
|
-
catch (error) {
|
|
454
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
455
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.DEFINE_SECRET_TARGETS, AuditOutcome.DENIED, detail, {
|
|
456
|
-
secretAlias: command.alias,
|
|
457
|
-
}));
|
|
458
|
-
throw error;
|
|
459
|
-
}
|
|
460
|
-
const existing = await this._deps.secrets.getByAlias({ value: command.alias });
|
|
461
|
-
if (!existing) {
|
|
462
|
-
const error = new VaultCoreError("secret not found", "VAULT_SECRET_NOT_FOUND");
|
|
463
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.DEFINE_SECRET_TARGETS, AuditOutcome.DENIED, error.message, {
|
|
464
|
-
secretAlias: command.alias,
|
|
465
|
-
}));
|
|
466
|
-
throw error;
|
|
467
|
-
}
|
|
468
|
-
const nextRecord = {
|
|
469
|
-
...existing,
|
|
470
|
-
targetBindings: [...command.targetBindings],
|
|
471
|
-
updatedAt: this._deps.clock.nowIso(),
|
|
472
|
-
};
|
|
473
|
-
await this._deps.secrets.save(nextRecord);
|
|
474
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.DEFINE_SECRET_TARGETS, AuditOutcome.SUCCEEDED, "secret targets defined", {
|
|
475
|
-
requestId: command.requestId,
|
|
476
|
-
secretAlias: nextRecord.alias.value,
|
|
477
|
-
secretId: nextRecord.secretId.value,
|
|
478
|
-
}));
|
|
479
|
-
return nextRecord;
|
|
480
|
-
}
|
|
481
567
|
async agentAuthorizeDispatch(request) {
|
|
482
568
|
if (request.vaultId.value !== this._deps.vaultId.value) {
|
|
483
569
|
throw new VaultCoreError("request vault mismatch", "VAULT_DISPATCH_DENIED");
|
|
@@ -492,7 +578,6 @@ export class VaultCore {
|
|
|
492
578
|
decision: "deny",
|
|
493
579
|
reason: "secret not found",
|
|
494
580
|
secretId: null,
|
|
495
|
-
executorTarget: null,
|
|
496
581
|
};
|
|
497
582
|
}
|
|
498
583
|
try {
|
|
@@ -511,41 +596,44 @@ export class VaultCore {
|
|
|
511
596
|
// DISCOVERY LOGIC: Find best matching capability
|
|
512
597
|
const agentRecord = await this._deps.agentIdentities.get(this._deps.vaultId, request.agent.id);
|
|
513
598
|
if (!agentRecord) {
|
|
514
|
-
return { vaultId: this._deps.vaultId, decision: "deny", reason: "agent not found", secretId: null
|
|
599
|
+
return { vaultId: this._deps.vaultId, decision: "deny", reason: "agent not found", secretId: null };
|
|
515
600
|
}
|
|
516
|
-
const capabilities = await this._deps.
|
|
601
|
+
const capabilities = (await this._deps.capabilityStates.list(this._deps.vaultId, request.agent.id))
|
|
602
|
+
.filter((state) => state.status === "GRANTED")
|
|
603
|
+
.map((state) => this._stateToGrantedCapability(state));
|
|
517
604
|
const requestedCapabilityId = request.capability?.capabilityId;
|
|
518
605
|
const candidateCapabilities = requestedCapabilityId
|
|
519
606
|
? capabilities.filter((cap) => cap.capabilityId === requestedCapabilityId)
|
|
520
607
|
: capabilities;
|
|
521
608
|
const capability = candidateCapabilities.find((cap) => this.isCapabilityMatch(cap, request, record?.secretId.value));
|
|
522
|
-
const executorTarget = record
|
|
523
|
-
? record.targetBindings.find((binding) => binding.targetUrl === request.targetUrl)
|
|
524
|
-
?? record.targetBindings.find((binding) => binding.targetId === request.targetUrl)
|
|
525
|
-
?? null
|
|
526
|
-
: null;
|
|
527
609
|
if (!capability) {
|
|
528
610
|
// It's a discovery case if the agent and secret exist but no capability matches
|
|
529
611
|
const pendingRecord = {
|
|
612
|
+
vaultId: this._deps.vaultId,
|
|
613
|
+
status: "PENDING",
|
|
614
|
+
source: "dispatch_discovery",
|
|
530
615
|
requestId: request.requestId,
|
|
531
616
|
agentId: request.agent.id,
|
|
532
617
|
capabilityId: undefined,
|
|
618
|
+
operation: "dispatch_http",
|
|
619
|
+
secretAliases: request.secretAlias ? [request.secretAlias] : [],
|
|
620
|
+
scope: request.targetUrl,
|
|
621
|
+
methods: [request.method],
|
|
622
|
+
requestedAt: request.requestedAt,
|
|
533
623
|
secretAlias: request.secretAlias ?? "unknown",
|
|
534
624
|
targetUrl: request.targetUrl,
|
|
535
|
-
method: request.method,
|
|
536
625
|
headers: request.headers,
|
|
537
626
|
body: request.body,
|
|
538
|
-
requestedAt: request.requestedAt,
|
|
539
627
|
proof: request.proof,
|
|
540
628
|
};
|
|
541
|
-
await this._deps.
|
|
629
|
+
await this._deps.capabilityStates.upsert(pendingRecord);
|
|
542
630
|
// Notify observers
|
|
543
|
-
for (const observer of this.
|
|
631
|
+
for (const observer of this._capabilityStateObservers) {
|
|
544
632
|
try {
|
|
545
633
|
observer(pendingRecord);
|
|
546
634
|
}
|
|
547
635
|
catch (error) {
|
|
548
|
-
console.error("VaultCore: error in
|
|
636
|
+
console.error("VaultCore: error in capability state observer:", error);
|
|
549
637
|
}
|
|
550
638
|
}
|
|
551
639
|
await this._appendDecisionAudit(request, AuditOutcome.PENDING, "dispatch stalled for manual discovery approval", {
|
|
@@ -557,7 +645,6 @@ export class VaultCore {
|
|
|
557
645
|
decision: "pending",
|
|
558
646
|
reason: "no matching capability found (discovery needed)",
|
|
559
647
|
secretId: record?.secretId ?? null,
|
|
560
|
-
executorTarget,
|
|
561
648
|
};
|
|
562
649
|
}
|
|
563
650
|
try {
|
|
@@ -577,7 +664,6 @@ export class VaultCore {
|
|
|
577
664
|
decision: "deny",
|
|
578
665
|
reason: detail,
|
|
579
666
|
secretId: record?.secretId ?? null,
|
|
580
|
-
executorTarget,
|
|
581
667
|
};
|
|
582
668
|
}
|
|
583
669
|
// Capability found, proceed
|
|
@@ -592,7 +678,6 @@ export class VaultCore {
|
|
|
592
678
|
decision: "allow",
|
|
593
679
|
reason: null,
|
|
594
680
|
secretId: record?.secretId ?? null,
|
|
595
|
-
executorTarget,
|
|
596
681
|
capability, // Expose the found capability for subsequent steps
|
|
597
682
|
};
|
|
598
683
|
}
|
|
@@ -705,7 +790,9 @@ export class VaultCore {
|
|
|
705
790
|
return identities;
|
|
706
791
|
}
|
|
707
792
|
async ownerListCapabilities(actor, agentId, request) {
|
|
708
|
-
const capabilities = await this._deps.
|
|
793
|
+
const capabilities = (await this._deps.capabilityStates.list(this._deps.vaultId, agentId))
|
|
794
|
+
.filter((state) => state.status === "GRANTED")
|
|
795
|
+
.map((state) => this._stateToGrantedCapability(state));
|
|
709
796
|
await this._appendAudit(toAuditEntry(this._deps, actor, AuditAction.LIST_CAPABILITIES, AuditOutcome.ALLOWED, "capabilities listed", {
|
|
710
797
|
requestId: request?.requestId,
|
|
711
798
|
agentId,
|
|
@@ -722,7 +809,7 @@ export class VaultCore {
|
|
|
722
809
|
secretId: record.secretId,
|
|
723
810
|
alias: record.alias,
|
|
724
811
|
issuerId: record.issuerId,
|
|
725
|
-
|
|
812
|
+
source: record.source,
|
|
726
813
|
createdAt: record.createdAt,
|
|
727
814
|
updatedAt: record.updatedAt,
|
|
728
815
|
}));
|
|
@@ -732,7 +819,7 @@ export class VaultCore {
|
|
|
732
819
|
throw new VaultCoreError("read vault mismatch", "VAULT_READ_DENIED");
|
|
733
820
|
}
|
|
734
821
|
await this._verifyAgentControlProof(request, "list_capabilities");
|
|
735
|
-
return this.
|
|
822
|
+
return this._buildAgentCapabilityStates(request.agent.id);
|
|
736
823
|
}
|
|
737
824
|
async agentListSecrets(request) {
|
|
738
825
|
if (request.vaultId.value !== this._deps.vaultId.value) {
|
|
@@ -745,13 +832,25 @@ export class VaultCore {
|
|
|
745
832
|
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
746
833
|
throw new VaultCoreError("read vault mismatch", "VAULT_READ_DENIED");
|
|
747
834
|
}
|
|
748
|
-
|
|
835
|
+
await this._verifyAgentControlProof(command, "get_manifest");
|
|
836
|
+
const agentRecord = await this._deps.agentIdentities.get(this._deps.vaultId, command.agent.id);
|
|
837
|
+
if (!agentRecord) {
|
|
838
|
+
throw new VaultCoreError("agent identity not registered", "VAULT_DISPATCH_DENIED");
|
|
839
|
+
}
|
|
840
|
+
const capabilities = await this._buildAgentCapabilityStates(command.agent.id);
|
|
749
841
|
const vaultNickname = "CBIO Vault"; // TODO: Pull from profile if available
|
|
750
842
|
return {
|
|
751
843
|
agentId: command.agent.id,
|
|
752
844
|
vaultId: this._deps.vaultId.value,
|
|
753
845
|
vaultNickname,
|
|
754
846
|
issuedAt: this._deps.clock.nowIso(),
|
|
847
|
+
agent: {
|
|
848
|
+
agentId: agentRecord.agentId,
|
|
849
|
+
identityId: agentRecord.identityId,
|
|
850
|
+
publicKey: agentRecord.publicKey,
|
|
851
|
+
nickname: agentRecord.nickname,
|
|
852
|
+
metadata: agentRecord.metadata,
|
|
853
|
+
},
|
|
755
854
|
capabilities,
|
|
756
855
|
tools: getAgentToolbox(),
|
|
757
856
|
};
|
|
@@ -778,7 +877,15 @@ export class VaultCore {
|
|
|
778
877
|
});
|
|
779
878
|
}
|
|
780
879
|
async ownerRevokeCapability(command) {
|
|
781
|
-
await this._deps.
|
|
880
|
+
const existing = await this._deps.capabilityStates.getByCapabilityId(command.vaultId, command.agentId, command.capabilityId);
|
|
881
|
+
if (!existing) {
|
|
882
|
+
throw new VaultCoreError("capability not found", "VAULT_CAPABILITY_NOT_FOUND");
|
|
883
|
+
}
|
|
884
|
+
await this._deps.capabilityStates.upsert({
|
|
885
|
+
...existing,
|
|
886
|
+
status: "REJECTED",
|
|
887
|
+
decidedAt: this._deps.clock.nowIso(),
|
|
888
|
+
});
|
|
782
889
|
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.REVOKE_CAPABILITY, AuditOutcome.SUCCEEDED, "capability revoked", {
|
|
783
890
|
requestId: command.requestId,
|
|
784
891
|
agentId: command.agentId,
|
|
@@ -824,135 +931,39 @@ export class VaultCore {
|
|
|
824
931
|
await this._deps.sessionTokens.revoke(request.token);
|
|
825
932
|
await this._appendAudit(toAuditEntry(this._deps, request.actor, AuditAction.REVOKE_SESSION_TOKEN, AuditOutcome.SUCCEEDED, "session token revoked"));
|
|
826
933
|
}
|
|
827
|
-
async
|
|
934
|
+
async ownerListCapabilityStates(command) {
|
|
828
935
|
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
829
936
|
throw new VaultCoreError("read vault mismatch", "VAULT_READ_DENIED");
|
|
830
937
|
}
|
|
831
|
-
return this._deps.
|
|
938
|
+
return (await this._deps.capabilityStates.list(command.vaultId, command.agentId))
|
|
939
|
+
.filter((state) => !command.status || state.status === command.status);
|
|
832
940
|
}
|
|
833
|
-
async
|
|
834
|
-
|
|
835
|
-
throw new VaultCoreError("read vault mismatch", "VAULT_READ_DENIED");
|
|
836
|
-
}
|
|
837
|
-
return this._deps.pendingCapabilityRequests.list(command.vaultId);
|
|
941
|
+
async ownerExecuteCapabilityStateOnce(command) {
|
|
942
|
+
return this._executePendingCapabilityState(command, "once");
|
|
838
943
|
}
|
|
839
|
-
async
|
|
840
|
-
|
|
841
|
-
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
842
|
-
}
|
|
843
|
-
const pending = await this._deps.pendingCapabilityRequests.get(command.requestId);
|
|
844
|
-
if (!pending) {
|
|
845
|
-
throw new VaultCoreError("pending capability request not found", "VAULT_REQUEST_NOT_FOUND");
|
|
846
|
-
}
|
|
847
|
-
const capability = {
|
|
848
|
-
vaultId: this._deps.vaultId,
|
|
849
|
-
agentId: pending.agentId,
|
|
850
|
-
capabilityId: command.capabilityId ?? this._deps.ids.newCapabilityId(),
|
|
851
|
-
operation: pending.scope.operation,
|
|
852
|
-
secretAliases: pending.scope.secretAliases ? [...pending.scope.secretAliases] : [],
|
|
853
|
-
scope: pending.scope.scope,
|
|
854
|
-
methods: [...pending.scope.methods],
|
|
855
|
-
rateLimit: pending.scope.rateLimit,
|
|
856
|
-
skipAudit: pending.scope.skipAudit,
|
|
857
|
-
expiresAt: pending.scope.expiresAt,
|
|
858
|
-
issuedAt: this._deps.clock.nowIso(),
|
|
859
|
-
};
|
|
860
|
-
await this._deps.capabilities.register(capability);
|
|
861
|
-
await this._deps.pendingCapabilityRequests.delete(command.requestId);
|
|
862
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.APPROVE_CAPABILITY_REQUEST, AuditOutcome.SUCCEEDED, `approved capability request ${command.requestId}`, {
|
|
863
|
-
requestId: command.requestId,
|
|
864
|
-
agentId: pending.agentId,
|
|
865
|
-
capabilityId: capability.capabilityId,
|
|
866
|
-
operation: capability.operation,
|
|
867
|
-
}));
|
|
868
|
-
return capability;
|
|
944
|
+
async ownerExecuteCapabilityStateAndGrant(command) {
|
|
945
|
+
return this._executePendingCapabilityState(command, "grant");
|
|
869
946
|
}
|
|
870
|
-
async
|
|
947
|
+
async ownerRejectCapabilityState(command) {
|
|
871
948
|
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
872
949
|
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
873
950
|
}
|
|
874
|
-
const pending = await this._deps.
|
|
875
|
-
if (!pending) {
|
|
876
|
-
throw new VaultCoreError("pending capability
|
|
951
|
+
const pending = await this._deps.capabilityStates.getByRequestId(command.vaultId, command.requestId);
|
|
952
|
+
if (!pending || pending.status !== "PENDING") {
|
|
953
|
+
throw new VaultCoreError("pending capability state not found", "VAULT_REQUEST_NOT_FOUND");
|
|
877
954
|
}
|
|
878
|
-
|
|
955
|
+
const rejectedState = {
|
|
956
|
+
...pending,
|
|
957
|
+
status: "REJECTED",
|
|
958
|
+
decidedAt: this._deps.clock.nowIso(),
|
|
959
|
+
};
|
|
960
|
+
await this._deps.capabilityStates.upsert(rejectedState);
|
|
879
961
|
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.REJECT_CAPABILITY_REQUEST, AuditOutcome.SUCCEEDED, `rejected capability request ${command.requestId}`, {
|
|
880
962
|
requestId: command.requestId,
|
|
881
963
|
agentId: pending.agentId,
|
|
882
|
-
operation: pending.
|
|
883
|
-
}));
|
|
884
|
-
}
|
|
885
|
-
async ownerApproveDispatch(command) {
|
|
886
|
-
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
887
|
-
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
888
|
-
}
|
|
889
|
-
const pending = await this._deps.pendingRequests.get(command.requestId);
|
|
890
|
-
if (!pending) {
|
|
891
|
-
throw new VaultCoreError("pending request not found", "VAULT_REQUEST_NOT_FOUND");
|
|
892
|
-
}
|
|
893
|
-
const agentRecord = await this._deps.agentIdentities.get(this._deps.vaultId, pending.agentId);
|
|
894
|
-
if (!agentRecord) {
|
|
895
|
-
throw new VaultCoreError("agent identity not found", "VAULT_AGENT_NOT_FOUND");
|
|
896
|
-
}
|
|
897
|
-
let capability;
|
|
898
|
-
if (pending.capabilityId) {
|
|
899
|
-
const existing = await this._deps.capabilities.get(this._deps.vaultId, pending.agentId, pending.capabilityId);
|
|
900
|
-
if (!existing) {
|
|
901
|
-
throw new VaultCoreError("capability not found", "VAULT_CAPABILITY_NOT_FOUND");
|
|
902
|
-
}
|
|
903
|
-
capability = existing;
|
|
904
|
-
}
|
|
905
|
-
else {
|
|
906
|
-
// Discovery case: derive from request
|
|
907
|
-
const capabilityId = this._deps.ids.newCapabilityId();
|
|
908
|
-
capability = {
|
|
909
|
-
vaultId: this._deps.vaultId,
|
|
910
|
-
agentId: pending.agentId,
|
|
911
|
-
capabilityId,
|
|
912
|
-
secretAliases: [pending.secretAlias],
|
|
913
|
-
methods: [pending.method],
|
|
914
|
-
scope: pending.targetUrl,
|
|
915
|
-
operation: "dispatch_http",
|
|
916
|
-
issuedAt: this._deps.clock.nowIso(),
|
|
917
|
-
skipAudit: command.skipAudit ?? false,
|
|
918
|
-
};
|
|
919
|
-
if (command.permanent) {
|
|
920
|
-
await this._deps.capabilities.register(capability);
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
const result = await this.agentDispatchSecret({
|
|
924
|
-
vaultId: this._deps.vaultId,
|
|
925
|
-
agent: { kind: "agent", id: pending.agentId },
|
|
926
|
-
capability: capability,
|
|
927
|
-
secretAlias: pending.secretAlias === "unknown" ? undefined : pending.secretAlias,
|
|
928
|
-
targetUrl: pending.targetUrl,
|
|
929
|
-
method: pending.method,
|
|
930
|
-
headers: pending.headers,
|
|
931
|
-
body: pending.body,
|
|
932
|
-
proof: pending.proof,
|
|
933
|
-
requestId: pending.requestId,
|
|
934
|
-
requestedAt: pending.requestedAt,
|
|
935
|
-
});
|
|
936
|
-
await this._deps.pendingRequests.delete(command.requestId);
|
|
937
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.APPROVE_DISPATCH, AuditOutcome.SUCCEEDED, `approved dispatch ${command.requestId}${command.permanent ? " and granted permanent capability" : ""}`, {
|
|
938
|
-
requestId: command.requestId,
|
|
939
|
-
agentId: pending.agentId,
|
|
940
|
-
capabilityId: capability.capabilityId,
|
|
941
|
-
}));
|
|
942
|
-
return result;
|
|
943
|
-
}
|
|
944
|
-
async ownerRejectDispatch(command) {
|
|
945
|
-
if (command.vaultId.value !== this._deps.vaultId.value) {
|
|
946
|
-
throw new VaultCoreError("write vault mismatch", "VAULT_WRITE_DENIED");
|
|
947
|
-
}
|
|
948
|
-
const pending = await this._deps.pendingRequests.get(command.requestId);
|
|
949
|
-
if (!pending) {
|
|
950
|
-
throw new VaultCoreError("pending request not found", "VAULT_REQUEST_NOT_FOUND");
|
|
951
|
-
}
|
|
952
|
-
await this._deps.pendingRequests.delete(command.requestId);
|
|
953
|
-
await this._appendAudit(toAuditEntry(this._deps, command.owner, AuditAction.REJECT_DISPATCH, AuditOutcome.SUCCEEDED, `rejected dispatch ${command.requestId}`, {
|
|
954
|
-
requestId: command.requestId,
|
|
964
|
+
operation: pending.operation,
|
|
955
965
|
}));
|
|
966
|
+
return rejectedState;
|
|
956
967
|
}
|
|
957
968
|
}
|
|
958
969
|
export function createVaultCore(deps) {
|