@substrat-run/contracts 0.116.0 → 0.117.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/dist/capability.d.ts +243 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +210 -0
- package/dist/capability.js.map +1 -0
- package/dist/control-plane.d.ts +115 -0
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +78 -2
- package/dist/control-plane.js.map +1 -1
- package/dist/denial.d.ts +15 -0
- package/dist/denial.d.ts.map +1 -1
- package/dist/denial.js +30 -0
- package/dist/denial.js.map +1 -1
- package/dist/events.d.ts +63 -39
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +125 -4
- package/dist/events.js.map +1 -1
- package/dist/ids.d.ts +12 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +17 -0
- package/dist/ids.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +39 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +43 -0
- package/dist/mcp.js.map +1 -0
- package/dist/permission.d.ts +68 -4
- package/dist/permission.d.ts.map +1 -1
- package/dist/permission.js +65 -5
- package/dist/permission.js.map +1 -1
- package/dist/platform-request.d.ts +5 -0
- package/dist/platform-request.d.ts.map +1 -1
- package/dist/platform-request.js +18 -0
- package/dist/platform-request.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Capabilities (#1672) — authority carried by a SECRET rather than held by a principal.
|
|
4
|
+
*
|
|
5
|
+
* The permission checker reasons about principals, and a link share is authority held by
|
|
6
|
+
* whoever has the URL: nobody the checker knows. #97 solved the neighbouring case for
|
|
7
|
+
* connectors by letting the connection BE an actor; this does the same for a secret. A
|
|
8
|
+
* capability is a directory row, the row names what it may do, and the holder of its
|
|
9
|
+
* secret acts as `{ capability: <id> }` — resolved by the checker, recorded on the event,
|
|
10
|
+
* refused into the denial log, like any other actor.
|
|
11
|
+
*
|
|
12
|
+
* It is a building block rather than a link-share feature. The repo carried three
|
|
13
|
+
* hand-built "authority carried by a secret" mechanisms (owner claim links, member
|
|
14
|
+
* invites, the dashboard's signed tokens), each with its own table and a code path outside
|
|
15
|
+
* the checker, none of them on the spine as authority. So the shape here has what those
|
|
16
|
+
* need even where a link share does not: a use limit beside the expiry, and a `become`
|
|
17
|
+
* mode for "exercising this binds that principal".
|
|
18
|
+
*
|
|
19
|
+
* **Directory-backed, never self-contained.** The checker reads the row on every check, so
|
|
20
|
+
* revoking one is the next read, and every exchange is a counted, recorded use. Only the
|
|
21
|
+
* secret's SHA-256 is ever stored; the secret itself leaves the kernel once, in the mint's
|
|
22
|
+
* return value.
|
|
23
|
+
*
|
|
24
|
+
* **A use is an exchange, not an invocation.** The secret is presented once, traded for a
|
|
25
|
+
* session cookie (so it does not live in history or `Referer`), and the session then acts
|
|
26
|
+
* until the capability expires or is revoked. A read-only share makes dozens of calls per
|
|
27
|
+
* page load, and a single-use invite would otherwise be spent by its own redemption — so
|
|
28
|
+
* `maxUses` bounds how many browsers may hold a capability, not how many reads they make.
|
|
29
|
+
*/
|
|
30
|
+
/** What every minted secret starts with — so a secret scanner can recognise a leaked one. */
|
|
31
|
+
export declare const CAPABILITY_SECRET_PREFIX = "sbcap_";
|
|
32
|
+
/** What every session token an exchange hands out starts with. */
|
|
33
|
+
export declare const CAPABILITY_SESSION_PREFIX = "sbses_";
|
|
34
|
+
/** How long a session outlives its exchange, at most — never past the capability itself. */
|
|
35
|
+
export declare const CAPABILITY_SESSION_TTL_MS: number;
|
|
36
|
+
/** The most keys one capability may carry. A link that needs more is a role. */
|
|
37
|
+
export declare const CAPABILITY_PERMISSIONS_MAX = 16;
|
|
38
|
+
/** The most operations one capability's allowlist may name. */
|
|
39
|
+
export declare const CAPABILITY_OPERATIONS_MAX = 32;
|
|
40
|
+
/** An optional operator-facing name for a capability ("client review link"). Never a secret. */
|
|
41
|
+
export declare const capabilityLabel: z.ZodString;
|
|
42
|
+
/**
|
|
43
|
+
* (Not `capabilityGrant` — that older name in `permission.ts` is an entity-narrowed grant
|
|
44
|
+
* to a PRINCIPAL, and predates this module.)
|
|
45
|
+
*
|
|
46
|
+
* What an `act` capability may do: ONE entity and everything beneath it through declared
|
|
47
|
+
* parent edges, specific keys on that subtree, and optionally an allowlist of operations.
|
|
48
|
+
*
|
|
49
|
+
* The keys are the authority — each is checked against the entity exactly as an
|
|
50
|
+
* entity-narrowed grant would be, which is how grants already travel. `operations`
|
|
51
|
+
* narrows on top of them and never widens: an operation outside the list is refused at
|
|
52
|
+
* the door before its handler runs, however much the keys would have allowed. A
|
|
53
|
+
* capability never holds node-level authority, so an operation whose only check is a
|
|
54
|
+
* node-level one refuses it.
|
|
55
|
+
*/
|
|
56
|
+
export declare const capabilityAuthority: z.ZodObject<{
|
|
57
|
+
entity: z.ZodObject<{
|
|
58
|
+
entityType: z.ZodString;
|
|
59
|
+
entityId: z.ZodString;
|
|
60
|
+
}, z.core.$strip>;
|
|
61
|
+
permissions: z.ZodArray<z.core.$ZodBranded<z.ZodString, "PermissionKey", "out">>;
|
|
62
|
+
operations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
export type CapabilityAuthority = z.infer<typeof capabilityAuthority>;
|
|
65
|
+
/**
|
|
66
|
+
* What a MODULE may mint (`ctx.capabilities.mint`) — always an `act` capability.
|
|
67
|
+
*
|
|
68
|
+
* `expiresAt` absent means no expiry; `maxUses` absent means unlimited exchanges. Both are
|
|
69
|
+
* a vertical's call: "anyone with the link" is how most sharing works, and a link share
|
|
70
|
+
* that must die on Friday says so. Neither widens authority — the minter's own is
|
|
71
|
+
* re-checked on every use.
|
|
72
|
+
*/
|
|
73
|
+
export declare const capabilityMintInput: z.ZodObject<{
|
|
74
|
+
entity: z.ZodObject<{
|
|
75
|
+
entityType: z.ZodString;
|
|
76
|
+
entityId: z.ZodString;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
permissions: z.ZodArray<z.core.$ZodBranded<z.ZodString, "PermissionKey", "out">>;
|
|
79
|
+
operations: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
80
|
+
expiresAt: z.ZodOptional<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
81
|
+
maxUses: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
label: z.ZodOptional<z.ZodString>;
|
|
83
|
+
}, z.core.$strip>;
|
|
84
|
+
export type CapabilityMintInput = z.infer<typeof capabilityMintInput>;
|
|
85
|
+
/**
|
|
86
|
+
* What the PLATFORM may mint (`HostAdmin.mintCapability`) — a `become` capability:
|
|
87
|
+
* exchanging it yields a principal instead of a session, the shape an owner claim link and
|
|
88
|
+
* a member invite are ("whoever opens this becomes that seat").
|
|
89
|
+
*
|
|
90
|
+
* Platform-only in this first cut, deliberately. `become` is impersonation by another name
|
|
91
|
+
* — the holder acquires everything the principal holds — so the bound on who may mint one
|
|
92
|
+
* from module code is designed with the invite and claim migrations, not guessed here.
|
|
93
|
+
* Expiry and a use limit are REQUIRED for the same reason: an unbounded `become` is a
|
|
94
|
+
* standing credential for a person.
|
|
95
|
+
*/
|
|
96
|
+
export declare const becomeCapabilityInput: z.ZodObject<{
|
|
97
|
+
principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
98
|
+
expiresAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
99
|
+
maxUses: z.ZodNumber;
|
|
100
|
+
label: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
export type BecomeCapabilityInput = z.infer<typeof becomeCapabilityInput>;
|
|
103
|
+
/**
|
|
104
|
+
* Who minted or revoked a capability: the principal whose operation did it, or a platform
|
|
105
|
+
* actor through `HostAdmin`. Two members rather than a principal with a flag, because an
|
|
106
|
+
* `act` capability's authority is re-checked against its minter on every use and only a
|
|
107
|
+
* principal CAN be re-checked — a platform actor holds no tuples.
|
|
108
|
+
*/
|
|
109
|
+
export declare const capabilityAuthor: z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">, z.ZodObject<{
|
|
110
|
+
platform: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
111
|
+
}, z.core.$strip>]>;
|
|
112
|
+
export type CapabilityAuthor = z.infer<typeof capabilityAuthor>;
|
|
113
|
+
/**
|
|
114
|
+
* A capability as the directory holds it — what `ctx.capabilities.list` returns. Carries
|
|
115
|
+
* neither the secret nor its hash: the one is never stored, and the other is nothing a
|
|
116
|
+
* caller has a use for.
|
|
117
|
+
*/
|
|
118
|
+
export declare const capabilityRecord: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
119
|
+
id: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
120
|
+
label: z.ZodNullable<z.ZodString>;
|
|
121
|
+
mintedBy: z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">, z.ZodObject<{
|
|
122
|
+
platform: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
123
|
+
}, z.core.$strip>]>;
|
|
124
|
+
mintedAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
125
|
+
expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
126
|
+
maxUses: z.ZodNullable<z.ZodNumber>;
|
|
127
|
+
uses: z.ZodNumber;
|
|
128
|
+
lastUsedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
129
|
+
revokedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
130
|
+
revokedBy: z.ZodNullable<z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">, z.ZodObject<{
|
|
131
|
+
platform: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
132
|
+
}, z.core.$strip>]>>;
|
|
133
|
+
mode: z.ZodLiteral<"act">;
|
|
134
|
+
entity: z.ZodObject<{
|
|
135
|
+
entityType: z.ZodString;
|
|
136
|
+
entityId: z.ZodString;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
permissions: z.ZodArray<z.core.$ZodBranded<z.ZodString, "PermissionKey", "out">>;
|
|
139
|
+
operations: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
140
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
141
|
+
id: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
142
|
+
label: z.ZodNullable<z.ZodString>;
|
|
143
|
+
mintedBy: z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">, z.ZodObject<{
|
|
144
|
+
platform: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
145
|
+
}, z.core.$strip>]>;
|
|
146
|
+
mintedAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
147
|
+
expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
148
|
+
maxUses: z.ZodNullable<z.ZodNumber>;
|
|
149
|
+
uses: z.ZodNumber;
|
|
150
|
+
lastUsedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
151
|
+
revokedAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
152
|
+
revokedBy: z.ZodNullable<z.ZodUnion<readonly [z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">, z.ZodObject<{
|
|
153
|
+
platform: z.core.$ZodBranded<z.ZodString, "PlatformActorId", "out">;
|
|
154
|
+
}, z.core.$strip>]>>;
|
|
155
|
+
mode: z.ZodLiteral<"become">;
|
|
156
|
+
principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
157
|
+
}, z.core.$strip>], "mode">;
|
|
158
|
+
export type CapabilityRecord = z.infer<typeof capabilityRecord>;
|
|
159
|
+
/**
|
|
160
|
+
* What a mint hands back — the ONLY time the secret exists outside the caller's hands.
|
|
161
|
+
* The kernel keeps its hash; a vertical builds the link from it and returns it once.
|
|
162
|
+
*/
|
|
163
|
+
export declare const mintedCapability: z.ZodObject<{
|
|
164
|
+
id: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
165
|
+
secret: z.ZodString;
|
|
166
|
+
expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
167
|
+
}, z.core.$strip>;
|
|
168
|
+
export type MintedCapability = z.infer<typeof mintedCapability>;
|
|
169
|
+
/**
|
|
170
|
+
* What an exchange yields: a session to act as the capability (`act`), or the principal
|
|
171
|
+
* the holder becomes (`become`). A refused exchange — an unknown, expired, revoked or
|
|
172
|
+
* used-up secret — is `null`, one answer for all four, so a probe learns nothing.
|
|
173
|
+
*/
|
|
174
|
+
export declare const capabilityExchange: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
175
|
+
kind: z.ZodLiteral<"session">;
|
|
176
|
+
capabilityId: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
177
|
+
sessionToken: z.ZodString;
|
|
178
|
+
expiresAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
179
|
+
entity: z.ZodObject<{
|
|
180
|
+
entityType: z.ZodString;
|
|
181
|
+
entityId: z.ZodString;
|
|
182
|
+
}, z.core.$strip>;
|
|
183
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
184
|
+
kind: z.ZodLiteral<"principal">;
|
|
185
|
+
capabilityId: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
186
|
+
principal: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
187
|
+
}, z.core.$strip>], "kind">;
|
|
188
|
+
export type CapabilityExchange = z.infer<typeof capabilityExchange>;
|
|
189
|
+
/** What narrows `ctx.capabilities.list`. Live capabilities only unless `includeRevoked`. */
|
|
190
|
+
export declare const capabilityFilter: z.ZodObject<{
|
|
191
|
+
entity: z.ZodOptional<z.ZodObject<{
|
|
192
|
+
entityType: z.ZodString;
|
|
193
|
+
entityId: z.ZodString;
|
|
194
|
+
}, z.core.$strip>>;
|
|
195
|
+
includeRevoked: z.ZodOptional<z.ZodBoolean>;
|
|
196
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
}, z.core.$strip>;
|
|
198
|
+
export type CapabilityFilter = z.infer<typeof capabilityFilter>;
|
|
199
|
+
/** A module minted an `act` capability. Entity: the shared entity; actor: the minter. */
|
|
200
|
+
export declare const CAPABILITY_MINTED = "capability.minted";
|
|
201
|
+
/** A module revoked one. Entity: the shared entity; actor: the revoker. */
|
|
202
|
+
export declare const CAPABILITY_REVOKED = "capability.revoked";
|
|
203
|
+
/**
|
|
204
|
+
* A secret was exchanged — one counted use. Entity: the shared entity for `act`, the
|
|
205
|
+
* capability itself (`capability:<id>`) for `become`; actor: `{ capability }`.
|
|
206
|
+
*/
|
|
207
|
+
export declare const CAPABILITY_EXERCISED = "capability.exercised";
|
|
208
|
+
export declare const capabilityMintedPayload: z.ZodObject<{
|
|
209
|
+
capabilityId: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
210
|
+
entity: z.ZodObject<{
|
|
211
|
+
entityType: z.ZodString;
|
|
212
|
+
entityId: z.ZodString;
|
|
213
|
+
}, z.core.$strip>;
|
|
214
|
+
permissions: z.ZodArray<z.core.$ZodBranded<z.ZodString, "PermissionKey", "out">>;
|
|
215
|
+
operations: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
216
|
+
expiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
217
|
+
maxUses: z.ZodNullable<z.ZodNumber>;
|
|
218
|
+
label: z.ZodNullable<z.ZodString>;
|
|
219
|
+
mintedBy: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
220
|
+
}, z.core.$strip>;
|
|
221
|
+
export type CapabilityMintedPayload = z.infer<typeof capabilityMintedPayload>;
|
|
222
|
+
export declare const capabilityRevokedPayload: z.ZodObject<{
|
|
223
|
+
capabilityId: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
224
|
+
entity: z.ZodObject<{
|
|
225
|
+
entityType: z.ZodString;
|
|
226
|
+
entityId: z.ZodString;
|
|
227
|
+
}, z.core.$strip>;
|
|
228
|
+
revokedBy: z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">;
|
|
229
|
+
}, z.core.$strip>;
|
|
230
|
+
export type CapabilityRevokedPayload = z.infer<typeof capabilityRevokedPayload>;
|
|
231
|
+
export declare const capabilityExercisedPayload: z.ZodObject<{
|
|
232
|
+
capabilityId: z.core.$ZodBranded<z.ZodString, "CapabilityId", "out">;
|
|
233
|
+
mode: z.ZodEnum<{
|
|
234
|
+
act: "act";
|
|
235
|
+
become: "become";
|
|
236
|
+
}>;
|
|
237
|
+
uses: z.ZodNumber;
|
|
238
|
+
maxUses: z.ZodNullable<z.ZodNumber>;
|
|
239
|
+
sessionExpiresAt: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "Instant", "out">>;
|
|
240
|
+
principal: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "PrincipalId", "out">>;
|
|
241
|
+
}, z.core.$strip>;
|
|
242
|
+
export type CapabilityExercisedPayload = z.infer<typeof capabilityExercisedPayload>;
|
|
243
|
+
//# sourceMappingURL=capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,wBAAwB,WAAW,CAAC;AACjD,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,4FAA4F;AAC5F,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAC1D,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,+DAA+D;AAC/D,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,gGAAgG;AAChG,eAAO,MAAM,eAAe,aAAoC,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB;;;;;;;iBAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;iBAI9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB;;;;;iBAKhC,CAAC;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;mBAAkE,CAAC;AAChG,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAkBhE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAc3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;;;iBAI3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;2BAa7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEpE,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB;;;;;;;iBAI3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAShE,yFAAyF;AACzF,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AACvD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;iBASlC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E,eAAO,MAAM,wBAAwB;;;;;;;iBAInC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF,eAAO,MAAM,0BAA0B;;;;;;;;;;iBAUrC,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { entityRef } from './events.js';
|
|
3
|
+
import { capabilityId, instant, permissionKey, platformActorId, principalId } from './ids.js';
|
|
4
|
+
/**
|
|
5
|
+
* Capabilities (#1672) — authority carried by a SECRET rather than held by a principal.
|
|
6
|
+
*
|
|
7
|
+
* The permission checker reasons about principals, and a link share is authority held by
|
|
8
|
+
* whoever has the URL: nobody the checker knows. #97 solved the neighbouring case for
|
|
9
|
+
* connectors by letting the connection BE an actor; this does the same for a secret. A
|
|
10
|
+
* capability is a directory row, the row names what it may do, and the holder of its
|
|
11
|
+
* secret acts as `{ capability: <id> }` — resolved by the checker, recorded on the event,
|
|
12
|
+
* refused into the denial log, like any other actor.
|
|
13
|
+
*
|
|
14
|
+
* It is a building block rather than a link-share feature. The repo carried three
|
|
15
|
+
* hand-built "authority carried by a secret" mechanisms (owner claim links, member
|
|
16
|
+
* invites, the dashboard's signed tokens), each with its own table and a code path outside
|
|
17
|
+
* the checker, none of them on the spine as authority. So the shape here has what those
|
|
18
|
+
* need even where a link share does not: a use limit beside the expiry, and a `become`
|
|
19
|
+
* mode for "exercising this binds that principal".
|
|
20
|
+
*
|
|
21
|
+
* **Directory-backed, never self-contained.** The checker reads the row on every check, so
|
|
22
|
+
* revoking one is the next read, and every exchange is a counted, recorded use. Only the
|
|
23
|
+
* secret's SHA-256 is ever stored; the secret itself leaves the kernel once, in the mint's
|
|
24
|
+
* return value.
|
|
25
|
+
*
|
|
26
|
+
* **A use is an exchange, not an invocation.** The secret is presented once, traded for a
|
|
27
|
+
* session cookie (so it does not live in history or `Referer`), and the session then acts
|
|
28
|
+
* until the capability expires or is revoked. A read-only share makes dozens of calls per
|
|
29
|
+
* page load, and a single-use invite would otherwise be spent by its own redemption — so
|
|
30
|
+
* `maxUses` bounds how many browsers may hold a capability, not how many reads they make.
|
|
31
|
+
*/
|
|
32
|
+
/** What every minted secret starts with — so a secret scanner can recognise a leaked one. */
|
|
33
|
+
export const CAPABILITY_SECRET_PREFIX = 'sbcap_';
|
|
34
|
+
/** What every session token an exchange hands out starts with. */
|
|
35
|
+
export const CAPABILITY_SESSION_PREFIX = 'sbses_';
|
|
36
|
+
/** How long a session outlives its exchange, at most — never past the capability itself. */
|
|
37
|
+
export const CAPABILITY_SESSION_TTL_MS = 24 * 60 * 60_000;
|
|
38
|
+
/** The most keys one capability may carry. A link that needs more is a role. */
|
|
39
|
+
export const CAPABILITY_PERMISSIONS_MAX = 16;
|
|
40
|
+
/** The most operations one capability's allowlist may name. */
|
|
41
|
+
export const CAPABILITY_OPERATIONS_MAX = 32;
|
|
42
|
+
/** An optional operator-facing name for a capability ("client review link"). Never a secret. */
|
|
43
|
+
export const capabilityLabel = z.string().trim().min(1).max(200);
|
|
44
|
+
/**
|
|
45
|
+
* (Not `capabilityGrant` — that older name in `permission.ts` is an entity-narrowed grant
|
|
46
|
+
* to a PRINCIPAL, and predates this module.)
|
|
47
|
+
*
|
|
48
|
+
* What an `act` capability may do: ONE entity and everything beneath it through declared
|
|
49
|
+
* parent edges, specific keys on that subtree, and optionally an allowlist of operations.
|
|
50
|
+
*
|
|
51
|
+
* The keys are the authority — each is checked against the entity exactly as an
|
|
52
|
+
* entity-narrowed grant would be, which is how grants already travel. `operations`
|
|
53
|
+
* narrows on top of them and never widens: an operation outside the list is refused at
|
|
54
|
+
* the door before its handler runs, however much the keys would have allowed. A
|
|
55
|
+
* capability never holds node-level authority, so an operation whose only check is a
|
|
56
|
+
* node-level one refuses it.
|
|
57
|
+
*/
|
|
58
|
+
export const capabilityAuthority = z.object({
|
|
59
|
+
entity: entityRef,
|
|
60
|
+
permissions: z.array(permissionKey).min(1).max(CAPABILITY_PERMISSIONS_MAX),
|
|
61
|
+
operations: z.array(z.string().min(1)).min(1).max(CAPABILITY_OPERATIONS_MAX).optional(),
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* What a MODULE may mint (`ctx.capabilities.mint`) — always an `act` capability.
|
|
65
|
+
*
|
|
66
|
+
* `expiresAt` absent means no expiry; `maxUses` absent means unlimited exchanges. Both are
|
|
67
|
+
* a vertical's call: "anyone with the link" is how most sharing works, and a link share
|
|
68
|
+
* that must die on Friday says so. Neither widens authority — the minter's own is
|
|
69
|
+
* re-checked on every use.
|
|
70
|
+
*/
|
|
71
|
+
export const capabilityMintInput = capabilityAuthority.extend({
|
|
72
|
+
expiresAt: instant.optional(),
|
|
73
|
+
maxUses: z.number().int().positive().optional(),
|
|
74
|
+
label: capabilityLabel.optional(),
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* What the PLATFORM may mint (`HostAdmin.mintCapability`) — a `become` capability:
|
|
78
|
+
* exchanging it yields a principal instead of a session, the shape an owner claim link and
|
|
79
|
+
* a member invite are ("whoever opens this becomes that seat").
|
|
80
|
+
*
|
|
81
|
+
* Platform-only in this first cut, deliberately. `become` is impersonation by another name
|
|
82
|
+
* — the holder acquires everything the principal holds — so the bound on who may mint one
|
|
83
|
+
* from module code is designed with the invite and claim migrations, not guessed here.
|
|
84
|
+
* Expiry and a use limit are REQUIRED for the same reason: an unbounded `become` is a
|
|
85
|
+
* standing credential for a person.
|
|
86
|
+
*/
|
|
87
|
+
export const becomeCapabilityInput = z.object({
|
|
88
|
+
principal: principalId,
|
|
89
|
+
expiresAt: instant,
|
|
90
|
+
maxUses: z.number().int().positive(),
|
|
91
|
+
label: capabilityLabel.optional(),
|
|
92
|
+
});
|
|
93
|
+
/**
|
|
94
|
+
* Who minted or revoked a capability: the principal whose operation did it, or a platform
|
|
95
|
+
* actor through `HostAdmin`. Two members rather than a principal with a flag, because an
|
|
96
|
+
* `act` capability's authority is re-checked against its minter on every use and only a
|
|
97
|
+
* principal CAN be re-checked — a platform actor holds no tuples.
|
|
98
|
+
*/
|
|
99
|
+
export const capabilityAuthor = z.union([principalId, z.object({ platform: platformActorId })]);
|
|
100
|
+
const capabilityRecordCommon = {
|
|
101
|
+
id: capabilityId,
|
|
102
|
+
label: capabilityLabel.nullable(),
|
|
103
|
+
mintedBy: capabilityAuthor,
|
|
104
|
+
mintedAt: instant,
|
|
105
|
+
/** Null = never expires. */
|
|
106
|
+
expiresAt: instant.nullable(),
|
|
107
|
+
/** Null = unlimited exchanges. */
|
|
108
|
+
maxUses: z.number().int().positive().nullable(),
|
|
109
|
+
/** Exchanges so far. Never above `maxUses`. */
|
|
110
|
+
uses: z.number().int().nonnegative(),
|
|
111
|
+
lastUsedAt: instant.nullable(),
|
|
112
|
+
revokedAt: instant.nullable(),
|
|
113
|
+
revokedBy: capabilityAuthor.nullable(),
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* A capability as the directory holds it — what `ctx.capabilities.list` returns. Carries
|
|
117
|
+
* neither the secret nor its hash: the one is never stored, and the other is nothing a
|
|
118
|
+
* caller has a use for.
|
|
119
|
+
*/
|
|
120
|
+
export const capabilityRecord = z.discriminatedUnion('mode', [
|
|
121
|
+
z.object({
|
|
122
|
+
mode: z.literal('act'),
|
|
123
|
+
...capabilityRecordCommon,
|
|
124
|
+
entity: entityRef,
|
|
125
|
+
permissions: z.array(permissionKey).min(1),
|
|
126
|
+
/** Null = any operation the keys allow. */
|
|
127
|
+
operations: z.array(z.string().min(1)).nullable(),
|
|
128
|
+
}),
|
|
129
|
+
z.object({
|
|
130
|
+
mode: z.literal('become'),
|
|
131
|
+
...capabilityRecordCommon,
|
|
132
|
+
principal: principalId,
|
|
133
|
+
}),
|
|
134
|
+
]);
|
|
135
|
+
/**
|
|
136
|
+
* What a mint hands back — the ONLY time the secret exists outside the caller's hands.
|
|
137
|
+
* The kernel keeps its hash; a vertical builds the link from it and returns it once.
|
|
138
|
+
*/
|
|
139
|
+
export const mintedCapability = z.object({
|
|
140
|
+
id: capabilityId,
|
|
141
|
+
secret: z.string().startsWith(CAPABILITY_SECRET_PREFIX),
|
|
142
|
+
expiresAt: instant.nullable(),
|
|
143
|
+
});
|
|
144
|
+
/**
|
|
145
|
+
* What an exchange yields: a session to act as the capability (`act`), or the principal
|
|
146
|
+
* the holder becomes (`become`). A refused exchange — an unknown, expired, revoked or
|
|
147
|
+
* used-up secret — is `null`, one answer for all four, so a probe learns nothing.
|
|
148
|
+
*/
|
|
149
|
+
export const capabilityExchange = z.discriminatedUnion('kind', [
|
|
150
|
+
z.object({
|
|
151
|
+
kind: z.literal('session'),
|
|
152
|
+
capabilityId,
|
|
153
|
+
sessionToken: z.string().startsWith(CAPABILITY_SESSION_PREFIX),
|
|
154
|
+
expiresAt: instant,
|
|
155
|
+
entity: entityRef,
|
|
156
|
+
}),
|
|
157
|
+
z.object({
|
|
158
|
+
kind: z.literal('principal'),
|
|
159
|
+
capabilityId,
|
|
160
|
+
principal: principalId,
|
|
161
|
+
}),
|
|
162
|
+
]);
|
|
163
|
+
/** What narrows `ctx.capabilities.list`. Live capabilities only unless `includeRevoked`. */
|
|
164
|
+
export const capabilityFilter = z.object({
|
|
165
|
+
entity: entityRef.optional(),
|
|
166
|
+
includeRevoked: z.boolean().optional(),
|
|
167
|
+
limit: z.number().int().min(1).max(200).optional(),
|
|
168
|
+
});
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// The spine events the kernel emits about capabilities — kernel-authored, like
|
|
171
|
+
// `attachment.added`, so module code can neither forge nor suppress them. Fat, per
|
|
172
|
+
// the event rule: a consumer never has to read the directory to know what happened.
|
|
173
|
+
// Never the secret, never its hash.
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
/** A module minted an `act` capability. Entity: the shared entity; actor: the minter. */
|
|
176
|
+
export const CAPABILITY_MINTED = 'capability.minted';
|
|
177
|
+
/** A module revoked one. Entity: the shared entity; actor: the revoker. */
|
|
178
|
+
export const CAPABILITY_REVOKED = 'capability.revoked';
|
|
179
|
+
/**
|
|
180
|
+
* A secret was exchanged — one counted use. Entity: the shared entity for `act`, the
|
|
181
|
+
* capability itself (`capability:<id>`) for `become`; actor: `{ capability }`.
|
|
182
|
+
*/
|
|
183
|
+
export const CAPABILITY_EXERCISED = 'capability.exercised';
|
|
184
|
+
export const capabilityMintedPayload = z.object({
|
|
185
|
+
capabilityId,
|
|
186
|
+
entity: entityRef,
|
|
187
|
+
permissions: z.array(permissionKey).min(1),
|
|
188
|
+
operations: z.array(z.string().min(1)).nullable(),
|
|
189
|
+
expiresAt: instant.nullable(),
|
|
190
|
+
maxUses: z.number().int().positive().nullable(),
|
|
191
|
+
label: capabilityLabel.nullable(),
|
|
192
|
+
mintedBy: principalId,
|
|
193
|
+
});
|
|
194
|
+
export const capabilityRevokedPayload = z.object({
|
|
195
|
+
capabilityId,
|
|
196
|
+
entity: entityRef,
|
|
197
|
+
revokedBy: principalId,
|
|
198
|
+
});
|
|
199
|
+
export const capabilityExercisedPayload = z.object({
|
|
200
|
+
capabilityId,
|
|
201
|
+
mode: z.enum(['act', 'become']),
|
|
202
|
+
/** The count AFTER this exchange. */
|
|
203
|
+
uses: z.number().int().positive(),
|
|
204
|
+
maxUses: z.number().int().positive().nullable(),
|
|
205
|
+
/** `act`: when the session this exchange handed out stops working. Null for `become`. */
|
|
206
|
+
sessionExpiresAt: instant.nullable(),
|
|
207
|
+
/** `become`: the principal the holder became. Null for `act`. */
|
|
208
|
+
principal: principalId.nullable(),
|
|
209
|
+
});
|
|
210
|
+
//# sourceMappingURL=capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"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"}
|
package/dist/control-plane.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare const adminAction: z.ZodEnum<{
|
|
|
27
27
|
importScope: "importScope";
|
|
28
28
|
linkIdentity: "linkIdentity";
|
|
29
29
|
markScopeProvisioned: "markScopeProvisioned";
|
|
30
|
+
mintCapability: "mintCapability";
|
|
30
31
|
promoteVersion: "promoteVersion";
|
|
31
32
|
provisionBlobStore: "provisionBlobStore";
|
|
32
33
|
provisionScope: "provisionScope";
|
|
@@ -43,8 +44,11 @@ export declare const adminAction: z.ZodEnum<{
|
|
|
43
44
|
requestPublish: "requestPublish";
|
|
44
45
|
restoreDirectory: "restoreDirectory";
|
|
45
46
|
restoreScope: "restoreScope";
|
|
47
|
+
restoreToSystem: "restoreToSystem";
|
|
48
|
+
revokeCapability: "revokeCapability";
|
|
46
49
|
revokeConnection: "revokeConnection";
|
|
47
50
|
revokeEntitlement: "revokeEntitlement";
|
|
51
|
+
revokeFromSystem: "revokeFromSystem";
|
|
48
52
|
rewindScope: "rewindScope";
|
|
49
53
|
setHostnameIssuance: "setHostnameIssuance";
|
|
50
54
|
setHostnameStatus: "setHostnameStatus";
|
|
@@ -79,6 +83,7 @@ export type AdminAction = z.infer<typeof adminAction>;
|
|
|
79
83
|
export declare const subjectShredReceipt: z.ZodObject<{
|
|
80
84
|
subjectId: z.ZodString;
|
|
81
85
|
eventsRedacted: z.ZodNumber;
|
|
86
|
+
intentsRedacted: z.ZodDefault<z.ZodNumber>;
|
|
82
87
|
keyDestroyed: z.ZodBoolean;
|
|
83
88
|
tombstoned: z.ZodBoolean;
|
|
84
89
|
}, z.core.$strip>;
|
|
@@ -693,6 +698,7 @@ export declare const adminLogEntry: z.ZodObject<{
|
|
|
693
698
|
importScope: "importScope";
|
|
694
699
|
linkIdentity: "linkIdentity";
|
|
695
700
|
markScopeProvisioned: "markScopeProvisioned";
|
|
701
|
+
mintCapability: "mintCapability";
|
|
696
702
|
promoteVersion: "promoteVersion";
|
|
697
703
|
provisionBlobStore: "provisionBlobStore";
|
|
698
704
|
provisionScope: "provisionScope";
|
|
@@ -709,8 +715,11 @@ export declare const adminLogEntry: z.ZodObject<{
|
|
|
709
715
|
requestPublish: "requestPublish";
|
|
710
716
|
restoreDirectory: "restoreDirectory";
|
|
711
717
|
restoreScope: "restoreScope";
|
|
718
|
+
restoreToSystem: "restoreToSystem";
|
|
719
|
+
revokeCapability: "revokeCapability";
|
|
712
720
|
revokeConnection: "revokeConnection";
|
|
713
721
|
revokeEntitlement: "revokeEntitlement";
|
|
722
|
+
revokeFromSystem: "revokeFromSystem";
|
|
714
723
|
rewindScope: "rewindScope";
|
|
715
724
|
setHostnameIssuance: "setHostnameIssuance";
|
|
716
725
|
setHostnameStatus: "setHostnameStatus";
|
|
@@ -1056,6 +1065,7 @@ export declare const tenantExport: z.ZodObject<{
|
|
|
1056
1065
|
importScope: "importScope";
|
|
1057
1066
|
linkIdentity: "linkIdentity";
|
|
1058
1067
|
markScopeProvisioned: "markScopeProvisioned";
|
|
1068
|
+
mintCapability: "mintCapability";
|
|
1059
1069
|
promoteVersion: "promoteVersion";
|
|
1060
1070
|
provisionBlobStore: "provisionBlobStore";
|
|
1061
1071
|
provisionScope: "provisionScope";
|
|
@@ -1072,8 +1082,11 @@ export declare const tenantExport: z.ZodObject<{
|
|
|
1072
1082
|
requestPublish: "requestPublish";
|
|
1073
1083
|
restoreDirectory: "restoreDirectory";
|
|
1074
1084
|
restoreScope: "restoreScope";
|
|
1085
|
+
restoreToSystem: "restoreToSystem";
|
|
1086
|
+
revokeCapability: "revokeCapability";
|
|
1075
1087
|
revokeConnection: "revokeConnection";
|
|
1076
1088
|
revokeEntitlement: "revokeEntitlement";
|
|
1089
|
+
revokeFromSystem: "revokeFromSystem";
|
|
1077
1090
|
rewindScope: "rewindScope";
|
|
1078
1091
|
setHostnameIssuance: "setHostnameIssuance";
|
|
1079
1092
|
setHostnameStatus: "setHostnameStatus";
|
|
@@ -1250,4 +1263,106 @@ export declare const meterReading: z.ZodObject<{
|
|
|
1250
1263
|
}, z.core.$strip>>;
|
|
1251
1264
|
}, z.core.$strip>;
|
|
1252
1265
|
export type MeterReading = z.infer<typeof meterReading>;
|
|
1266
|
+
/**
|
|
1267
|
+
* Storage, read on demand (#1524): the size of each of one tenant's scope DATABASES,
|
|
1268
|
+
* and their sum. Read-only first, by decision — nothing is stored, no sweep takes it,
|
|
1269
|
+
* and there is no fleet-wide form. Reading a scope's size wakes that scope's Durable
|
|
1270
|
+
* Object, so a periodic or fleet-wide reading would bill a DO invocation per idle scope
|
|
1271
|
+
* per interval. The reading is taken when a person asks for it and costs what they asked.
|
|
1272
|
+
*
|
|
1273
|
+
* What it counts: `SqlStorage.databaseSize` on Cloudflare, `page_count × page_size` on
|
|
1274
|
+
* SQLite. That is rows, indexes, the spine, and free pages the database has not given back.
|
|
1275
|
+
* What it deliberately does NOT count, named in `excluded` so a consumer cannot mistake
|
|
1276
|
+
* the number for the whole bill:
|
|
1277
|
+
* - `attachments`: attachment bytes live in a blob store. The scope holds only their rows.
|
|
1278
|
+
* - `tenant-stores`: per-tenant D1 databases are separate databases.
|
|
1279
|
+
* - `lake`: shipped event history is volume in the lake, not in any scope.
|
|
1280
|
+
*/
|
|
1281
|
+
export declare const storageExclusion: z.ZodEnum<{
|
|
1282
|
+
attachments: "attachments";
|
|
1283
|
+
lake: "lake";
|
|
1284
|
+
"tenant-stores": "tenant-stores";
|
|
1285
|
+
}>;
|
|
1286
|
+
export type StorageExclusion = z.infer<typeof storageExclusion>;
|
|
1287
|
+
/** Every exclusion, in the order a surface lists them. A reading always carries all three. */
|
|
1288
|
+
export declare const STORAGE_EXCLUSIONS: readonly StorageExclusion[];
|
|
1289
|
+
/** One scope's database size, or why it could not be read. Exactly one of the two is set. */
|
|
1290
|
+
export declare const scopeStorageReading: z.ZodUnion<readonly [z.ZodObject<{
|
|
1291
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
1292
|
+
status: z.ZodEnum<{
|
|
1293
|
+
active: "active";
|
|
1294
|
+
archived: "archived";
|
|
1295
|
+
archiving: "archiving";
|
|
1296
|
+
provisioning: "provisioning";
|
|
1297
|
+
reaped: "reaped";
|
|
1298
|
+
suspended: "suspended";
|
|
1299
|
+
}>;
|
|
1300
|
+
bytes: z.ZodNumber;
|
|
1301
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1302
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
1303
|
+
status: z.ZodEnum<{
|
|
1304
|
+
active: "active";
|
|
1305
|
+
archived: "archived";
|
|
1306
|
+
archiving: "archiving";
|
|
1307
|
+
provisioning: "provisioning";
|
|
1308
|
+
reaped: "reaped";
|
|
1309
|
+
suspended: "suspended";
|
|
1310
|
+
}>;
|
|
1311
|
+
bytes: z.ZodNull;
|
|
1312
|
+
error: z.ZodString;
|
|
1313
|
+
}, z.core.$strip>]>;
|
|
1314
|
+
export type ScopeStorageReading = z.infer<typeof scopeStorageReading>;
|
|
1315
|
+
/**
|
|
1316
|
+
* One PAGE of a tenant's storage reading. It is paged because each scope read wakes
|
|
1317
|
+
* a DO, and one card opened on a tenant with thousands of scopes must not fan out to
|
|
1318
|
+
* all of them. A caller that wants more asks for the next page. `nextCursor` is the
|
|
1319
|
+
* scope id to resume after.
|
|
1320
|
+
*
|
|
1321
|
+
* `complete` is the only field that may be read as "this is the tenant's total". It is
|
|
1322
|
+
* true when this one page covered every readable scope (no cursor was given and none is
|
|
1323
|
+
* returned) and no read failed. A partial sum is `bytes` with `complete: false`, and a
|
|
1324
|
+
* surface must say so rather than label it a total.
|
|
1325
|
+
*/
|
|
1326
|
+
export declare const storageMeterReading: z.ZodObject<{
|
|
1327
|
+
tenantId: z.core.$ZodBranded<z.ZodString, "TenantId", "out">;
|
|
1328
|
+
readAt: z.core.$ZodBranded<z.ZodString, "Instant", "out">;
|
|
1329
|
+
basis: z.ZodLiteral<"scope-databases">;
|
|
1330
|
+
excluded: z.ZodArray<z.ZodEnum<{
|
|
1331
|
+
attachments: "attachments";
|
|
1332
|
+
lake: "lake";
|
|
1333
|
+
"tenant-stores": "tenant-stores";
|
|
1334
|
+
}>>;
|
|
1335
|
+
bytes: z.ZodNumber;
|
|
1336
|
+
scopes: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
1337
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
1338
|
+
status: z.ZodEnum<{
|
|
1339
|
+
active: "active";
|
|
1340
|
+
archived: "archived";
|
|
1341
|
+
archiving: "archiving";
|
|
1342
|
+
provisioning: "provisioning";
|
|
1343
|
+
reaped: "reaped";
|
|
1344
|
+
suspended: "suspended";
|
|
1345
|
+
}>;
|
|
1346
|
+
bytes: z.ZodNumber;
|
|
1347
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1348
|
+
scopeId: z.core.$ZodBranded<z.ZodString, "ScopeId", "out">;
|
|
1349
|
+
status: z.ZodEnum<{
|
|
1350
|
+
active: "active";
|
|
1351
|
+
archived: "archived";
|
|
1352
|
+
archiving: "archiving";
|
|
1353
|
+
provisioning: "provisioning";
|
|
1354
|
+
reaped: "reaped";
|
|
1355
|
+
suspended: "suspended";
|
|
1356
|
+
}>;
|
|
1357
|
+
bytes: z.ZodNull;
|
|
1358
|
+
error: z.ZodString;
|
|
1359
|
+
}, z.core.$strip>]>>;
|
|
1360
|
+
read: z.ZodNumber;
|
|
1361
|
+
failed: z.ZodNumber;
|
|
1362
|
+
total: z.ZodNumber;
|
|
1363
|
+
reaped: z.ZodNumber;
|
|
1364
|
+
nextCursor: z.ZodNullable<z.core.$ZodBranded<z.ZodString, "ScopeId", "out">>;
|
|
1365
|
+
complete: z.ZodBoolean;
|
|
1366
|
+
}, z.core.$strip>;
|
|
1367
|
+
export type StorageMeterReading = z.infer<typeof storageMeterReading>;
|
|
1253
1368
|
//# sourceMappingURL=control-plane.d.ts.map
|