@treeseed/sdk 0.13.0-rc.83 → 0.13.0-rc.85

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.
@@ -1 +1 @@
1
- {"completedAt":"2026-09-03T07:04:23.401Z"}
1
+ {"completedAt":"2026-09-03T08:31:01.823Z"}
@@ -59,92 +59,8 @@ export declare const HOSTED_TOPOLOGY_OPERATIONS: {
59
59
  connectionRef: string;
60
60
  }>>;
61
61
  };
62
- }, {
63
- schemaVersion: "treeseed.hosted-topology-plan/v1";
64
- blockers: {
65
- code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
66
- message: string;
67
- resourceId?: string | undefined;
68
- }[];
69
- planDigest: string;
70
- actions: {
71
- action: "noop" | "create" | "adopt" | "update";
72
- resourceId: string;
73
- kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
74
- provider: "cloudflare" | "railway";
75
- providerResourceId: string | null;
76
- desiredResource: {
77
- id: string;
78
- kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
79
- provider: "cloudflare" | "railway";
80
- adoption: {
81
- mode: "adopt-or-create";
82
- replacement: "forbidden";
83
- externalIdInput?: string | undefined;
84
- };
85
- dependsOn?: string[] | undefined;
86
- parameters?: Record<string, {
87
- input: string;
88
- } | {
89
- artifact: string;
90
- } | {
91
- resourceOutput: {
92
- resourceId: string;
93
- output: string;
94
- };
95
- } | {
96
- literal: string | number | boolean;
97
- }> | undefined;
98
- };
99
- desiredDigest: string;
100
- previousDigest: string | null;
101
- }[];
102
- teamId: string;
103
- environment: "production" | "staging";
104
- executable: false;
105
- artifacts: Record<string, {
106
- digest: string;
107
- source: string;
108
- kind: "archive";
109
- format: "tar+gzip";
110
- } | {
111
- digest: string;
112
- source: string;
113
- kind: "file";
114
- mediaType: string;
115
- } | {
116
- digest: string;
117
- kind: "oci-image";
118
- identity: string;
119
- }>;
120
- planId: string;
121
- deploymentId: string;
122
- stackId: string;
123
- stateBackend: {
124
- key: string;
125
- type: "s3";
126
- schemaVersion: "treeseed.hosted-state-backend/v1";
127
- teamId: string;
128
- environment: "production" | "staging";
129
- deploymentId: string;
130
- stackId: string;
131
- connectionRef: string;
132
- bucket: string;
133
- region: string;
134
- encryptionKeyRef: string;
135
- bindingDigest: string;
136
- endpoint?: string | undefined;
137
- usePathStyle?: boolean | undefined;
138
- } | null;
139
- providerConnections: Partial<Record<"cloudflare" | "railway", {
140
- connectionRef: string;
141
- nonSecretConfig: Record<string, string | number | boolean>;
142
- }>>;
143
- declarationDigest: string;
144
- topologyId: string;
145
- platformCommit: string;
146
- approvalRequired: boolean;
147
- }>;
62
+ credentialLeaseIds?: string[] | undefined;
63
+ }, Record<string, unknown>>;
148
64
  readonly apply: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
149
65
  teamId: string;
150
66
  }, {}, {
@@ -246,6 +162,7 @@ export declare const HOSTED_TOPOLOGY_OPERATIONS: {
246
162
  platformCommit: string;
247
163
  approvalRequired: boolean;
248
164
  };
165
+ credentialLeaseIds?: string[] | undefined;
249
166
  }, Record<string, unknown>>;
250
167
  readonly status: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
251
168
  teamId: string;
@@ -290,34 +207,220 @@ export declare const HOSTED_TOPOLOGY_OPERATIONS: {
290
207
  readonly rollback: import("../control-plane-operation.js").ControlPlaneOperationBinding<{
291
208
  teamId: string;
292
209
  }, {}, {
293
- rollback: {
294
- schemaVersion: "treeseed.hosted-topology-rollback/v1";
210
+ approval: {
211
+ schemaVersion: "treeseed.hosted-topology-rollback-execution-approval/v1";
295
212
  teamId: string;
296
213
  environment: "production" | "staging";
297
- operations: {
298
- action: "noop" | "restore" | "delete-created";
299
- resourceId: string;
300
- providerResourceId: string;
301
- targetDigest: string | null;
302
- }[];
303
214
  deploymentId: string;
304
215
  stackId: string;
305
216
  backendBindingDigest: string;
306
- rollbackId: string;
307
- sourceReceiptId: string;
308
- rollbackDigest: string;
217
+ decision: "approved";
218
+ approvedBy: string;
219
+ approvedAt: string;
220
+ executionDigest: string;
309
221
  };
310
- approval: {
311
- schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
222
+ execution: {
223
+ schemaVersion: "treeseed.hosted-topology-rollback-execution/v1";
312
224
  teamId: string;
313
225
  environment: "production" | "staging";
226
+ rollback: {
227
+ schemaVersion: "treeseed.hosted-topology-rollback/v1";
228
+ teamId: string;
229
+ environment: "production" | "staging";
230
+ operations: {
231
+ action: "noop" | "restore" | "delete-created";
232
+ resourceId: string;
233
+ providerResourceId: string;
234
+ targetDigest: string | null;
235
+ }[];
236
+ deploymentId: string;
237
+ stackId: string;
238
+ backendBindingDigest: string;
239
+ rollbackId: string;
240
+ sourceReceiptId: string;
241
+ rollbackDigest: string;
242
+ };
314
243
  deploymentId: string;
315
244
  stackId: string;
245
+ topologyId: string;
316
246
  backendBindingDigest: string;
317
- decision: "approved";
318
- approvedBy: string;
319
- approvedAt: string;
320
- rollbackDigest: string;
247
+ sourceReceiptId: string;
248
+ sourcePlanDigest: string;
249
+ targetPlanDigest: string;
250
+ executionDigest: string;
251
+ };
252
+ sourcePlan: {
253
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
254
+ blockers: {
255
+ code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
256
+ message: string;
257
+ resourceId?: string | undefined;
258
+ }[];
259
+ planDigest: string;
260
+ actions: {
261
+ action: "noop" | "create" | "adopt" | "update";
262
+ resourceId: string;
263
+ kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
264
+ provider: "cloudflare" | "railway";
265
+ providerResourceId: string | null;
266
+ desiredResource: {
267
+ id: string;
268
+ kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
269
+ provider: "cloudflare" | "railway";
270
+ adoption: {
271
+ mode: "adopt-or-create";
272
+ replacement: "forbidden";
273
+ externalIdInput?: string | undefined;
274
+ };
275
+ dependsOn?: string[] | undefined;
276
+ parameters?: Record<string, {
277
+ input: string;
278
+ } | {
279
+ artifact: string;
280
+ } | {
281
+ resourceOutput: {
282
+ resourceId: string;
283
+ output: string;
284
+ };
285
+ } | {
286
+ literal: string | number | boolean;
287
+ }> | undefined;
288
+ };
289
+ desiredDigest: string;
290
+ previousDigest: string | null;
291
+ }[];
292
+ teamId: string;
293
+ environment: "production" | "staging";
294
+ executable: false;
295
+ artifacts: Record<string, {
296
+ digest: string;
297
+ source: string;
298
+ kind: "archive";
299
+ format: "tar+gzip";
300
+ } | {
301
+ digest: string;
302
+ source: string;
303
+ kind: "file";
304
+ mediaType: string;
305
+ } | {
306
+ digest: string;
307
+ kind: "oci-image";
308
+ identity: string;
309
+ }>;
310
+ planId: string;
311
+ deploymentId: string;
312
+ stackId: string;
313
+ stateBackend: {
314
+ key: string;
315
+ type: "s3";
316
+ schemaVersion: "treeseed.hosted-state-backend/v1";
317
+ teamId: string;
318
+ environment: "production" | "staging";
319
+ deploymentId: string;
320
+ stackId: string;
321
+ connectionRef: string;
322
+ bucket: string;
323
+ region: string;
324
+ encryptionKeyRef: string;
325
+ bindingDigest: string;
326
+ endpoint?: string | undefined;
327
+ usePathStyle?: boolean | undefined;
328
+ } | null;
329
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
330
+ connectionRef: string;
331
+ nonSecretConfig: Record<string, string | number | boolean>;
332
+ }>>;
333
+ declarationDigest: string;
334
+ topologyId: string;
335
+ platformCommit: string;
336
+ approvalRequired: boolean;
337
+ };
338
+ targetPlan: {
339
+ schemaVersion: "treeseed.hosted-topology-plan/v1";
340
+ blockers: {
341
+ code: "connection-unavailable" | "state-backend-unavailable" | "dependency-cycle" | "observation-unhealthy" | "adoption-drift";
342
+ message: string;
343
+ resourceId?: string | undefined;
344
+ }[];
345
+ planDigest: string;
346
+ actions: {
347
+ action: "noop" | "create" | "adopt" | "update";
348
+ resourceId: string;
349
+ kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
350
+ provider: "cloudflare" | "railway";
351
+ providerResourceId: string | null;
352
+ desiredResource: {
353
+ id: string;
354
+ kind: "admin-application" | "pages-application" | "dns-record" | "tls-policy" | "api-proxy" | "control-plane-api" | "postgresql" | "operations-runner" | "treedx-service";
355
+ provider: "cloudflare" | "railway";
356
+ adoption: {
357
+ mode: "adopt-or-create";
358
+ replacement: "forbidden";
359
+ externalIdInput?: string | undefined;
360
+ };
361
+ dependsOn?: string[] | undefined;
362
+ parameters?: Record<string, {
363
+ input: string;
364
+ } | {
365
+ artifact: string;
366
+ } | {
367
+ resourceOutput: {
368
+ resourceId: string;
369
+ output: string;
370
+ };
371
+ } | {
372
+ literal: string | number | boolean;
373
+ }> | undefined;
374
+ };
375
+ desiredDigest: string;
376
+ previousDigest: string | null;
377
+ }[];
378
+ teamId: string;
379
+ environment: "production" | "staging";
380
+ executable: false;
381
+ artifacts: Record<string, {
382
+ digest: string;
383
+ source: string;
384
+ kind: "archive";
385
+ format: "tar+gzip";
386
+ } | {
387
+ digest: string;
388
+ source: string;
389
+ kind: "file";
390
+ mediaType: string;
391
+ } | {
392
+ digest: string;
393
+ kind: "oci-image";
394
+ identity: string;
395
+ }>;
396
+ planId: string;
397
+ deploymentId: string;
398
+ stackId: string;
399
+ stateBackend: {
400
+ key: string;
401
+ type: "s3";
402
+ schemaVersion: "treeseed.hosted-state-backend/v1";
403
+ teamId: string;
404
+ environment: "production" | "staging";
405
+ deploymentId: string;
406
+ stackId: string;
407
+ connectionRef: string;
408
+ bucket: string;
409
+ region: string;
410
+ encryptionKeyRef: string;
411
+ bindingDigest: string;
412
+ endpoint?: string | undefined;
413
+ usePathStyle?: boolean | undefined;
414
+ } | null;
415
+ providerConnections: Partial<Record<"cloudflare" | "railway", {
416
+ connectionRef: string;
417
+ nonSecretConfig: Record<string, string | number | boolean>;
418
+ }>>;
419
+ declarationDigest: string;
420
+ topologyId: string;
421
+ platformCommit: string;
422
+ approvalRequired: boolean;
321
423
  };
424
+ credentialLeaseIds?: string[] | undefined;
322
425
  }, Record<string, unknown>>;
323
426
  };
@@ -1,10 +1,11 @@
1
1
  import { z } from "zod";
2
- import { hostedTopologyApprovalSchema, hostedTopologyDeclarationSchema, hostedTopologyPlanSchema, hostedTopologyReceiptSchema, hostedTopologyRollbackApprovalSchema, hostedTopologyRollbackSchema } from "../../deployment/hosted-topology.js";
2
+ import { hostedTopologyApprovalSchema, hostedTopologyDeclarationSchema, hostedTopologyPlanSchema, hostedTopologyReceiptSchema, hostedTopologyRollbackExecutionApprovalSchema, hostedTopologyRollbackExecutionSchema } from "../../deployment/hosted-topology.js";
3
3
  import { defineOperation } from "../operation-builder.js";
4
4
  const teamPath = z.object({ teamId: z.string().min(1) }).strict();
5
5
  const empty = z.object({}).strict();
6
6
  const none = z.undefined();
7
7
  const operationReceipt = z.record(z.unknown());
8
+ const credentialLeaseIds = z.array(z.string().min(1)).min(1).optional();
8
9
  const HOSTED_TOPOLOGY_OPERATIONS = {
9
10
  plan: defineOperation({
10
11
  operationId: "infrastructure.topology.plan",
@@ -21,7 +22,7 @@ const HOSTED_TOPOLOGY_OPERATIONS = {
21
22
  cacheScope: "none",
22
23
  pagination: "none",
23
24
  idempotencyRequired: false
24
- }, { path: teamPath, query: empty, body: z.object({ declaration: hostedTopologyDeclarationSchema }).strict(), output: hostedTopologyPlanSchema }),
25
+ }, { path: teamPath, query: empty, body: z.object({ declaration: hostedTopologyDeclarationSchema, credentialLeaseIds }).strict(), output: operationReceipt }),
25
26
  apply: defineOperation({
26
27
  operationId: "infrastructure.topology.apply",
27
28
  description: "Apply an exact approved hosted topology plan through the operations runner.",
@@ -38,7 +39,7 @@ const HOSTED_TOPOLOGY_OPERATIONS = {
38
39
  pagination: "none",
39
40
  concurrencyRequired: true,
40
41
  redactedPaths: ["body.approval.approvedBy"]
41
- }, { path: teamPath, query: empty, body: z.object({ plan: hostedTopologyPlanSchema, approval: hostedTopologyApprovalSchema }).strict(), output: operationReceipt }),
42
+ }, { path: teamPath, query: empty, body: z.object({ plan: hostedTopologyPlanSchema, approval: hostedTopologyApprovalSchema, credentialLeaseIds }).strict(), output: operationReceipt }),
42
43
  status: defineOperation({
43
44
  operationId: "infrastructure.topology.status",
44
45
  description: "Read the latest authoritative hosted topology receipt and operation state.",
@@ -70,7 +71,13 @@ const HOSTED_TOPOLOGY_OPERATIONS = {
70
71
  pagination: "none",
71
72
  concurrencyRequired: true,
72
73
  redactedPaths: ["body.approval.approvedBy"]
73
- }, { path: teamPath, query: empty, body: z.object({ rollback: hostedTopologyRollbackSchema, approval: hostedTopologyRollbackApprovalSchema }).strict(), output: operationReceipt })
74
+ }, { path: teamPath, query: empty, body: z.object({
75
+ execution: hostedTopologyRollbackExecutionSchema,
76
+ approval: hostedTopologyRollbackExecutionApprovalSchema,
77
+ sourcePlan: hostedTopologyPlanSchema,
78
+ targetPlan: hostedTopologyPlanSchema,
79
+ credentialLeaseIds
80
+ }).strict(), output: operationReceipt })
74
81
  };
75
82
  export {
76
83
  HOSTED_TOPOLOGY_OPERATIONS
@@ -1,17 +1,17 @@
1
1
  export declare const SERVICE_VAULT_OPERATIONS: {
2
- readonly userVaultKey: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
3
- readonly putUserVaultKey: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
4
- readonly teamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
5
- readonly initializeTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
6
- readonly resetTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
7
- readonly rotateTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
8
- readonly vaultGrantCandidates: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
9
- readonly createVaultGrant: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
10
- readonly deleteVaultGrant: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
11
- readonly vaultCredentialEnvelopes: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
12
- readonly credentialEnvelopes: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
13
- readonly putCredentialEnvelope: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
14
- readonly createOperationLease: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
15
- readonly operationLease: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
16
- readonly putOperationLeasePayload: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
2
+ readonly userVaultKey: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
3
+ readonly putUserVaultKey: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
4
+ readonly teamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
5
+ readonly initializeTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
6
+ readonly resetTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
7
+ readonly rotateTeamVault: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
8
+ readonly vaultGrantCandidates: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
9
+ readonly createVaultGrant: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
10
+ readonly deleteVaultGrant: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
11
+ readonly vaultCredentialEnvelopes: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
12
+ readonly credentialEnvelopes: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
13
+ readonly putCredentialEnvelope: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
14
+ readonly createOperationLease: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
15
+ readonly operationLease: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
16
+ readonly putOperationLeasePayload: import("../../control-plane-operation.js").ControlPlaneOperationBinding<any, {}, any, any>;
17
17
  };
@@ -21,46 +21,70 @@ function vaultOperation(operationId, method, path, pathSchema, options = {}) {
21
21
  cacheScope: read ? "principal" : "none",
22
22
  pagination: "none",
23
23
  redactedPaths: options.redactedPaths
24
- }, { path: pathSchema, query: read ? record : empty, body: read ? none : record, output: record });
24
+ }, { path: pathSchema, query: read ? record : empty, body: read ? none : options.body ?? record, output: options.output ?? record });
25
25
  }
26
+ const nullableRecord = record.nullable(), records = z.array(record);
27
+ const encryptedPrivateKeyEnvelope = z.object({
28
+ version: z.literal("service-vault-v1"),
29
+ algorithm: z.literal("xchacha20-poly1305-ietf"),
30
+ kdf: z.object({ algorithm: z.literal("argon2id"), opsLimit: z.number().int().positive(), memLimit: z.number().int().positive(), salt: z.string().min(1) }).strict(),
31
+ nonce: z.string().min(1),
32
+ ciphertext: z.string().min(1),
33
+ publicKey: z.string().min(1)
34
+ }).strict();
35
+ const encryptedCredentialEnvelope = z.object({
36
+ version: z.literal("service-vault-v1"),
37
+ algorithm: z.literal("xchacha20-poly1305-ietf"),
38
+ ciphertext: z.string().min(1),
39
+ nonce: z.string().min(1),
40
+ wrappedKey: z.string().min(1),
41
+ wrappedKeyNonce: z.string().min(1),
42
+ associatedData: z.string().min(1),
43
+ associatedDataDigest: z.string().min(1),
44
+ fingerprint: z.string().min(1)
45
+ }).strict();
26
46
  const SERVICE_VAULT_OPERATIONS = {
27
- userVaultKey: vaultOperation("services.vault.user.key.show", "GET", "/v1/users/me/vault-key", empty),
47
+ userVaultKey: vaultOperation("services.vault.user.key.show", "GET", "/v1/users/me/vault-key", empty, { output: nullableRecord }),
28
48
  putUserVaultKey: vaultOperation(
29
49
  "services.vault.user.key.put",
30
50
  "PUT",
31
51
  "/v1/users/me/vault-key",
32
52
  empty,
33
- { risk: "credential", redactedPaths: ["body.encryptedPrivateKeyEnvelope"] }
53
+ { risk: "credential", redactedPaths: ["body.encryptedPrivateKeyEnvelope"], body: z.object({ publicKey: z.string().min(1), encryptedPrivateKeyEnvelope }).strict() }
34
54
  ),
35
- teamVault: vaultOperation("services.vault.team.show", "GET", "/v1/teams/{teamId}/vault", teamPath),
55
+ teamVault: vaultOperation("services.vault.team.show", "GET", "/v1/teams/{teamId}/vault", teamPath, { output: nullableRecord }),
36
56
  initializeTeamVault: vaultOperation(
37
57
  "services.vault.team.initialize",
38
58
  "POST",
39
59
  "/v1/teams/{teamId}/vault",
40
60
  teamPath,
41
- { risk: "credential", redactedPaths: ["body.wrappedTeamVaultKey"] }
61
+ { risk: "credential", redactedPaths: ["body.wrappedTeamVaultKey"], body: z.object({ userVaultKeyId: z.string().min(1), wrappedTeamVaultKey: z.string().min(1), encryptionVersion: z.literal("service-vault-v1") }).strict() }
42
62
  ),
43
63
  resetTeamVault: vaultOperation(
44
64
  "services.vault.team.reset",
45
65
  "POST",
46
66
  "/v1/teams/{teamId}/vault/reset",
47
67
  teamPath,
48
- { risk: "destructive", redactedPaths: ["body.wrappedTeamVaultKey", "body.currentPassword"] }
68
+ { risk: "destructive", redactedPaths: ["body.wrappedTeamVaultKey", "body.currentPassword"], body: z.object({ userVaultKeyId: z.string().min(1), wrappedTeamVaultKey: z.string().min(1), encryptionVersion: z.literal("service-vault-v1"), confirmation: z.string().min(1), currentPassword: z.string().min(1) }).strict() }
49
69
  ),
50
70
  rotateTeamVault: vaultOperation(
51
71
  "services.vault.team.rotate",
52
72
  "POST",
53
73
  "/v1/teams/{teamId}/vault/rotate",
54
74
  teamPath,
55
- { risk: "credential", redactedPaths: ["body.envelopes", "body.grants"] }
75
+ { risk: "credential", redactedPaths: ["body.envelopes", "body.grants"], body: z.object({
76
+ expectedKeyVersion: z.number().int().positive(),
77
+ envelopes: z.array(z.object({ id: z.string().min(1), envelope: encryptedCredentialEnvelope }).strict()),
78
+ grants: z.array(z.object({ userId: z.string().min(1), userVaultKeyId: z.string().min(1), wrappedTeamVaultKey: z.string().min(1) }).strict()).min(1)
79
+ }).strict() }
56
80
  ),
57
- vaultGrantCandidates: vaultOperation("services.vault.grant.candidates.list", "GET", "/v1/teams/{teamId}/vault/grant-candidates", teamPath),
81
+ vaultGrantCandidates: vaultOperation("services.vault.grant.candidates.list", "GET", "/v1/teams/{teamId}/vault/grant-candidates", teamPath, { output: records }),
58
82
  createVaultGrant: vaultOperation(
59
83
  "services.vault.grants.create",
60
84
  "POST",
61
85
  "/v1/teams/{teamId}/vault/grants",
62
86
  teamPath,
63
- { risk: "credential", redactedPaths: ["body.wrappedTeamVaultKey"] }
87
+ { risk: "credential", redactedPaths: ["body.wrappedTeamVaultKey"], body: z.object({ userId: z.string().min(1), userVaultKeyId: z.string().min(1), wrappedTeamVaultKey: z.string().min(1) }).strict() }
64
88
  ),
65
89
  deleteVaultGrant: vaultOperation(
66
90
  "services.vault.grants.delete",
@@ -73,27 +97,47 @@ const SERVICE_VAULT_OPERATIONS = {
73
97
  "services.vault.credential.envelopes.list",
74
98
  "GET",
75
99
  "/v1/teams/{teamId}/vault/credential-envelopes",
76
- teamPath
100
+ teamPath,
101
+ { output: records }
77
102
  ),
78
103
  credentialEnvelopes: vaultOperation(
79
104
  "services.credential.envelopes.list",
80
105
  "GET",
81
106
  "/v1/teams/{teamId}/services/{connectionId}/credential-envelopes",
82
- z.object({ teamId: z.string().min(1), connectionId: z.string().min(1) }).strict()
107
+ z.object({ teamId: z.string().min(1), connectionId: z.string().min(1) }).strict(),
108
+ { output: records }
83
109
  ),
84
110
  putCredentialEnvelope: vaultOperation(
85
111
  "services.credential.envelopes.put",
86
112
  "POST",
87
113
  "/v1/teams/{teamId}/services/{connectionId}/credential-envelopes",
88
114
  z.object({ teamId: z.string().min(1), connectionId: z.string().min(1) }).strict(),
89
- { risk: "credential", redactedPaths: ["body.envelope"] }
115
+ { risk: "credential", redactedPaths: ["body.envelope"], body: z.object({ definitionId: z.string().min(1), fieldKey: z.string().min(1), keyVersion: z.number().int().positive(), envelope: encryptedCredentialEnvelope }).strict() }
90
116
  ),
91
117
  createOperationLease: vaultOperation(
92
118
  "services.operation.leases.create",
93
119
  "POST",
94
120
  "/v1/teams/{teamId}/service-operation-leases",
95
121
  teamPath,
96
- { risk: "authority" }
122
+ { risk: "authority", body: z.object({
123
+ connectionId: z.string().min(1),
124
+ capabilityType: z.string().min(1),
125
+ credentialProfileId: z.string().min(1),
126
+ purpose: z.enum([
127
+ "provider-connection-validation",
128
+ "remote-git-publication",
129
+ "workflow-dispatch",
130
+ "workflow-configuration",
131
+ "hosted-topology-plan",
132
+ "hosted-topology-apply",
133
+ "hosted-topology-readback",
134
+ "hosted-topology-rollback"
135
+ ]),
136
+ idempotencyKey: z.string().min(1).optional(),
137
+ resourceScope: record.optional(),
138
+ hostedBinding: record.optional(),
139
+ authorityRequests: z.array(record).optional()
140
+ }).strict() }
97
141
  ),
98
142
  operationLease: vaultOperation(
99
143
  "services.operation.leases.show",
@@ -106,7 +150,7 @@ const SERVICE_VAULT_OPERATIONS = {
106
150
  "PUT",
107
151
  "/v1/teams/{teamId}/service-operation-leases/{leaseId}/payload",
108
152
  z.object({ teamId: z.string().min(1), leaseId: z.string().min(1) }).strict(),
109
- { risk: "credential", redactedPaths: ["body.sealedPayload"] }
153
+ { risk: "credential", redactedPaths: ["body.sealedPayload"], body: z.object({ sealedPayload: z.string().min(1) }).strict() }
110
154
  )
111
155
  };
112
156
  export {
@@ -62,92 +62,8 @@ export declare const CONTROL_PLANE_OPERATIONS: {
62
62
  connectionRef: string;
63
63
  }>>;
64
64
  };
65
- }, {
66
- schemaVersion: "treeseed.hosted-topology-plan/v1";
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
- rollback: {
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
- rollbackId: string;
310
- sourceReceiptId: string;
311
- rollbackDigest: string;
220
+ decision: "approved";
221
+ approvedBy: string;
222
+ approvedAt: string;
223
+ executionDigest: string;
312
224
  };
313
- approval: {
314
- schemaVersion: "treeseed.hosted-topology-rollback-approval/v1";
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
- decision: "approved";
321
- approvedBy: string;
322
- approvedAt: string;
323
- rollbackDigest: string;
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,21 +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>>;
1326
- readonly userVaultKey: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1327
- readonly putUserVaultKey: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1328
- readonly teamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1329
- readonly initializeTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1330
- readonly resetTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1331
- readonly rotateTeamVault: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1332
- readonly vaultGrantCandidates: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1333
- readonly createVaultGrant: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1334
- readonly deleteVaultGrant: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1335
- readonly vaultCredentialEnvelopes: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1336
- readonly credentialEnvelopes: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1337
- readonly putCredentialEnvelope: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1338
- readonly createOperationLease: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1339
- readonly operationLease: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, Record<string, unknown> | undefined, Record<string, unknown>>;
1340
- readonly putOperationLeasePayload: import("./control-plane-operation.js").ControlPlaneOperationBinding<any, {}, 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>;
1341
1444
  };
1342
1445
  readonly agents: {
1343
1446
  readonly list: import("./control-plane-operation.js").ControlPlaneOperationBinding<{
@@ -1,5 +1,5 @@
1
1
  export declare const SERVICE_PROVIDER_IDS: readonly ["github", "cloudflare", "railway", "openbao"];
2
- export declare const SERVICE_CAPABILITY_TYPES: readonly ["repository-hosting", "workflow-execution", "workflow-configuration", "secret-enclave", "frontend-hosting", "backend-hosting", "dns-management", "object-storage", "database-hosting", "capacity-runtime-hosting", "private-knowledge-index-hosting", "artifact-hosting"];
2
+ export declare const SERVICE_CAPABILITY_TYPES: readonly ["repository-hosting", "workflow-execution", "workflow-configuration", "secret-enclave", "frontend-hosting", "backend-hosting", "dns-management", "object-storage", "state-encryption", "database-hosting", "capacity-runtime-hosting", "private-knowledge-index-hosting", "artifact-hosting"];
3
3
  export declare const SERVICE_CONNECTION_STATUSES: readonly ["draft", "active", "degraded", "validation-failed", "reentry-required", "reauthorization-required", "disconnected"];
4
4
  export declare const SERVICE_CAPABILITY_STATUSES: readonly ["configured", "disabled", "blocked", "planned"];
5
5
  export type ServiceProviderId = (typeof SERVICE_PROVIDER_IDS)[number];
@@ -8,6 +8,7 @@ const SERVICE_CAPABILITY_TYPES = [
8
8
  "backend-hosting",
9
9
  "dns-management",
10
10
  "object-storage",
11
+ "state-encryption",
11
12
  "database-hosting",
12
13
  "capacity-runtime-hosting",
13
14
  "private-knowledge-index-hosting",
@@ -127,12 +128,15 @@ const SERVICE_PROVIDER_CATALOG = [
127
128
  capabilities: [
128
129
  { type: "frontend-hosting", label: "Frontend hosting", description: "Pages and Workers application hosting.", credentialProfileIds: ["cloudflare-runtime"], status: "available" },
129
130
  { type: "dns-management", label: "DNS management", description: "Scoped DNS record management.", credentialProfileIds: ["cloudflare-dns"], status: "available" },
130
- { type: "object-storage", label: "Object storage", description: "R2-backed immutable publication and private artifact storage.", credentialProfileIds: ["cloudflare-storage"], status: "available" }
131
+ { type: "object-storage", label: "Object storage", description: "R2-backed immutable publication, private artifact storage, and scoped S3 state access.", credentialProfileIds: ["cloudflare-storage", "s3-state-session"], status: "available" },
132
+ { type: "state-encryption", label: "State encryption", description: "Independent encryption authority for OpenTofu state and plan files.", credentialProfileIds: ["opentofu-state-encryption"], status: "available" }
131
133
  ],
132
134
  credentialProfiles: [
133
135
  { 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
136
  { 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"] }
137
+ { id: "cloudflare-storage", label: "Storage management authority", description: "Vault-custodied token used only to reconcile authorized R2 resources.", capabilities: ["object-storage"], fields: [field("apiToken", "Storage API token", "Encrypted separately and used only to reconcile authorized R2 resources.", true, true)], permissions: ["Account: Workers R2 Storage Edit"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
138
+ { id: "s3-state-session", label: "OpenTofu state session", description: "S3-compatible credentials limited to the selected team state prefix.", capabilities: ["object-storage"], fields: [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("sessionToken", "R2 session token", "Optional short-lived S3-compatible session token.", false, true)], permissions: ["Object read and write for only the managed team state prefix"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] },
139
+ { id: "opentofu-state-encryption", label: "OpenTofu state encryption", description: "Independent encryption material that is never stored with the R2 state object.", capabilities: ["state-encryption"], fields: [field("stateEncryptionKey", "OpenTofu state encryption key", "Generated in the browser as a 32-byte hexadecimal key and encrypted separately.", true, true)], permissions: ["Encrypt and decrypt only the selected team OpenTofu state"], sharing: "capability-scoped", unattendedCompatible: true, authoritySchemes: ["environment-reference", "client-encrypted", "external-vault", "workload-identity"], knowledgePageIds: ["provider.cloudflare", "services.credentials", "vault.rotation"] }
136
140
  ]
137
141
  },
138
142
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.13.0-rc.83",
3
+ "version": "0.13.0-rc.85",
4
4
  "description": "Portable TreeSeed contracts, standards, and typed remote control-plane clients.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {