@treeseed/sdk 0.13.0-rc.82 → 0.13.0-rc.84
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/dist/.treeseed-build-complete.json +1 -1
- package/dist/agent-capacity/artifact-mutation-receipt.d.ts +1 -1
- package/dist/agent-capacity/contracts/capacity/assignments/assignment-records.d.ts +1 -1
- package/dist/agent-capacity/contracts/capacity/workdays/workday-records.d.ts +1 -1
- package/dist/agent-capacity/contracts/runtime/runtime-observability.d.ts +3 -3
- package/dist/agent-capacity/contracts/support/decision-work.d.ts +1 -1
- package/dist/configuration/secrets-capability.d.ts +1 -0
- package/dist/configuration/secrets-capability.js +1 -0
- package/dist/operator-contracts/catalog/hosted-topology-operations.d.ts +206 -103
- package/dist/operator-contracts/catalog/hosted-topology-operations.js +11 -4
- package/dist/operator-contracts/catalog/services/service-vault-operations.d.ts +17 -0
- package/dist/operator-contracts/catalog/services/service-vault-operations.js +158 -0
- package/dist/operator-contracts/control-plane-operations.d.ts +221 -103
- package/dist/operator-contracts/control-plane-operations.js +5 -3
- package/dist/secrets-capability/service-provider-contracts.js +4 -4
- package/dist/secrets-capability/service-vault-contracts.d.ts +48 -1
- package/dist/secrets-capability/service-vault-contracts.js +36 -1
- package/dist/secrets-capability/service-vault-crypto.d.ts +20 -0
- package/dist/secrets-capability/service-vault-crypto.js +210 -0
- package/dist/types/agents/agent-trigger-kinds.d.ts +0 -1
- package/package.json +2 -1
|
@@ -62,92 +62,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
62
62
|
connectionRef: string;
|
|
63
63
|
}>>;
|
|
64
64
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
blockers: {
|
|
68
|
-
code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
|
|
69
|
-
message: string;
|
|
70
|
-
resourceId?: string | undefined;
|
|
71
|
-
}[];
|
|
72
|
-
planDigest: string;
|
|
73
|
-
actions: {
|
|
74
|
-
action: "noop" | "create" | "adopt" | "update";
|
|
75
|
-
resourceId: string;
|
|
76
|
-
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
77
|
-
provider: "cloudflare" | "railway";
|
|
78
|
-
providerResourceId: string | null;
|
|
79
|
-
desiredResource: {
|
|
80
|
-
id: string;
|
|
81
|
-
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
82
|
-
provider: "cloudflare" | "railway";
|
|
83
|
-
adoption: {
|
|
84
|
-
mode: "adopt-or-create";
|
|
85
|
-
replacement: "forbidden";
|
|
86
|
-
externalIdInput?: string | undefined;
|
|
87
|
-
};
|
|
88
|
-
dependsOn?: string[] | undefined;
|
|
89
|
-
parameters?: Record<string, {
|
|
90
|
-
input: string;
|
|
91
|
-
} | {
|
|
92
|
-
artifact: string;
|
|
93
|
-
} | {
|
|
94
|
-
resourceOutput: {
|
|
95
|
-
resourceId: string;
|
|
96
|
-
output: string;
|
|
97
|
-
};
|
|
98
|
-
} | {
|
|
99
|
-
literal: string | number | boolean;
|
|
100
|
-
}> | undefined;
|
|
101
|
-
};
|
|
102
|
-
desiredDigest: string;
|
|
103
|
-
previousDigest: string | null;
|
|
104
|
-
}[];
|
|
105
|
-
teamId: string;
|
|
106
|
-
environment: "production" | "staging";
|
|
107
|
-
executable: false;
|
|
108
|
-
artifacts: Record<string, {
|
|
109
|
-
digest: string;
|
|
110
|
-
source: string;
|
|
111
|
-
kind: "archive";
|
|
112
|
-
format: "tar+gzip";
|
|
113
|
-
} | {
|
|
114
|
-
digest: string;
|
|
115
|
-
source: string;
|
|
116
|
-
kind: "file";
|
|
117
|
-
mediaType: string;
|
|
118
|
-
} | {
|
|
119
|
-
digest: string;
|
|
120
|
-
kind: "oci-image";
|
|
121
|
-
identity: string;
|
|
122
|
-
}>;
|
|
123
|
-
planId: string;
|
|
124
|
-
deploymentId: string;
|
|
125
|
-
stackId: string;
|
|
126
|
-
stateBackend: {
|
|
127
|
-
key: string;
|
|
128
|
-
type: "s3";
|
|
129
|
-
schemaVersion: "treeseed.hosted-state-backend/v1";
|
|
130
|
-
teamId: string;
|
|
131
|
-
environment: "production" | "staging";
|
|
132
|
-
deploymentId: string;
|
|
133
|
-
stackId: string;
|
|
134
|
-
connectionRef: string;
|
|
135
|
-
bucket: string;
|
|
136
|
-
region: string;
|
|
137
|
-
encryptionKeyRef: string;
|
|
138
|
-
bindingDigest: string;
|
|
139
|
-
endpoint?: string | undefined;
|
|
140
|
-
usePathStyle?: boolean | undefined;
|
|
141
|
-
} | null;
|
|
142
|
-
providerConnections: Partial<Record<"cloudflare" | "railway", {
|
|
143
|
-
connectionRef: string;
|
|
144
|
-
nonSecretConfig: Record<string, string | number | boolean>;
|
|
145
|
-
}>>;
|
|
146
|
-
declarationDigest: string;
|
|
147
|
-
topologyId: string;
|
|
148
|
-
platformCommit: string;
|
|
149
|
-
approvalRequired: boolean;
|
|
150
|
-
}>;
|
|
65
|
+
credentialLeaseIds?: string[] | undefined;
|
|
66
|
+
}, Record<string, unknown>>;
|
|
151
67
|
readonly apply: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
152
68
|
teamId: string;
|
|
153
69
|
}, {}, {
|
|
@@ -249,6 +165,7 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
249
165
|
platformCommit: string;
|
|
250
166
|
approvalRequired: boolean;
|
|
251
167
|
};
|
|
168
|
+
credentialLeaseIds?: string[] | undefined;
|
|
252
169
|
}, Record<string, unknown>>;
|
|
253
170
|
readonly status: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
254
171
|
teamId: string;
|
|
@@ -293,35 +210,221 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
293
210
|
readonly rollback: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
294
211
|
teamId: string;
|
|
295
212
|
}, {}, {
|
|
296
|
-
|
|
297
|
-
schemaVersion: "treeseed.hosted-topology-rollback/v1";
|
|
213
|
+
approval: {
|
|
214
|
+
schemaVersion: "treeseed.hosted-topology-rollback-execution-approval/v1";
|
|
298
215
|
teamId: string;
|
|
299
216
|
environment: "production" | "staging";
|
|
300
|
-
operations: {
|
|
301
|
-
action: "noop" | "restore" | "delete-created";
|
|
302
|
-
resourceId: string;
|
|
303
|
-
providerResourceId: string;
|
|
304
|
-
targetDigest: string | null;
|
|
305
|
-
}[];
|
|
306
217
|
deploymentId: string;
|
|
307
218
|
stackId: string;
|
|
308
219
|
backendBindingDigest: string;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
220
|
+
decision: "approved";
|
|
221
|
+
approvedBy: string;
|
|
222
|
+
approvedAt: string;
|
|
223
|
+
executionDigest: string;
|
|
312
224
|
};
|
|
313
|
-
|
|
314
|
-
schemaVersion: "treeseed.hosted-topology-rollback-
|
|
225
|
+
execution: {
|
|
226
|
+
schemaVersion: "treeseed.hosted-topology-rollback-execution/v1";
|
|
315
227
|
teamId: string;
|
|
316
228
|
environment: "production" | "staging";
|
|
229
|
+
rollback: {
|
|
230
|
+
schemaVersion: "treeseed.hosted-topology-rollback/v1";
|
|
231
|
+
teamId: string;
|
|
232
|
+
environment: "production" | "staging";
|
|
233
|
+
operations: {
|
|
234
|
+
action: "noop" | "restore" | "delete-created";
|
|
235
|
+
resourceId: string;
|
|
236
|
+
providerResourceId: string;
|
|
237
|
+
targetDigest: string | null;
|
|
238
|
+
}[];
|
|
239
|
+
deploymentId: string;
|
|
240
|
+
stackId: string;
|
|
241
|
+
backendBindingDigest: string;
|
|
242
|
+
rollbackId: string;
|
|
243
|
+
sourceReceiptId: string;
|
|
244
|
+
rollbackDigest: string;
|
|
245
|
+
};
|
|
317
246
|
deploymentId: string;
|
|
318
247
|
stackId: string;
|
|
248
|
+
topologyId: string;
|
|
319
249
|
backendBindingDigest: string;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
250
|
+
sourceReceiptId: string;
|
|
251
|
+
sourcePlanDigest: string;
|
|
252
|
+
targetPlanDigest: string;
|
|
253
|
+
executionDigest: string;
|
|
254
|
+
};
|
|
255
|
+
sourcePlan: {
|
|
256
|
+
schemaVersion: "treeseed.hosted-topology-plan/v1";
|
|
257
|
+
blockers: {
|
|
258
|
+
code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
|
|
259
|
+
message: string;
|
|
260
|
+
resourceId?: string | undefined;
|
|
261
|
+
}[];
|
|
262
|
+
planDigest: string;
|
|
263
|
+
actions: {
|
|
264
|
+
action: "noop" | "create" | "adopt" | "update";
|
|
265
|
+
resourceId: string;
|
|
266
|
+
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
267
|
+
provider: "cloudflare" | "railway";
|
|
268
|
+
providerResourceId: string | null;
|
|
269
|
+
desiredResource: {
|
|
270
|
+
id: string;
|
|
271
|
+
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
272
|
+
provider: "cloudflare" | "railway";
|
|
273
|
+
adoption: {
|
|
274
|
+
mode: "adopt-or-create";
|
|
275
|
+
replacement: "forbidden";
|
|
276
|
+
externalIdInput?: string | undefined;
|
|
277
|
+
};
|
|
278
|
+
dependsOn?: string[] | undefined;
|
|
279
|
+
parameters?: Record<string, {
|
|
280
|
+
input: string;
|
|
281
|
+
} | {
|
|
282
|
+
artifact: string;
|
|
283
|
+
} | {
|
|
284
|
+
resourceOutput: {
|
|
285
|
+
resourceId: string;
|
|
286
|
+
output: string;
|
|
287
|
+
};
|
|
288
|
+
} | {
|
|
289
|
+
literal: string | number | boolean;
|
|
290
|
+
}> | undefined;
|
|
291
|
+
};
|
|
292
|
+
desiredDigest: string;
|
|
293
|
+
previousDigest: string | null;
|
|
294
|
+
}[];
|
|
295
|
+
teamId: string;
|
|
296
|
+
environment: "production" | "staging";
|
|
297
|
+
executable: false;
|
|
298
|
+
artifacts: Record<string, {
|
|
299
|
+
digest: string;
|
|
300
|
+
source: string;
|
|
301
|
+
kind: "archive";
|
|
302
|
+
format: "tar+gzip";
|
|
303
|
+
} | {
|
|
304
|
+
digest: string;
|
|
305
|
+
source: string;
|
|
306
|
+
kind: "file";
|
|
307
|
+
mediaType: string;
|
|
308
|
+
} | {
|
|
309
|
+
digest: string;
|
|
310
|
+
kind: "oci-image";
|
|
311
|
+
identity: string;
|
|
312
|
+
}>;
|
|
313
|
+
planId: string;
|
|
314
|
+
deploymentId: string;
|
|
315
|
+
stackId: string;
|
|
316
|
+
stateBackend: {
|
|
317
|
+
key: string;
|
|
318
|
+
type: "s3";
|
|
319
|
+
schemaVersion: "treeseed.hosted-state-backend/v1";
|
|
320
|
+
teamId: string;
|
|
321
|
+
environment: "production" | "staging";
|
|
322
|
+
deploymentId: string;
|
|
323
|
+
stackId: string;
|
|
324
|
+
connectionRef: string;
|
|
325
|
+
bucket: string;
|
|
326
|
+
region: string;
|
|
327
|
+
encryptionKeyRef: string;
|
|
328
|
+
bindingDigest: string;
|
|
329
|
+
endpoint?: string | undefined;
|
|
330
|
+
usePathStyle?: boolean | undefined;
|
|
331
|
+
} | null;
|
|
332
|
+
providerConnections: Partial<Record<"cloudflare" | "railway", {
|
|
333
|
+
connectionRef: string;
|
|
334
|
+
nonSecretConfig: Record<string, string | number | boolean>;
|
|
335
|
+
}>>;
|
|
336
|
+
declarationDigest: string;
|
|
337
|
+
topologyId: string;
|
|
338
|
+
platformCommit: string;
|
|
339
|
+
approvalRequired: boolean;
|
|
340
|
+
};
|
|
341
|
+
targetPlan: {
|
|
342
|
+
schemaVersion: "treeseed.hosted-topology-plan/v1";
|
|
343
|
+
blockers: {
|
|
344
|
+
code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
|
|
345
|
+
message: string;
|
|
346
|
+
resourceId?: string | undefined;
|
|
347
|
+
}[];
|
|
348
|
+
planDigest: string;
|
|
349
|
+
actions: {
|
|
350
|
+
action: "noop" | "create" | "adopt" | "update";
|
|
351
|
+
resourceId: string;
|
|
352
|
+
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
353
|
+
provider: "cloudflare" | "railway";
|
|
354
|
+
providerResourceId: string | null;
|
|
355
|
+
desiredResource: {
|
|
356
|
+
id: string;
|
|
357
|
+
kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
|
|
358
|
+
provider: "cloudflare" | "railway";
|
|
359
|
+
adoption: {
|
|
360
|
+
mode: "adopt-or-create";
|
|
361
|
+
replacement: "forbidden";
|
|
362
|
+
externalIdInput?: string | undefined;
|
|
363
|
+
};
|
|
364
|
+
dependsOn?: string[] | undefined;
|
|
365
|
+
parameters?: Record<string, {
|
|
366
|
+
input: string;
|
|
367
|
+
} | {
|
|
368
|
+
artifact: string;
|
|
369
|
+
} | {
|
|
370
|
+
resourceOutput: {
|
|
371
|
+
resourceId: string;
|
|
372
|
+
output: string;
|
|
373
|
+
};
|
|
374
|
+
} | {
|
|
375
|
+
literal: string | number | boolean;
|
|
376
|
+
}> | undefined;
|
|
377
|
+
};
|
|
378
|
+
desiredDigest: string;
|
|
379
|
+
previousDigest: string | null;
|
|
380
|
+
}[];
|
|
381
|
+
teamId: string;
|
|
382
|
+
environment: "production" | "staging";
|
|
383
|
+
executable: false;
|
|
384
|
+
artifacts: Record<string, {
|
|
385
|
+
digest: string;
|
|
386
|
+
source: string;
|
|
387
|
+
kind: "archive";
|
|
388
|
+
format: "tar+gzip";
|
|
389
|
+
} | {
|
|
390
|
+
digest: string;
|
|
391
|
+
source: string;
|
|
392
|
+
kind: "file";
|
|
393
|
+
mediaType: string;
|
|
394
|
+
} | {
|
|
395
|
+
digest: string;
|
|
396
|
+
kind: "oci-image";
|
|
397
|
+
identity: string;
|
|
398
|
+
}>;
|
|
399
|
+
planId: string;
|
|
400
|
+
deploymentId: string;
|
|
401
|
+
stackId: string;
|
|
402
|
+
stateBackend: {
|
|
403
|
+
key: string;
|
|
404
|
+
type: "s3";
|
|
405
|
+
schemaVersion: "treeseed.hosted-state-backend/v1";
|
|
406
|
+
teamId: string;
|
|
407
|
+
environment: "production" | "staging";
|
|
408
|
+
deploymentId: string;
|
|
409
|
+
stackId: string;
|
|
410
|
+
connectionRef: string;
|
|
411
|
+
bucket: string;
|
|
412
|
+
region: string;
|
|
413
|
+
encryptionKeyRef: string;
|
|
414
|
+
bindingDigest: string;
|
|
415
|
+
endpoint?: string | undefined;
|
|
416
|
+
usePathStyle?: boolean | undefined;
|
|
417
|
+
} | null;
|
|
418
|
+
providerConnections: Partial<Record<"cloudflare" | "railway", {
|
|
419
|
+
connectionRef: string;
|
|
420
|
+
nonSecretConfig: Record<string, string | number | boolean>;
|
|
421
|
+
}>>;
|
|
422
|
+
declarationDigest: string;
|
|
423
|
+
topologyId: string;
|
|
424
|
+
platformCommit: string;
|
|
425
|
+
approvalRequired: boolean;
|
|
324
426
|
};
|
|
427
|
+
credentialLeaseIds?: string[] | undefined;
|
|
325
428
|
}, Record<string, unknown>>;
|
|
326
429
|
};
|
|
327
430
|
};
|
|
@@ -1323,6 +1426,21 @@ export declare const CONTROL_PLANE_OPERATIONS: {
|
|
|
1323
1426
|
profileId: string;
|
|
1324
1427
|
connectionId: string;
|
|
1325
1428
|
}, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
|
|
1429
|
+
readonly userVaultKey: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1430
|
+
readonly putUserVaultKey: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1431
|
+
readonly teamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1432
|
+
readonly initializeTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1433
|
+
readonly resetTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1434
|
+
readonly rotateTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1435
|
+
readonly vaultGrantCandidates: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1436
|
+
readonly createVaultGrant: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1437
|
+
readonly deleteVaultGrant: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1438
|
+
readonly vaultCredentialEnvelopes: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1439
|
+
readonly credentialEnvelopes: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1440
|
+
readonly putCredentialEnvelope: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1441
|
+
readonly createOperationLease: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1442
|
+
readonly operationLease: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1443
|
+
readonly putOperationLeasePayload: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
|
|
1326
1444
|
};
|
|
1327
1445
|
readonly agents: {
|
|
1328
1446
|
readonly list: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
|
|
@@ -8,6 +8,7 @@ import { capabilityOntologyOperations } from "./catalog/capability-ontology-oper
|
|
|
8
8
|
import { knowledgeShareOperations } from "./catalog/knowledge-share-operations.js";
|
|
9
9
|
import { PROVIDER_ENVIRONMENT_OPERATIONS } from "./catalog/provider-environment-operations.js";
|
|
10
10
|
import { HOSTED_TOPOLOGY_OPERATIONS } from "./catalog/hosted-topology-operations.js";
|
|
11
|
+
import { SERVICE_VAULT_OPERATIONS } from "./catalog/services/service-vault-operations.js";
|
|
11
12
|
import { buildControlPlaneCatalog, flattenControlPlaneOperations } from "./catalog/control-plane-catalog.js";
|
|
12
13
|
const empty = z.object({}).strict(), none = z.undefined(), record = z.record(z.unknown()), payload = record;
|
|
13
14
|
function read(operationId, path, capability, surfaces = ["rest"]) {
|
|
@@ -277,6 +278,7 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
277
278
|
deleteWorkflowVariable: resource("repositories.workflow.variables.delete", "DELETE", "/v1/projects/{projectId}/workflow-configuration/variables/{name}", { projectId: z.string().min(1), name: z.string().min(1) }, { capability: "workflows.write", risk: "destructive", concurrency: true })
|
|
278
279
|
},
|
|
279
280
|
services: {
|
|
281
|
+
...SERVICE_VAULT_OPERATIONS,
|
|
280
282
|
providers: resource("services.providers.list", "GET", "/v1/service-providers", {}, { capability: "services.read", surfaces: ["rest", "cli", "mcp_tool"] }),
|
|
281
283
|
connections: resource("services.connections.list", "GET", "/v1/teams/{teamId}/services", { teamId: z.string().min(1) }, { capability: "services.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
|
|
282
284
|
connection: resource("services.connections.show", "GET", "/v1/teams/{teamId}/services/{connectionId}", { teamId: z.string().min(1), connectionId: z.string().min(1) }, { capability: "services.read", surfaces: ["rest", "cli", "mcp_resource"] }),
|
|
@@ -335,12 +337,12 @@ const CONTROL_PLANE_OPERATIONS = {
|
|
|
335
337
|
retry: resource("assignments.retry", "POST", "/v1/teams/{teamId}/capacity/assignments/{assignmentId}/requeue", { teamId: z.string().min(1), assignmentId: z.string().min(1) }, { capability: "assignments.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli", "mcp_tool"], risk: "authority" })
|
|
336
338
|
},
|
|
337
339
|
operations: {
|
|
338
|
-
list: resource("operations.list", "GET", "/v1/platform/operations", {}, { capability: "operations.read", surfaces: ["rest", "mcp_tool"], pagination: "cursor" }),
|
|
340
|
+
list: resource("operations.list", "GET", "/v1/platform/operations", {}, { capability: "operations.read", surfaces: ["rest", "cli", "mcp_tool"], pagination: "cursor" }),
|
|
339
341
|
create: resource("operations.create", "POST", "/v1/platform/operations", {}, { capability: "operations.execute", scopes: ["treeseed:execution"] }),
|
|
340
|
-
show: resource("operations.show", "GET", "/v1/platform/operations/{operationId}", { operationId: z.string().min(1) }, { capability: "operations.read", surfaces: ["rest", "mcp_resource"] }),
|
|
342
|
+
show: resource("operations.show", "GET", "/v1/platform/operations/{operationId}", { operationId: z.string().min(1) }, { capability: "operations.read", surfaces: ["rest", "cli", "mcp_resource"] }),
|
|
341
343
|
events: resource("operations.events.list", "GET", "/v1/platform/operations/{operationId}/events", { operationId: z.string().min(1) }, { capability: "operations.read", pagination: "cursor" }),
|
|
342
344
|
cancel: resource("operations.cancel", "POST", "/v1/platform/operations/{operationId}/cancel", { operationId: z.string().min(1) }, { capability: "operations.execute", scopes: ["treeseed:execution"], risk: "destructive" }),
|
|
343
|
-
retry: resource("operations.retry", "POST", "/v1/platform/operations/{operationId}/retry", { operationId: z.string().min(1) }, { capability: "operations.execute", scopes: ["treeseed:execution"] })
|
|
345
|
+
retry: resource("operations.retry", "POST", "/v1/platform/operations/{operationId}/retry", { operationId: z.string().min(1) }, { capability: "operations.execute", scopes: ["treeseed:execution"], surfaces: ["rest", "cli"] })
|
|
344
346
|
},
|
|
345
347
|
seeds: {
|
|
346
348
|
runs: resource("seeds.runs.list", "GET", "/v1/seeds/runs", {}, { capability: "seeds.read", pagination: "cursor" }),
|
|
@@ -130,9 +130,9 @@ const SERVICE_PROVIDER_CATALOG = [
|
|
|
130
130
|
{ type: "object-storage", label: "Object storage", description: "R2-backed immutable publication and private artifact storage.", credentialProfileIds: ["cloudflare-storage"], status: "available" }
|
|
131
131
|
],
|
|
132
132
|
credentialProfiles: [
|
|
133
|
-
{ id: "cloudflare-runtime", label: "Pages and Workers token", description: "A token limited to application deployment resources.", capabilities: ["frontend-hosting"], fields: [field("apiToken", "API token", "Encrypted in this browser and used only for authorized frontend operations.", true, true)], permissions: ["Account: Workers Scripts Edit", "Account: Pages Edit"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
|
|
134
|
-
{ id: "cloudflare-dns", label: "DNS token", description: "A token restricted to selected zones.", capabilities: ["dns-management"], fields: [field("apiToken", "DNS API token", "Encrypted separately from deployment authority.", true, true)], permissions: ["Zone: DNS Edit for only the managed zones"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
|
|
135
|
-
{ id: "cloudflare-storage", label: "Storage authority", description: "Vault-custodied R2 management and S3-compatible state credentials, isolated from runtime and DNS authority.", capabilities: ["object-storage"], fields: [field("apiToken", "Storage API token", "Encrypted separately and used only to reconcile authorized R2 resources.", true, true), field("accessKeyId", "R2 access key ID", "Vault-custodied S3-compatible access key identifier for encrypted OpenTofu state.", true, true), field("secretAccessKey", "R2 secret access key", "Vault-custodied S3-compatible secret key for encrypted OpenTofu state.", true, true)], permissions: ["Account: Workers R2 Storage Edit", "Object read and write for only the managed state bucket"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] }
|
|
133
|
+
{ id: "cloudflare-runtime", label: "Pages and Workers token", description: "A token limited to application deployment resources.", capabilities: ["frontend-hosting"], fields: [field("apiToken", "API token", "Encrypted in this browser and used only for authorized frontend operations.", true, true)], permissions: ["Account: Workers Scripts Edit", "Account: Pages Edit"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
|
|
134
|
+
{ id: "cloudflare-dns", label: "DNS token", description: "A token restricted to selected zones.", capabilities: ["dns-management"], fields: [field("apiToken", "DNS API token", "Encrypted separately from deployment authority.", true, true)], permissions: ["Zone: DNS Edit for only the managed zones"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
|
|
135
|
+
{ id: "cloudflare-storage", label: "Storage authority", description: "Vault-custodied R2 management and S3-compatible state credentials, isolated from runtime and DNS authority.", capabilities: ["object-storage"], fields: [field("apiToken", "Storage API token", "Encrypted separately and used only to reconcile authorized R2 resources.", true, true), field("accessKeyId", "R2 access key ID", "Vault-custodied S3-compatible access key identifier for encrypted OpenTofu state.", true, true), field("secretAccessKey", "R2 secret access key", "Vault-custodied S3-compatible secret key for encrypted OpenTofu state.", true, true), field("stateEncryptionKey", "OpenTofu state encryption key", "Generated in the browser and encrypted separately; never store this key with the R2 state object.", true, true)], permissions: ["Account: Workers R2 Storage Edit", "Object read and write for only the managed state bucket"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] }
|
|
136
136
|
]
|
|
137
137
|
},
|
|
138
138
|
{
|
|
@@ -163,7 +163,7 @@ const SERVICE_PROVIDER_CATALOG = [
|
|
|
163
163
|
permissions: ["Workspace access required by the selected operations"],
|
|
164
164
|
sharing: "provider-shared",
|
|
165
165
|
unattendedCompatible: true,
|
|
166
|
-
authoritySchemes: ["environment-reference", "external-vault", "workload-identity"],
|
|
166
|
+
authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"],
|
|
167
167
|
knowledgePageIds: ["provider.railway", "services.credentials", "vault.rotation"]
|
|
168
168
|
}]
|
|
169
169
|
},
|
|
@@ -2,6 +2,9 @@ export declare const SERVICE_VAULT_ENCRYPTION_VERSION: "service-vault-v1";
|
|
|
2
2
|
export declare const SERVICE_VAULT_AEAD_ALGORITHM: "xchacha20-poly1305-ietf";
|
|
3
3
|
export declare const SERVICE_VAULT_KEY_AGREEMENT: "x25519-sealed-box";
|
|
4
4
|
export declare const SERVICE_VAULT_KDF: "argon2id";
|
|
5
|
+
export declare const SECRET_OPERATION_PURPOSES: readonly ["provider-connection-validation", "remote-git-publication", "workflow-dispatch", "workflow-configuration", "hosted-topology-plan", "hosted-topology-apply", "hosted-topology-readback", "hosted-topology-rollback"];
|
|
6
|
+
export type SecretOperationPurpose = (typeof SECRET_OPERATION_PURPOSES)[number];
|
|
7
|
+
export type HostedSecretOperationPurpose = Extract<SecretOperationPurpose, `hosted-topology-${string}`>;
|
|
5
8
|
export type EncryptedCredentialEnvelope = {
|
|
6
9
|
version: typeof SERVICE_VAULT_ENCRYPTION_VERSION;
|
|
7
10
|
algorithm: typeof SERVICE_VAULT_AEAD_ALGORITHM;
|
|
@@ -37,7 +40,7 @@ export type SecretOperationLease = {
|
|
|
37
40
|
teamId: string;
|
|
38
41
|
connectionId: string;
|
|
39
42
|
capabilityType: string;
|
|
40
|
-
purpose:
|
|
43
|
+
purpose: SecretOperationPurpose;
|
|
41
44
|
resourceScope: Record<string, string>;
|
|
42
45
|
credentialProfileId: string;
|
|
43
46
|
actorUserId: string;
|
|
@@ -47,6 +50,47 @@ export type SecretOperationLease = {
|
|
|
47
50
|
expiresAt: string;
|
|
48
51
|
consumedAt?: string | null;
|
|
49
52
|
operationCorrelationId: string;
|
|
53
|
+
hostedBinding?: HostedSecretOperationBinding;
|
|
54
|
+
authorityRequests?: SecretOperationAuthorityRequest[];
|
|
55
|
+
};
|
|
56
|
+
export type HostedSecretOperationBinding = {
|
|
57
|
+
subjectType: 'declaration' | 'plan' | 'rollback';
|
|
58
|
+
subjectDigest: string;
|
|
59
|
+
deploymentId: string;
|
|
60
|
+
stackId: string;
|
|
61
|
+
environment: 'staging' | 'production';
|
|
62
|
+
};
|
|
63
|
+
export type SecretOperationAuthorityRequest = {
|
|
64
|
+
requestId: string;
|
|
65
|
+
connectionId: string;
|
|
66
|
+
credentialProfileId: string;
|
|
67
|
+
provider: 'cloudflare' | 'railway' | 'treeseed';
|
|
68
|
+
purpose: 'provider' | 'state-backend' | 'state-encryption';
|
|
69
|
+
capabilities: string[];
|
|
70
|
+
requiredFields: string[];
|
|
71
|
+
secretRef?: string;
|
|
72
|
+
};
|
|
73
|
+
export type SealedSecretOperationPayload = {
|
|
74
|
+
schemaVersion: 'treeseed.sealed-secret-operation-payload/v1';
|
|
75
|
+
leaseId: string;
|
|
76
|
+
teamId: string;
|
|
77
|
+
operationCorrelationId: string;
|
|
78
|
+
hostedBinding: HostedSecretOperationBinding;
|
|
79
|
+
algorithm: typeof SERVICE_VAULT_KEY_AGREEMENT;
|
|
80
|
+
ciphertext: string;
|
|
81
|
+
};
|
|
82
|
+
export type SecretOperationCredentialBundle = {
|
|
83
|
+
schemaVersion: 'treeseed.secret-operation-credential-bundle/v1';
|
|
84
|
+
leaseId: string;
|
|
85
|
+
teamId: string;
|
|
86
|
+
operationCorrelationId: string;
|
|
87
|
+
hostedBinding: HostedSecretOperationBinding;
|
|
88
|
+
materials: Array<{
|
|
89
|
+
requestId: string;
|
|
90
|
+
connectionId: string;
|
|
91
|
+
credentialProfileId: string;
|
|
92
|
+
values: Record<string, string>;
|
|
93
|
+
}>;
|
|
50
94
|
};
|
|
51
95
|
export type ServiceVaultAssociatedData = {
|
|
52
96
|
teamId: string;
|
|
@@ -58,4 +102,7 @@ export type ServiceVaultAssociatedData = {
|
|
|
58
102
|
};
|
|
59
103
|
export declare function containsForbiddenPlaintextSecretMaterial(value: unknown, path?: string): string[];
|
|
60
104
|
export declare function canonicalServiceVaultAssociatedData(input: ServiceVaultAssociatedData): string;
|
|
105
|
+
export declare function canonicalHostedSecretOperationBinding(input: HostedSecretOperationBinding): string;
|
|
106
|
+
export declare function validateHostedSecretOperationBinding(value: unknown): value is HostedSecretOperationBinding;
|
|
107
|
+
export declare function validateSealedSecretOperationPayload(value: unknown): value is SealedSecretOperationPayload;
|
|
61
108
|
export declare function validateEncryptedCredentialEnvelope(value: unknown): value is EncryptedCredentialEnvelope;
|
|
@@ -2,6 +2,16 @@ const SERVICE_VAULT_ENCRYPTION_VERSION = "service-vault-v1";
|
|
|
2
2
|
const SERVICE_VAULT_AEAD_ALGORITHM = "xchacha20-poly1305-ietf";
|
|
3
3
|
const SERVICE_VAULT_KEY_AGREEMENT = "x25519-sealed-box";
|
|
4
4
|
const SERVICE_VAULT_KDF = "argon2id";
|
|
5
|
+
const SECRET_OPERATION_PURPOSES = [
|
|
6
|
+
"provider-connection-validation",
|
|
7
|
+
"remote-git-publication",
|
|
8
|
+
"workflow-dispatch",
|
|
9
|
+
"workflow-configuration",
|
|
10
|
+
"hosted-topology-plan",
|
|
11
|
+
"hosted-topology-apply",
|
|
12
|
+
"hosted-topology-readback",
|
|
13
|
+
"hosted-topology-rollback"
|
|
14
|
+
];
|
|
5
15
|
const FORBIDDEN_SECRET_KEYS = /(?:passphrase|password|plaintext|derivedKey|privateKey|apiToken|accessToken|secretValue|credentialValue)$/iu;
|
|
6
16
|
function containsForbiddenPlaintextSecretMaterial(value, path = "") {
|
|
7
17
|
if (!value || typeof value !== "object") return [];
|
|
@@ -23,17 +33,42 @@ function canonicalServiceVaultAssociatedData(input) {
|
|
|
23
33
|
version: input.version
|
|
24
34
|
});
|
|
25
35
|
}
|
|
36
|
+
const digest = /^sha256:[a-f0-9]{64}$/u;
|
|
37
|
+
const identifier = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;
|
|
38
|
+
function canonicalHostedSecretOperationBinding(input) {
|
|
39
|
+
return JSON.stringify({
|
|
40
|
+
subjectType: input.subjectType,
|
|
41
|
+
subjectDigest: input.subjectDigest,
|
|
42
|
+
deploymentId: input.deploymentId,
|
|
43
|
+
stackId: input.stackId,
|
|
44
|
+
environment: input.environment
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function validateHostedSecretOperationBinding(value) {
|
|
48
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
49
|
+
const binding = value;
|
|
50
|
+
return ["declaration", "plan", "rollback"].includes(String(binding.subjectType)) && digest.test(String(binding.subjectDigest)) && identifier.test(String(binding.deploymentId)) && identifier.test(String(binding.stackId)) && ["staging", "production"].includes(String(binding.environment));
|
|
51
|
+
}
|
|
52
|
+
function validateSealedSecretOperationPayload(value) {
|
|
53
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
54
|
+
const payload = value;
|
|
55
|
+
return payload.schemaVersion === "treeseed.sealed-secret-operation-payload/v1" && payload.algorithm === SERVICE_VAULT_KEY_AGREEMENT && [payload.leaseId, payload.teamId, payload.operationCorrelationId, payload.ciphertext].every((field) => typeof field === "string" && field.length > 0) && validateHostedSecretOperationBinding(payload.hostedBinding);
|
|
56
|
+
}
|
|
26
57
|
function validateEncryptedCredentialEnvelope(value) {
|
|
27
58
|
if (!value || typeof value !== "object") return false;
|
|
28
59
|
const envelope = value;
|
|
29
60
|
return envelope.version === SERVICE_VAULT_ENCRYPTION_VERSION && envelope.algorithm === SERVICE_VAULT_AEAD_ALGORITHM && [envelope.ciphertext, envelope.nonce, envelope.wrappedKey, envelope.wrappedKeyNonce, envelope.associatedData, envelope.associatedDataDigest, envelope.fingerprint].every((field) => typeof field === "string" && field.length > 0);
|
|
30
61
|
}
|
|
31
62
|
export {
|
|
63
|
+
SECRET_OPERATION_PURPOSES,
|
|
32
64
|
SERVICE_VAULT_AEAD_ALGORITHM,
|
|
33
65
|
SERVICE_VAULT_ENCRYPTION_VERSION,
|
|
34
66
|
SERVICE_VAULT_KDF,
|
|
35
67
|
SERVICE_VAULT_KEY_AGREEMENT,
|
|
68
|
+
canonicalHostedSecretOperationBinding,
|
|
36
69
|
canonicalServiceVaultAssociatedData,
|
|
37
70
|
containsForbiddenPlaintextSecretMaterial,
|
|
38
|
-
validateEncryptedCredentialEnvelope
|
|
71
|
+
validateEncryptedCredentialEnvelope,
|
|
72
|
+
validateHostedSecretOperationBinding,
|
|
73
|
+
validateSealedSecretOperationPayload
|
|
39
74
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type EncryptedCredentialEnvelope, type EncryptedPrivateKeyEnvelope, type TeamVaultGrantEnvelope } from '@treeseed/sdk/secrets-capability';
|
|
2
|
+
export declare function createServiceVaultKey(): Promise<Uint8Array>;
|
|
3
|
+
export declare function createServiceVaultUserKeyPair(): Promise<{
|
|
4
|
+
publicKey: string;
|
|
5
|
+
privateKey: Uint8Array;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function encryptServiceVaultPrivateKey(privateKey: Uint8Array, publicKey: string, passphrase: string, options?: {
|
|
8
|
+
opsLimit?: number;
|
|
9
|
+
memLimit?: number;
|
|
10
|
+
}): Promise<EncryptedPrivateKeyEnvelope>;
|
|
11
|
+
export declare function decryptServiceVaultPrivateKey(envelope: EncryptedPrivateKeyEnvelope, passphrase: string): Promise<Uint8Array>;
|
|
12
|
+
export declare function createTeamVaultGrant(teamVaultKey: Uint8Array, recipientPublicKey: string): Promise<TeamVaultGrantEnvelope>;
|
|
13
|
+
export declare function openTeamVaultGrant(grant: TeamVaultGrantEnvelope, recipientPrivateKey: Uint8Array): Promise<Uint8Array>;
|
|
14
|
+
export declare function encryptServiceCredential(plaintext: string, teamVaultKey: Uint8Array, associatedData: string): Promise<EncryptedCredentialEnvelope>;
|
|
15
|
+
export declare function decryptServiceCredential(envelope: EncryptedCredentialEnvelope, teamVaultKey: Uint8Array, expectedAssociatedData: string): Promise<string>;
|
|
16
|
+
export declare function rewrapServiceCredential(envelope: EncryptedCredentialEnvelope, currentTeamVaultKey: Uint8Array, replacementTeamVaultKey: Uint8Array): Promise<EncryptedCredentialEnvelope>;
|
|
17
|
+
export declare function sealSecretOperationPayload(values: Record<string, string>, operationPublicKey: string): Promise<string>;
|
|
18
|
+
export declare function encryptGitHubActionsSecret(value: string, providerPublicKey: string): Promise<string>;
|
|
19
|
+
export declare function openSecretOperationPayload(sealedPayload: string, operationPublicKey: string, operationPrivateKey: Uint8Array): Promise<Record<string, string>>;
|
|
20
|
+
export declare function clearServiceVaultKey(value: Uint8Array | undefined): void;
|