@openvtc/trust-tasks 0.12.16 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -3
- package/dist/_runtime/canonical.d.ts +40 -0
- package/dist/_runtime/canonical.d.ts.map +1 -0
- package/dist/_runtime/canonical.js +147 -0
- package/dist/_runtime/canonical.js.map +1 -0
- package/dist/_runtime/consume.d.ts +108 -2
- package/dist/_runtime/consume.d.ts.map +1 -1
- package/dist/_runtime/consume.js +174 -8
- package/dist/_runtime/consume.js.map +1 -1
- package/dist/_runtime/document.d.ts +17 -4
- package/dist/_runtime/document.d.ts.map +1 -1
- package/dist/_runtime/document.js +17 -4
- package/dist/_runtime/document.js.map +1 -1
- package/dist/_runtime/freshness.d.ts +105 -0
- package/dist/_runtime/freshness.d.ts.map +1 -0
- package/dist/_runtime/freshness.js +142 -0
- package/dist/_runtime/freshness.js.map +1 -0
- package/dist/_runtime/index.d.ts +4 -1
- package/dist/_runtime/index.d.ts.map +1 -1
- package/dist/_runtime/index.js +4 -1
- package/dist/_runtime/index.js.map +1 -1
- package/dist/_runtime/replay.d.ts +176 -0
- package/dist/_runtime/replay.d.ts.map +1 -0
- package/dist/_runtime/replay.js +147 -0
- package/dist/_runtime/replay.js.map +1 -0
- package/dist/keys/create/0.1/payload.d.ts +27 -13
- package/dist/keys/create/0.1/payload.d.ts.map +1 -1
- package/dist/keys/create/0.1/payload.js +11 -5
- package/dist/keys/create/0.1/payload.js.map +1 -1
- package/dist/keys/import/0.1/payload.d.ts +10 -10
- package/dist/keys/import/0.1/payload.d.ts.map +1 -1
- package/dist/keys/import/0.1/payload.js +6 -4
- package/dist/keys/import/0.1/payload.js.map +1 -1
- package/dist/keys/list/0.1/payload.d.ts +10 -10
- package/dist/keys/list/0.1/payload.d.ts.map +1 -1
- package/dist/keys/list/0.1/payload.js +6 -4
- package/dist/keys/list/0.1/payload.js.map +1 -1
- package/dist/keys/show/0.1/payload.d.ts +10 -10
- package/dist/keys/show/0.1/payload.d.ts.map +1 -1
- package/dist/keys/show/0.1/payload.js +6 -4
- package/dist/keys/show/0.1/payload.js.map +1 -1
- package/package.json +1 -1
- package/src/_runtime/canonical.ts +159 -0
- package/src/_runtime/consume.ts +267 -10
- package/src/_runtime/document.ts +17 -4
- package/src/_runtime/freshness.ts +183 -0
- package/src/_runtime/index.ts +30 -0
- package/src/_runtime/replay.ts +250 -0
- package/src/keys/create/0.1/payload.ts +20 -8
- package/src/keys/import/0.1/payload.ts +8 -6
- package/src/keys/list/0.1/payload.ts +8 -6
- package/src/keys/show/0.1/payload.ts +8 -6
package/dist/_runtime/consume.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Inbound-document orchestration for SPEC.md §7.2 item 2
|
|
2
|
+
* Inbound-document orchestration for SPEC.md §7.2 item 2, items 4–8, and the
|
|
3
|
+
* two stateful checks — the freshness bound of item 4 and the
|
|
4
|
+
* duplicate-execution record of item 11.
|
|
3
5
|
*
|
|
4
6
|
* Hand-written. Mirrors `consume.rs` in trust-tasks-rs, deliberately closely:
|
|
5
7
|
* a TypeScript consumer and a Rust one must reach the same verdict on the same
|
|
6
8
|
* document, or the two reference implementations disagree about what conforms.
|
|
7
9
|
*
|
|
8
10
|
* ```ts
|
|
9
|
-
* import {
|
|
11
|
+
* import {
|
|
12
|
+
* consequentialChecks, consumeInbound, InMemoryReplayGuard,
|
|
13
|
+
* StaticTransport, AclGrant_v0_1,
|
|
14
|
+
* } from "@openvtc/trust-tasks";
|
|
15
|
+
*
|
|
16
|
+
* // One guard per consumer, not one per document: it *is* the record.
|
|
17
|
+
* const guard = new InMemoryReplayGuard();
|
|
10
18
|
*
|
|
11
19
|
* const outcome = await consumeInbound({
|
|
12
20
|
* transport,
|
|
@@ -14,6 +22,8 @@
|
|
|
14
22
|
* proofPolicy: { kind: "verify", verify: myVerifier },
|
|
15
23
|
* // ajv, or whatever validator you already run — see PayloadPolicy.
|
|
16
24
|
* payloadPolicy: { kind: "validate", validate: myValidator },
|
|
25
|
+
* // acl/grant is consequential: a replayed envelope must not grant twice.
|
|
26
|
+
* checks: consequentialChecks(guard),
|
|
17
27
|
* doc,
|
|
18
28
|
* myVid: "did:web:maintainer.example",
|
|
19
29
|
* now: Date.now(),
|
|
@@ -27,6 +37,11 @@
|
|
|
27
37
|
* case "rejected": emit(outcome.error); break;
|
|
28
38
|
* case "suppressed": logSuppressed(); break;
|
|
29
39
|
* case "accepted": break; // fire-and-forget: nothing to emit
|
|
40
|
+
* // §7.2 item 11: already executed. Not an error — return the prior result
|
|
41
|
+
* // if there is one, otherwise emit nothing.
|
|
42
|
+
* case "duplicate":
|
|
43
|
+
* if (outcome.priorResponse !== undefined) emit(outcome.priorResponse);
|
|
44
|
+
* break;
|
|
30
45
|
* }
|
|
31
46
|
* ```
|
|
32
47
|
*
|
|
@@ -45,7 +60,32 @@
|
|
|
45
60
|
* `payloadPolicy` decides what to do with it. See {@link PayloadPolicy}.
|
|
46
61
|
*/
|
|
47
62
|
import { enforceSpecPolicy, rejectWith, toErrorPayload, validateBasic, } from "./document.js";
|
|
63
|
+
import { CONSEQUENTIAL_FRESHNESS, DEFAULT_FRESHNESS, STALE_WIRE_MESSAGE, recordExpiry, validateFreshness, } from "./freshness.js";
|
|
64
|
+
import { documentDigest, } from "./replay.js";
|
|
48
65
|
import { identityMismatchReason, reject, resolveParties, } from "./transport.js";
|
|
66
|
+
/**
|
|
67
|
+
* The posture for a *consequential Trust Task* (§2): item 11 enforced against
|
|
68
|
+
* `guard`, and the bounded acceptance window that makes the record droppable.
|
|
69
|
+
*
|
|
70
|
+
* The right choice for any task whose execution grants access, moves value,
|
|
71
|
+
* discloses a secret, or otherwise cannot be undone by ignoring the next
|
|
72
|
+
* document.
|
|
73
|
+
*/
|
|
74
|
+
export function consequentialChecks(guard) {
|
|
75
|
+
return { freshness: CONSEQUENTIAL_FRESHNESS, replay: { kind: "guard", guard } };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The posture for a task that is **not** consequential, or whose specification
|
|
79
|
+
* "explicitly declares repeated execution safe and intended" — the narrow
|
|
80
|
+
* disapplication item 11 permits.
|
|
81
|
+
*
|
|
82
|
+
* Keeps no record. Still applies the default freshness policy, because a
|
|
83
|
+
* future-dated document and one with an empty validity interval are malformed
|
|
84
|
+
* whatever the task does.
|
|
85
|
+
*/
|
|
86
|
+
export function notConsequentialChecks() {
|
|
87
|
+
return { freshness: DEFAULT_FRESHNESS, replay: { kind: "notConsequential" } };
|
|
88
|
+
}
|
|
49
89
|
/** Wire-safe message for the `rejectIfPresent` path. */
|
|
50
90
|
export const PROOF_NOT_ACCEPTED_BY_POLICY = "in-band proof not accepted by consumer policy (SPEC §7.2 item 7)";
|
|
51
91
|
/**
|
|
@@ -59,7 +99,7 @@ export const PROOF_NOT_ACCEPTED_BY_POLICY = "in-band proof not accepted by consu
|
|
|
59
99
|
* safe for ordinary refusals but not for one that contests that identity.
|
|
60
100
|
*/
|
|
61
101
|
export async function consumeInbound(opts) {
|
|
62
|
-
const { transport, spec, proofPolicy, payloadPolicy, doc, myVid, now, newErrorId, handler, clock } = opts;
|
|
102
|
+
const { transport, spec, proofPolicy, payloadPolicy, checks, doc, myVid, now, newErrorId, handler, clock, } = opts;
|
|
63
103
|
const route = (reason) => {
|
|
64
104
|
const error = reject(transport, doc, newErrorId(), reason, clock);
|
|
65
105
|
return error === undefined ? { kind: "suppressed", reason } : { kind: "rejected", error };
|
|
@@ -74,6 +114,16 @@ export async function consumeInbound(opts) {
|
|
|
74
114
|
"`spec.payloadSchema`, or { kind: \"acceptUnvalidated\" } to state that you " +
|
|
75
115
|
"are deliberately not checking it.");
|
|
76
116
|
}
|
|
117
|
+
// Same reasoning, for the check that decides whether a replayed envelope
|
|
118
|
+
// executes a second time. A JavaScript caller gets no compile-time check,
|
|
119
|
+
// and defaulting to "keep no record" would silently reproduce the defect
|
|
120
|
+
// this option exists to remove.
|
|
121
|
+
if (checks === undefined) {
|
|
122
|
+
throw new TypeError("consumeInbound: `checks` is required as of 0.12.18 (SPEC §7.2 items 4 and 11). " +
|
|
123
|
+
"Pass consequentialChecks(guard) for a task whose execution grants access, " +
|
|
124
|
+
"moves value or is otherwise irreversible, or notConsequentialChecks() to " +
|
|
125
|
+
"state that repeated execution of this task is safe and intended.");
|
|
126
|
+
}
|
|
77
127
|
// §7.2 item 2 — payload schema. Runs first, in the spec's own order, and
|
|
78
128
|
// before anything that reasons about what the payload means: a payload that
|
|
79
129
|
// is not the shape the specification declares should be refused as malformed
|
|
@@ -105,6 +155,15 @@ export async function consumeInbound(opts) {
|
|
|
105
155
|
const basic = validateBasic(doc, now, myVid);
|
|
106
156
|
if (basic !== null)
|
|
107
157
|
return route(basic);
|
|
158
|
+
// §7.2 item 4, the other half — the freshness bound over `issuedAt`.
|
|
159
|
+
// `validateBasic` honours `expiresAt`, which is optional and which a
|
|
160
|
+
// producer sets for its own reasons; on its own it leaves a document stamped
|
|
161
|
+
// years ago, or years hence, indefinitely acceptable. It is also what bounds
|
|
162
|
+
// the replay record below: §7.2 makes the acceptance window and the record's
|
|
163
|
+
// retention one bound.
|
|
164
|
+
const fresh = validateFreshness(doc, now, checks.freshness);
|
|
165
|
+
if (fresh !== null)
|
|
166
|
+
return route(fresh);
|
|
108
167
|
// §7.2 item 6 — in-band vs transport-derived identity cross-check.
|
|
109
168
|
const resolved = resolveParties(transport, doc);
|
|
110
169
|
if ("error" in resolved)
|
|
@@ -121,9 +180,15 @@ export async function consumeInbound(opts) {
|
|
|
121
180
|
ok = false;
|
|
122
181
|
}
|
|
123
182
|
if (!ok) {
|
|
183
|
+
// A constant, never the verifier's own error text. SPEC §10.4
|
|
184
|
+
// extends the §8.1 identity rule to every code, and a verifier's
|
|
185
|
+
// vocabulary names DIDs it tried to resolve, whether a resolver
|
|
186
|
+
// answered, and what a fetched DID document contained — a
|
|
187
|
+
// resolver-reachability oracle for a sender who is, by construction,
|
|
188
|
+
// unauthenticated. Log the detail; do not send it.
|
|
124
189
|
return route({
|
|
125
190
|
code: "proofInvalid",
|
|
126
|
-
message:
|
|
191
|
+
message: PROOF_INVALID_WIRE_MESSAGE,
|
|
127
192
|
retryable: false,
|
|
128
193
|
});
|
|
129
194
|
}
|
|
@@ -144,13 +209,114 @@ export async function consumeInbound(opts) {
|
|
|
144
209
|
const policy = enforceSpecPolicy(doc, spec);
|
|
145
210
|
if (policy !== null)
|
|
146
211
|
return route(policy);
|
|
212
|
+
// §7.2 item 11 — the duplicate-execution record. Deliberately **last**:
|
|
213
|
+
// claiming the `id` marks the document as accepted for execution, and a
|
|
214
|
+
// document some earlier check refuses was never accepted. Claiming first
|
|
215
|
+
// would burn the `id` on every malformed or unauthorised arrival, so a
|
|
216
|
+
// corrected resend under the same `id` would come back `idConflict` forever
|
|
217
|
+
// — and an attacker could pre-burn an `id` it had merely observed.
|
|
218
|
+
let claim;
|
|
219
|
+
if (checks.replay.kind === "guard") {
|
|
220
|
+
const { guard } = checks.replay;
|
|
221
|
+
const digest = documentDigest(doc);
|
|
222
|
+
// §7.2 (*Bounding the record*): "A consumer that can establish neither an
|
|
223
|
+
// `expiresAt` nor an age for a document has no window in which to place
|
|
224
|
+
// it, and MUST NOT execute a consequential Trust Task on it." A guard
|
|
225
|
+
// asked to retain a record forever is not a guard, so refuse rather than
|
|
226
|
+
// pretend.
|
|
227
|
+
const retainUntil = recordExpiry(doc, checks.freshness, now);
|
|
228
|
+
if (retainUntil === undefined) {
|
|
229
|
+
return route({ code: "expired", message: STALE_WIRE_MESSAGE, retryable: false });
|
|
230
|
+
}
|
|
231
|
+
let verdict;
|
|
232
|
+
try {
|
|
233
|
+
verdict = await guard.claim(doc.id, digest, retainUntil, now);
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
// Fail closed. A consumer that cannot consult its record has not
|
|
237
|
+
// satisfied item 11, and executing anyway is exactly the double
|
|
238
|
+
// execution the rule forbids. `unavailable` is retryable, which is the
|
|
239
|
+
// honest answer: the producer's bit-for-bit resend will be absorbed
|
|
240
|
+
// correctly once the store is back. The thrown detail — a hostname, a
|
|
241
|
+
// connection string — stays out of the message, per §10.4.
|
|
242
|
+
return route({
|
|
243
|
+
code: "unavailable",
|
|
244
|
+
message: REPLAY_RECORD_UNAVAILABLE,
|
|
245
|
+
retryable: true,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
switch (verdict.kind) {
|
|
249
|
+
case "duplicate":
|
|
250
|
+
return verdict.priorResponse === undefined
|
|
251
|
+
? { kind: "duplicate", inFlight: verdict.inFlight }
|
|
252
|
+
: { kind: "duplicate", priorResponse: verdict.priorResponse, inFlight: verdict.inFlight };
|
|
253
|
+
case "conflict":
|
|
254
|
+
return route({
|
|
255
|
+
code: "idConflict",
|
|
256
|
+
message: ID_CONFLICT_WIRE_MESSAGE,
|
|
257
|
+
retryable: false,
|
|
258
|
+
});
|
|
259
|
+
case "fresh":
|
|
260
|
+
claim = { guard, digest };
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
147
264
|
const result = await handler(doc, resolved.parties);
|
|
148
|
-
if (result === undefined || result === null)
|
|
265
|
+
if (result === undefined || result === null) {
|
|
266
|
+
// Fire-and-forget: nothing to cache, but the claim stands — the effect
|
|
267
|
+
// happened, and item 11 is about the effect, not about the response.
|
|
268
|
+
await settle(claim, doc.id, undefined);
|
|
149
269
|
return { kind: "accepted" };
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
:
|
|
270
|
+
}
|
|
271
|
+
if (isErrorResponse(result)) {
|
|
272
|
+
// §8.4: a retryable refusal has just invited the producer to re-send this
|
|
273
|
+
// document bit-for-bit. Holding the claim would answer that invited retry
|
|
274
|
+
// with the cached failure forever. A non-retryable refusal is final, so
|
|
275
|
+
// the record stands and a replay is answered with the same determination.
|
|
276
|
+
if (result.payload.retryable === true) {
|
|
277
|
+
await claim?.guard.release?.(doc.id, claim.digest);
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
await settle(claim, doc.id, result);
|
|
281
|
+
}
|
|
282
|
+
return { kind: "rejected", error: result };
|
|
283
|
+
}
|
|
284
|
+
await settle(claim, doc.id, result);
|
|
285
|
+
return { kind: "handled", response: result };
|
|
153
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Record the response for a completed execution, best-effort.
|
|
289
|
+
*
|
|
290
|
+
* The effect has already happened, so a guard that cannot cache the response
|
|
291
|
+
* cannot un-happen it. The record of the *claim* is what item 11 needs and it
|
|
292
|
+
* is already written; all that is lost is the ability to hand the same
|
|
293
|
+
* response back, and the duplicate is still absorbed. Guards should log their
|
|
294
|
+
* own failures — there is nowhere to report this from here.
|
|
295
|
+
*/
|
|
296
|
+
async function settle(claim, id, response) {
|
|
297
|
+
if (claim === undefined)
|
|
298
|
+
return;
|
|
299
|
+
try {
|
|
300
|
+
await claim.guard.recordResponse?.(id, response);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
/* see above */
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Wire message for `proofInvalid`.
|
|
308
|
+
*
|
|
309
|
+
* Constant by design — see the §10.4 note at the rejection site. The Rust
|
|
310
|
+
* counterpart is `PROOF_INVALID_WIRE_MESSAGE` in `trust-tasks-rs`, kept equal.
|
|
311
|
+
*/
|
|
312
|
+
export const PROOF_INVALID_WIRE_MESSAGE = "proof verification failed";
|
|
313
|
+
/** Wire message for `idConflict` (SPEC §7.2 item 11, §8.3). */
|
|
314
|
+
export const ID_CONFLICT_WIRE_MESSAGE = "a different document has already been accepted under this id (SPEC §7.2 item 11)";
|
|
315
|
+
/**
|
|
316
|
+
* Wire message for a replay-record outage. A constant, so a store's hostname
|
|
317
|
+
* or connection string never reaches the wire (SPEC §10.4).
|
|
318
|
+
*/
|
|
319
|
+
export const REPLAY_RECORD_UNAVAILABLE = "temporarily unavailable";
|
|
154
320
|
/**
|
|
155
321
|
* Whether a handler returned an error response rather than a success response.
|
|
156
322
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consume.js","sourceRoot":"","sources":["../../src/_runtime/consume.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"consume.js","sourceRoot":"","sources":["../../src/_runtime/consume.ts"],"names":[],"mappings":"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"}
|
|
@@ -184,10 +184,23 @@ export interface RejectReason {
|
|
|
184
184
|
/**
|
|
185
185
|
* The Type URI a consumer emits error responses under.
|
|
186
186
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
187
|
+
* **The single source of truth for the emitted `trust-task-error` version on
|
|
188
|
+
* this side.** Three different answers were in circulation — this runtime and
|
|
189
|
+
* `trust-tasks-rs` emitted `0.5`, the HTTPS server emitted `0.2`, and the
|
|
190
|
+
* READMEs described `0.1` — so a producer could not tell from the
|
|
191
|
+
* documentation which schema an error response would validate against. Build
|
|
192
|
+
* error responses with `rejectWith` / `rejectWithRecipient`, or read the URI
|
|
193
|
+
* from here; do not spell it out again.
|
|
194
|
+
*
|
|
195
|
+
* The Rust counterpart is `trust_task_error_type_uri()` in `trust-tasks-rs`,
|
|
196
|
+
* kept equal to this value.
|
|
197
|
+
*
|
|
198
|
+
* `0.5` because this runtime populates the `inResponseTo` member of §8.2 and
|
|
199
|
+
* can emit `idConflict` (§8.3), which is absent from `0.3`'s code enum and does
|
|
200
|
+
* not match its extended-code pattern — a document carrying it would not
|
|
201
|
+
* validate as `0.3`. Per §5.2 forward-minor compatibility a `0.3` consumer
|
|
202
|
+
* SHOULD accept it. (This comment said `0.3` while the value said `0.5`: the
|
|
203
|
+
* value moved and the prose did not.)
|
|
191
204
|
*/
|
|
192
205
|
export declare const TRUST_TASK_ERROR_TYPE_URI = "https://trusttasks.org/spec/trust-task-error/0.5";
|
|
193
206
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/_runtime/document.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/_runtime/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,10 +8,23 @@ import { normalizeCode } from "./codes.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* The Type URI a consumer emits error responses under.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* **The single source of truth for the emitted `trust-task-error` version on
|
|
12
|
+
* this side.** Three different answers were in circulation — this runtime and
|
|
13
|
+
* `trust-tasks-rs` emitted `0.5`, the HTTPS server emitted `0.2`, and the
|
|
14
|
+
* READMEs described `0.1` — so a producer could not tell from the
|
|
15
|
+
* documentation which schema an error response would validate against. Build
|
|
16
|
+
* error responses with `rejectWith` / `rejectWithRecipient`, or read the URI
|
|
17
|
+
* from here; do not spell it out again.
|
|
18
|
+
*
|
|
19
|
+
* The Rust counterpart is `trust_task_error_type_uri()` in `trust-tasks-rs`,
|
|
20
|
+
* kept equal to this value.
|
|
21
|
+
*
|
|
22
|
+
* `0.5` because this runtime populates the `inResponseTo` member of §8.2 and
|
|
23
|
+
* can emit `idConflict` (§8.3), which is absent from `0.3`'s code enum and does
|
|
24
|
+
* not match its extended-code pattern — a document carrying it would not
|
|
25
|
+
* validate as `0.3`. Per §5.2 forward-minor compatibility a `0.3` consumer
|
|
26
|
+
* SHOULD accept it. (This comment said `0.3` while the value said `0.5`: the
|
|
27
|
+
* value moved and the prose did not.)
|
|
15
28
|
*/
|
|
16
29
|
export const TRUST_TASK_ERROR_TYPE_URI = "https://trusttasks.org/spec/trust-task-error/0.5";
|
|
17
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/_runtime/document.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAqB,MAAM,YAAY,CAAC;AA2L9D
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/_runtime/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Freshness bounds over `issuedAt` / `expiresAt` (SPEC §4.2, §7.2).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `freshness.rs` in trust-tasks-rs, deliberately closely: a TypeScript
|
|
5
|
+
* consumer and a Rust one must reach the same verdict on the same document.
|
|
6
|
+
*
|
|
7
|
+
* Until this module, the only temporal check either runtime made was §7.2
|
|
8
|
+
* item 4 — `expiresAt`, and only where the producer chose to set it.
|
|
9
|
+
* `issuedAt` was carried on the type and looked at by nobody. That accepted a
|
|
10
|
+
* document stamped a year in the future (for the whole of that year), and one
|
|
11
|
+
* whose `expiresAt` sat at or before its own `issuedAt` — a validity interval
|
|
12
|
+
* that never contained a valid instant.
|
|
13
|
+
*
|
|
14
|
+
* It is also what makes {@link ReplayGuard} implementable. SPEC §7.2
|
|
15
|
+
* (*Bounding the record*) ties the duplicate-execution record to the
|
|
16
|
+
* acceptance window and says the two bounds are the same bound: a consumer
|
|
17
|
+
* "**MUST NOT** accept for execution a document older than the window over
|
|
18
|
+
* which it retains records". Without {@link FreshnessPolicy.maxAgeMs} there is
|
|
19
|
+
* no window, so a record for a document carrying no `expiresAt` would have to
|
|
20
|
+
* be kept forever.
|
|
21
|
+
*/
|
|
22
|
+
import type { RejectReason, TrustTaskDocument } from "./document.js";
|
|
23
|
+
/** The clock-skew tolerance SPEC §4.2 sanctions ("typically ≤ 60s"), in ms. */
|
|
24
|
+
export declare const DEFAULT_SKEW_MS = 60000;
|
|
25
|
+
/**
|
|
26
|
+
* The acceptance window {@link consequentialFreshness} applies, in ms.
|
|
27
|
+
*
|
|
28
|
+
* Five minutes survives a mediator queue, a retry with backoff and a modest
|
|
29
|
+
* clock disagreement, and keeps the record it bounds small. A deployment whose
|
|
30
|
+
* transport buffers for longer must widen it *and* widen its guard's retention
|
|
31
|
+
* to match — §7.2 makes them one bound.
|
|
32
|
+
*/
|
|
33
|
+
export declare const DEFAULT_MAX_AGE_MS: number;
|
|
34
|
+
/** How a consumer bounds a document in time before acting on it. */
|
|
35
|
+
export interface FreshnessPolicy {
|
|
36
|
+
/**
|
|
37
|
+
* Tolerance applied to the document's timestamps against this consumer's
|
|
38
|
+
* clock, per SPEC §4.2. Applied to the future-dating check and to
|
|
39
|
+
* {@link maxAgeMs}; **not** to `expiresAt`, which `validateBasic` compares
|
|
40
|
+
* against the raw `now` it is given.
|
|
41
|
+
*/
|
|
42
|
+
readonly skewMs: number;
|
|
43
|
+
/**
|
|
44
|
+
* Oldest `issuedAt` this consumer accepts, measured back from `now`.
|
|
45
|
+
* `undefined` means unbounded — the pre-existing behaviour, and the only
|
|
46
|
+
* setting under which a document carrying neither timestamp is acceptable.
|
|
47
|
+
*/
|
|
48
|
+
readonly maxAgeMs?: number;
|
|
49
|
+
/** Reject a document carrying no `issuedAt`, with `malformedRequest`. */
|
|
50
|
+
readonly requireIssuedAt?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The minimum every consumer should apply: reject a future-dated document and
|
|
54
|
+
* one whose stated validity interval is empty. No conforming producer emits
|
|
55
|
+
* either, so this costs a correct deployment nothing.
|
|
56
|
+
*
|
|
57
|
+
* Deliberately sets no `maxAgeMs` — an acceptance window depends on how long
|
|
58
|
+
* the transport may hold a message, which is a deployment fact, and a library
|
|
59
|
+
* that guessed one would start refusing documents that had arrived for years.
|
|
60
|
+
*/
|
|
61
|
+
export declare const DEFAULT_FRESHNESS: FreshnessPolicy;
|
|
62
|
+
/**
|
|
63
|
+
* The posture SPEC §7.2 (*Bounding the record*) describes for a *consequential
|
|
64
|
+
* Trust Task*: `issuedAt` REQUIRED and a bounded acceptance window, so every
|
|
65
|
+
* accepted document sits inside a window a {@link ReplayGuard} can retain a
|
|
66
|
+
* record for.
|
|
67
|
+
*/
|
|
68
|
+
export declare const CONSEQUENTIAL_FRESHNESS: FreshnessPolicy;
|
|
69
|
+
/** Wire-safe reason for a `malformedRequest` from a future-dated `issuedAt`. */
|
|
70
|
+
export declare const FUTURE_ISSUED_AT = "issuedAt is in the future beyond the consumer's skew tolerance (SPEC \u00A74.2)";
|
|
71
|
+
/** Wire-safe reason for a `malformedRequest` from `expiresAt <= issuedAt`. */
|
|
72
|
+
export declare const EXPIRY_NOT_AFTER_ISSUANCE = "expiresAt is not after issuedAt: the document states an empty validity interval (SPEC \u00A74.2)";
|
|
73
|
+
/** Wire-safe reason for a `malformedRequest` from a missing `issuedAt`. */
|
|
74
|
+
export declare const ISSUED_AT_REQUIRED = "issuedAt is required by consumer policy (SPEC \u00A77.2, bounding the duplicate-execution record)";
|
|
75
|
+
/**
|
|
76
|
+
* Wire message for a document outside the consumer's acceptance window.
|
|
77
|
+
*
|
|
78
|
+
* A constant, not a rendering of the window or the consumer's clock: §10.4
|
|
79
|
+
* keeps consumer-side state off the wire, and echoing the delta would turn
|
|
80
|
+
* every rejection into a remote `ntpdate` — and a probe for the window's exact
|
|
81
|
+
* boundary — for an unauthenticated sender.
|
|
82
|
+
*/
|
|
83
|
+
export declare const STALE_WIRE_MESSAGE = "document is outside the consumer's acceptance window (SPEC \u00A77.2)";
|
|
84
|
+
/**
|
|
85
|
+
* Apply `policy` to this document's `issuedAt` / `expiresAt`. Returns `null`
|
|
86
|
+
* when the document is acceptable.
|
|
87
|
+
*
|
|
88
|
+
* This is the freshness half of SPEC §7.2 item 4 that `validateBasic` does not
|
|
89
|
+
* cover. {@link consumeInbound} calls it for you.
|
|
90
|
+
*
|
|
91
|
+
* @param now Milliseconds since the epoch, as from `Date.now()`.
|
|
92
|
+
*/
|
|
93
|
+
export declare function validateFreshness<P>(doc: TrustTaskDocument<P>, now: number, policy: FreshnessPolicy): RejectReason | null;
|
|
94
|
+
/**
|
|
95
|
+
* The instant past which a replay record for `doc` may be dropped — the end of
|
|
96
|
+
* this consumer's willingness to execute it, which SPEC §7.2 makes the same
|
|
97
|
+
* instant as the end of the record's required retention.
|
|
98
|
+
*
|
|
99
|
+
* `expiresAt` fixes it where present; otherwise `issuedAt + maxAgeMs`.
|
|
100
|
+
* `undefined` means this policy places no bound on the document, in which case
|
|
101
|
+
* a consumer **MUST NOT** execute a consequential task on it — there is no
|
|
102
|
+
* window in which to keep the record.
|
|
103
|
+
*/
|
|
104
|
+
export declare function recordExpiry<P>(doc: TrustTaskDocument<P>, policy: FreshnessPolicy, now: number): number | undefined;
|
|
105
|
+
//# sourceMappingURL=freshness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freshness.d.ts","sourceRoot":"","sources":["../../src/_runtime/freshness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAErE,+EAA+E;AAC/E,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAE7C,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,EAAE,eAA6C,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,eAIrC,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,oFACiD,CAAC;AAE/E,8EAA8E;AAC9E,eAAO,MAAM,yBAAyB,qGACyD,CAAC;AAEhG,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,sGACiE,CAAC;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,0EAAqE,CAAC;AAErG;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,eAAe,GACtB,YAAY,GAAG,IAAI,CAyCrB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,eAAe,EACvB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAWpB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Freshness bounds over `issuedAt` / `expiresAt` (SPEC §4.2, §7.2).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `freshness.rs` in trust-tasks-rs, deliberately closely: a TypeScript
|
|
5
|
+
* consumer and a Rust one must reach the same verdict on the same document.
|
|
6
|
+
*
|
|
7
|
+
* Until this module, the only temporal check either runtime made was §7.2
|
|
8
|
+
* item 4 — `expiresAt`, and only where the producer chose to set it.
|
|
9
|
+
* `issuedAt` was carried on the type and looked at by nobody. That accepted a
|
|
10
|
+
* document stamped a year in the future (for the whole of that year), and one
|
|
11
|
+
* whose `expiresAt` sat at or before its own `issuedAt` — a validity interval
|
|
12
|
+
* that never contained a valid instant.
|
|
13
|
+
*
|
|
14
|
+
* It is also what makes {@link ReplayGuard} implementable. SPEC §7.2
|
|
15
|
+
* (*Bounding the record*) ties the duplicate-execution record to the
|
|
16
|
+
* acceptance window and says the two bounds are the same bound: a consumer
|
|
17
|
+
* "**MUST NOT** accept for execution a document older than the window over
|
|
18
|
+
* which it retains records". Without {@link FreshnessPolicy.maxAgeMs} there is
|
|
19
|
+
* no window, so a record for a document carrying no `expiresAt` would have to
|
|
20
|
+
* be kept forever.
|
|
21
|
+
*/
|
|
22
|
+
/** The clock-skew tolerance SPEC §4.2 sanctions ("typically ≤ 60s"), in ms. */
|
|
23
|
+
export const DEFAULT_SKEW_MS = 60_000;
|
|
24
|
+
/**
|
|
25
|
+
* The acceptance window {@link consequentialFreshness} applies, in ms.
|
|
26
|
+
*
|
|
27
|
+
* Five minutes survives a mediator queue, a retry with backoff and a modest
|
|
28
|
+
* clock disagreement, and keeps the record it bounds small. A deployment whose
|
|
29
|
+
* transport buffers for longer must widen it *and* widen its guard's retention
|
|
30
|
+
* to match — §7.2 makes them one bound.
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_MAX_AGE_MS = 5 * 60_000;
|
|
33
|
+
/**
|
|
34
|
+
* The minimum every consumer should apply: reject a future-dated document and
|
|
35
|
+
* one whose stated validity interval is empty. No conforming producer emits
|
|
36
|
+
* either, so this costs a correct deployment nothing.
|
|
37
|
+
*
|
|
38
|
+
* Deliberately sets no `maxAgeMs` — an acceptance window depends on how long
|
|
39
|
+
* the transport may hold a message, which is a deployment fact, and a library
|
|
40
|
+
* that guessed one would start refusing documents that had arrived for years.
|
|
41
|
+
*/
|
|
42
|
+
export const DEFAULT_FRESHNESS = { skewMs: DEFAULT_SKEW_MS };
|
|
43
|
+
/**
|
|
44
|
+
* The posture SPEC §7.2 (*Bounding the record*) describes for a *consequential
|
|
45
|
+
* Trust Task*: `issuedAt` REQUIRED and a bounded acceptance window, so every
|
|
46
|
+
* accepted document sits inside a window a {@link ReplayGuard} can retain a
|
|
47
|
+
* record for.
|
|
48
|
+
*/
|
|
49
|
+
export const CONSEQUENTIAL_FRESHNESS = {
|
|
50
|
+
skewMs: DEFAULT_SKEW_MS,
|
|
51
|
+
maxAgeMs: DEFAULT_MAX_AGE_MS,
|
|
52
|
+
requireIssuedAt: true,
|
|
53
|
+
};
|
|
54
|
+
/** Wire-safe reason for a `malformedRequest` from a future-dated `issuedAt`. */
|
|
55
|
+
export const FUTURE_ISSUED_AT = "issuedAt is in the future beyond the consumer's skew tolerance (SPEC §4.2)";
|
|
56
|
+
/** Wire-safe reason for a `malformedRequest` from `expiresAt <= issuedAt`. */
|
|
57
|
+
export const EXPIRY_NOT_AFTER_ISSUANCE = "expiresAt is not after issuedAt: the document states an empty validity interval (SPEC §4.2)";
|
|
58
|
+
/** Wire-safe reason for a `malformedRequest` from a missing `issuedAt`. */
|
|
59
|
+
export const ISSUED_AT_REQUIRED = "issuedAt is required by consumer policy (SPEC §7.2, bounding the duplicate-execution record)";
|
|
60
|
+
/**
|
|
61
|
+
* Wire message for a document outside the consumer's acceptance window.
|
|
62
|
+
*
|
|
63
|
+
* A constant, not a rendering of the window or the consumer's clock: §10.4
|
|
64
|
+
* keeps consumer-side state off the wire, and echoing the delta would turn
|
|
65
|
+
* every rejection into a remote `ntpdate` — and a probe for the window's exact
|
|
66
|
+
* boundary — for an unauthenticated sender.
|
|
67
|
+
*/
|
|
68
|
+
export const STALE_WIRE_MESSAGE = "document is outside the consumer's acceptance window (SPEC §7.2)";
|
|
69
|
+
/**
|
|
70
|
+
* Apply `policy` to this document's `issuedAt` / `expiresAt`. Returns `null`
|
|
71
|
+
* when the document is acceptable.
|
|
72
|
+
*
|
|
73
|
+
* This is the freshness half of SPEC §7.2 item 4 that `validateBasic` does not
|
|
74
|
+
* cover. {@link consumeInbound} calls it for you.
|
|
75
|
+
*
|
|
76
|
+
* @param now Milliseconds since the epoch, as from `Date.now()`.
|
|
77
|
+
*/
|
|
78
|
+
export function validateFreshness(doc, now, policy) {
|
|
79
|
+
const malformed = (message) => ({
|
|
80
|
+
code: "malformedRequest",
|
|
81
|
+
message,
|
|
82
|
+
retryable: false,
|
|
83
|
+
});
|
|
84
|
+
const stale = () => ({
|
|
85
|
+
code: "expired",
|
|
86
|
+
message: STALE_WIRE_MESSAGE,
|
|
87
|
+
retryable: false,
|
|
88
|
+
});
|
|
89
|
+
if (doc.issuedAt !== undefined) {
|
|
90
|
+
const issuedAt = Date.parse(doc.issuedAt);
|
|
91
|
+
if (Number.isNaN(issuedAt)) {
|
|
92
|
+
return malformed("issuedAt is not a valid RFC 3339 timestamp");
|
|
93
|
+
}
|
|
94
|
+
if (issuedAt > now + policy.skewMs)
|
|
95
|
+
return malformed(FUTURE_ISSUED_AT);
|
|
96
|
+
if (doc.expiresAt !== undefined) {
|
|
97
|
+
const expiresAt = Date.parse(doc.expiresAt);
|
|
98
|
+
// A malformed `expiresAt` is `validateBasic`'s to report; skip it here
|
|
99
|
+
// rather than raise a second, differently-worded rejection for it.
|
|
100
|
+
if (!Number.isNaN(expiresAt) && expiresAt <= issuedAt) {
|
|
101
|
+
return malformed(EXPIRY_NOT_AFTER_ISSUANCE);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (policy.maxAgeMs !== undefined && issuedAt + policy.maxAgeMs + policy.skewMs < now) {
|
|
105
|
+
return stale();
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (policy.requireIssuedAt === true)
|
|
110
|
+
return malformed(ISSUED_AT_REQUIRED);
|
|
111
|
+
// No `issuedAt`. A policy with a window cannot place the document in it
|
|
112
|
+
// unless the producer supplied an `expiresAt` instead (SPEC §7.2, *Bounding
|
|
113
|
+
// the record*).
|
|
114
|
+
if (policy.maxAgeMs !== undefined && doc.expiresAt === undefined)
|
|
115
|
+
return stale();
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The instant past which a replay record for `doc` may be dropped — the end of
|
|
120
|
+
* this consumer's willingness to execute it, which SPEC §7.2 makes the same
|
|
121
|
+
* instant as the end of the record's required retention.
|
|
122
|
+
*
|
|
123
|
+
* `expiresAt` fixes it where present; otherwise `issuedAt + maxAgeMs`.
|
|
124
|
+
* `undefined` means this policy places no bound on the document, in which case
|
|
125
|
+
* a consumer **MUST NOT** execute a consequential task on it — there is no
|
|
126
|
+
* window in which to keep the record.
|
|
127
|
+
*/
|
|
128
|
+
export function recordExpiry(doc, policy, now) {
|
|
129
|
+
if (doc.expiresAt !== undefined) {
|
|
130
|
+
const expiresAt = Date.parse(doc.expiresAt);
|
|
131
|
+
if (!Number.isNaN(expiresAt))
|
|
132
|
+
return expiresAt;
|
|
133
|
+
}
|
|
134
|
+
if (policy.maxAgeMs === undefined)
|
|
135
|
+
return undefined;
|
|
136
|
+
const issuedAt = doc.issuedAt === undefined ? NaN : Date.parse(doc.issuedAt);
|
|
137
|
+
// Fall back to `now` when the producer stamped no usable `issuedAt`: the
|
|
138
|
+
// record then lives a full window from first sight, which is the longest the
|
|
139
|
+
// document could still be arriving from a queue.
|
|
140
|
+
return (Number.isNaN(issuedAt) ? now : issuedAt) + policy.maxAgeMs;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=freshness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freshness.js","sourceRoot":"","sources":["../../src/_runtime/freshness.ts"],"names":[],"mappings":"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"}
|