@interop/wallet-core 0.45.0 → 0.47.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/keyring/record.d.ts +4 -3
- package/dist/keyring/record.d.ts.map +1 -1
- package/dist/keyring/record.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts.map +1 -1
- package/dist/keys/rosterLogStore.js +18 -1
- package/dist/keys/rosterLogStore.js.map +1 -1
- package/dist/keys/rosterStore.d.ts +25 -1
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +6 -2
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/recovery/index.d.ts +1 -1
- package/dist/recovery/index.d.ts.map +1 -1
- package/dist/recovery/index.js +1 -1
- package/dist/recovery/index.js.map +1 -1
- package/dist/recovery/recoveryDelegation.d.ts +27 -40
- package/dist/recovery/recoveryDelegation.d.ts.map +1 -1
- package/dist/recovery/recoveryDelegation.js +119 -53
- package/dist/recovery/recoveryDelegation.js.map +1 -1
- package/dist/resourceLog/controller.d.ts +38 -3
- package/dist/resourceLog/controller.d.ts.map +1 -1
- package/dist/resourceLog/controller.js +106 -10
- package/dist/resourceLog/controller.js.map +1 -1
- package/dist/resourceLog/errors.d.ts +22 -1
- package/dist/resourceLog/errors.d.ts.map +1 -1
- package/dist/resourceLog/errors.js +23 -1
- package/dist/resourceLog/errors.js.map +1 -1
- package/dist/resourceLog/index.d.ts +8 -6
- package/dist/resourceLog/index.d.ts.map +1 -1
- package/dist/resourceLog/index.js +7 -5
- package/dist/resourceLog/index.js.map +1 -1
- package/dist/resourceLog/license.d.ts +44 -0
- package/dist/resourceLog/license.d.ts.map +1 -0
- package/dist/resourceLog/license.js +63 -0
- package/dist/resourceLog/license.js.map +1 -0
- package/dist/resourceLog/verify.d.ts +3 -2
- package/dist/resourceLog/verify.d.ts.map +1 -1
- package/dist/resourceLog/verify.js +30 -8
- package/dist/resourceLog/verify.js.map +1 -1
- package/dist/unlock/index.d.ts +17 -8
- package/dist/unlock/index.d.ts.map +1 -1
- package/dist/unlock/index.js +17 -8
- package/dist/unlock/index.js.map +1 -1
- package/dist/unlock/ladder.d.ts +76 -0
- package/dist/unlock/ladder.d.ts.map +1 -1
- package/dist/unlock/ladder.js +111 -1
- package/dist/unlock/ladder.js.map +1 -1
- package/dist/unlock/standingWebvh.d.ts +39 -0
- package/dist/unlock/standingWebvh.d.ts.map +1 -1
- package/dist/unlock/standingWebvh.js +69 -4
- package/dist/unlock/standingWebvh.js.map +1 -1
- package/dist/unlock/unlockRecord.d.ts +28 -8
- package/dist/unlock/unlockRecord.d.ts.map +1 -1
- package/dist/unlock/unlockRecord.js +93 -13
- package/dist/unlock/unlockRecord.js.map +1 -1
- package/dist/webvh/companion.d.ts +681 -0
- package/dist/webvh/companion.d.ts.map +1 -0
- package/dist/webvh/companion.js +1151 -0
- package/dist/webvh/companion.js.map +1 -0
- package/dist/webvh/delegatedLogStore.d.ts +67 -0
- package/dist/webvh/delegatedLogStore.d.ts.map +1 -0
- package/dist/webvh/delegatedLogStore.js +104 -0
- package/dist/webvh/delegatedLogStore.js.map +1 -0
- package/dist/webvh/didWebvh.d.ts +109 -5
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +186 -21
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +34 -5
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +31 -5
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +33 -0
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +27 -0
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/standingZcap.d.ts +48 -0
- package/dist/webvh/standingZcap.d.ts.map +1 -0
- package/dist/webvh/standingZcap.js +54 -0
- package/dist/webvh/standingZcap.js.map +1 -0
- package/dist/webvh/wasIdStore.d.ts +36 -6
- package/dist/webvh/wasIdStore.d.ts.map +1 -1
- package/dist/webvh/wasIdStore.js +32 -13
- package/dist/webvh/wasIdStore.js.map +1 -1
- package/dist/webvh/zcap.d.ts +24 -0
- package/dist/webvh/zcap.d.ts.map +1 -1
- package/dist/webvh/zcap.js +42 -0
- package/dist/webvh/zcap.js.map +1 -1
- package/package.json +9 -9
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
* record to the code's unlock KAK (the public half the registry records --
|
|
23
23
|
* the record carries no secrets, so re-encryption needs none), re-PUTs it
|
|
24
24
|
* through the entry's management zcap, and updates the registry's
|
|
25
|
-
* `delegationKeyId` and `delegationExpires`.
|
|
25
|
+
* `delegationKeyId` and `delegationExpires`. A standing credential's
|
|
26
|
+
* companion-Space sibling delegation rides the same pass (its scalar pair is
|
|
27
|
+
* `delegatedClientsKeyId` / `delegatedClientsExpires`): either member going
|
|
28
|
+
* stale reseals both, and the one registry rewrite records both fresh pairs
|
|
29
|
+
* -- a re-mint handling only the bridge is incomplete. The skip policy is
|
|
26
30
|
* cross-replica correctness and is
|
|
27
31
|
* decided here once: an entry that predates the re-mint fields, or whose
|
|
28
32
|
* standing record cannot be read or carries no binding, is skipped and stays
|
|
@@ -31,66 +35,48 @@
|
|
|
31
35
|
* registry read/record halves.
|
|
32
36
|
*/
|
|
33
37
|
import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
|
|
38
|
+
import { resourcePath, toUrl } from '@interop/was-client/paths';
|
|
34
39
|
import { DID_LOG_RESOURCE, ID_COLLECTION } from '../space/collections.js';
|
|
35
40
|
import { delegationKeyInDocument } from '../webvh/listClients.js';
|
|
36
41
|
import { getUnlockKeyringWithCapability, putUnlockKeyringWithCapability } from '../keyring/unlockSpace.js';
|
|
37
|
-
import {
|
|
42
|
+
import { remintUnlockRecordDelegations } from '../unlock/unlockRecord.js';
|
|
43
|
+
import { STANDING_ZCAP_TTL_MS, zcapExpiring } from '../webvh/standingZcap.js';
|
|
44
|
+
import { companionDidParts, delegatedClientsPointer, mintDelegatedClientsDelegation } from '../webvh/companion.js';
|
|
38
45
|
/**
|
|
39
|
-
* The recovery delegation's lifetime:
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* document).
|
|
46
|
+
* The recovery delegation's lifetime: the house standing-zcap value
|
|
47
|
+
* ({@link STANDING_ZCAP_TTL_MS} -- one year, per NIST SP 800-57's
|
|
48
|
+
* cryptoperiod guidance; see `webvh/standingZcap.ts`, the policy's one
|
|
49
|
+
* home). The delegation's scope stays narrow (PUT on the one world-readable
|
|
50
|
+
* DID log resource, whose worst-case abuse is a log write that still has to
|
|
51
|
+
* verify against the published hash chain and prerotation commitments to
|
|
52
|
+
* resolve). A code must keep working past the year, so expiry is watched
|
|
53
|
+
* rather than terminal: the registry entry records the delegation's
|
|
54
|
+
* `expires`, {@link zcapExpiring} treats the renewal window before it as
|
|
55
|
+
* stale, the re-mint refreshes a stale delegation, and the login-time
|
|
56
|
+
* recovery health check flags one the same way it flags rot (the signing
|
|
57
|
+
* client's verification method leaving the document).
|
|
52
58
|
*/
|
|
53
|
-
export const RECOVERY_DELEGATION_TTL_MS =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* regenerate nudge lands well before the zcap actually lapses.
|
|
58
|
-
*/
|
|
59
|
-
export const ZCAP_RENEWAL_WINDOW_MS = 30 * 24 * 60 * 60 * 1000;
|
|
60
|
-
/**
|
|
61
|
-
* Whether a recorded zcap expiry is past or inside the renewal window -- the
|
|
62
|
-
* expiry half of the staleness predicate for every long-lived zcap a wallet
|
|
63
|
-
* records beside its registry entries (the recovery `did.jsonl` delegation,
|
|
64
|
-
* an unlock Space's management zcap). The re-mint and the wallets'
|
|
65
|
-
* login-time checks all ask this one predicate. A record carrying no expiry
|
|
66
|
-
* (or an unparseable one) is uncheckable and therefore not assumed healthy,
|
|
67
|
-
* matching the rot check's treatment of a missing `delegationKeyId`.
|
|
68
|
-
*
|
|
69
|
-
* @param options {object}
|
|
70
|
-
* @param [options.expires] {string} the recorded ISO 8601 expiry
|
|
71
|
-
* @param [options.now] {number} epoch milliseconds, for tests
|
|
72
|
-
* @returns {boolean}
|
|
73
|
-
*/
|
|
74
|
-
export function zcapExpiring({ expires, now = Date.now() }) {
|
|
75
|
-
if (!expires) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
const expiresAt = Date.parse(expires);
|
|
79
|
-
if (Number.isNaN(expiresAt)) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
return expiresAt - now <= ZCAP_RENEWAL_WINDOW_MS;
|
|
83
|
-
}
|
|
59
|
+
export const RECOVERY_DELEGATION_TTL_MS = STANDING_ZCAP_TTL_MS;
|
|
60
|
+
// Re-exported from their shared leaf home (`webvh/standingZcap.ts`), so this
|
|
61
|
+
// module's public surface predating the move is unchanged.
|
|
62
|
+
export { ZCAP_RENEWAL_WINDOW_MS, zcapExpiring } from '../webvh/standingZcap.js';
|
|
84
63
|
/**
|
|
85
64
|
* The absolute URL of the account's `did.jsonl` log resource -- the
|
|
86
|
-
* invocation target of the pre-minted recovery delegation.
|
|
65
|
+
* invocation target of the pre-minted recovery delegation. Built with
|
|
66
|
+
* was-client's path builders, the one owner of the WAS path grammar, so the
|
|
67
|
+
* path is joined onto the pointer host's base path (a sub-path deployment
|
|
68
|
+
* keeps its prefix) and the minted target matches the URL the server checks
|
|
69
|
+
* it against byte for byte.
|
|
87
70
|
*
|
|
88
71
|
* @param options {object}
|
|
89
72
|
* @param options.pointer {AccountPointer}
|
|
90
73
|
* @returns {string}
|
|
91
74
|
*/
|
|
92
75
|
function didLogUrl({ pointer }) {
|
|
93
|
-
return
|
|
76
|
+
return toUrl({
|
|
77
|
+
serverUrl: pointer.host,
|
|
78
|
+
path: resourcePath(pointer.spaceId, ID_COLLECTION.id, DID_LOG_RESOURCE)
|
|
79
|
+
});
|
|
94
80
|
}
|
|
95
81
|
/**
|
|
96
82
|
* Delegates the narrow log-write bridge to a code-derived client: PUT on the
|
|
@@ -126,6 +112,33 @@ export function delegationProofKeyId(delegation) {
|
|
|
126
112
|
const single = Array.isArray(proof) ? proof[0] : proof;
|
|
127
113
|
return single?.verificationMethod;
|
|
128
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* The auxiliary companion Space id the account document currently points at,
|
|
117
|
+
* read off its delegated-clients service entry (the companion DID string
|
|
118
|
+
* embeds the Space id) -- what the re-mint rebuilds a sibling delegation's
|
|
119
|
+
* target from. `undefined` while the account points at no generation.
|
|
120
|
+
*
|
|
121
|
+
* @param options {object}
|
|
122
|
+
* @param options.doc {PublishedKeyDocument} the locally verified document
|
|
123
|
+
* @returns {string | undefined}
|
|
124
|
+
*/
|
|
125
|
+
function companionSpaceIdFromDocument({ doc }) {
|
|
126
|
+
// The verified document callers pass is the full resolved DID document;
|
|
127
|
+
// `PublishedKeyDocument` is its structural narrowing, and the companion
|
|
128
|
+
// helper runtime-checks the service list it reads.
|
|
129
|
+
const companionDid = delegatedClientsPointer({
|
|
130
|
+
doc: doc
|
|
131
|
+
});
|
|
132
|
+
if (!companionDid) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
return companionDidParts({ did: companionDid }).spaceId;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
129
142
|
/**
|
|
130
143
|
* Re-mints the recovery delegations the current document no longer backs --
|
|
131
144
|
* the recovery-code delta riding the revocation cascade (see the module doc
|
|
@@ -133,7 +146,11 @@ export function delegationProofKeyId(delegation) {
|
|
|
133
146
|
*
|
|
134
147
|
* The record's credential-authenticated core is preserved verbatim: the
|
|
135
148
|
* re-mint reads the standing record through the entry's management zcap and
|
|
136
|
-
* replaces only its
|
|
149
|
+
* replaces only its delegation members
|
|
150
|
+
* ({@link remintUnlockRecordDelegations}) -- the bridge always, and the
|
|
151
|
+
* companion-Space sibling where the entry records one (the two rot on one
|
|
152
|
+
* axis, so both reseal in the same atomic pass and one registry-entry
|
|
153
|
+
* rewrite records both fresh pairs). The
|
|
137
154
|
* shell, the ladder member (where one rides), and the binding tag all travel
|
|
138
155
|
* untouched, since the re-mint can decrypt none of them and does not need to.
|
|
139
156
|
* A re-mint therefore can never change the pointer or controller the
|
|
@@ -185,7 +202,24 @@ export async function remintRecoveryDelegations({ doc, entries, pointer, storage
|
|
|
185
202
|
const expiring = zcapExpiring({
|
|
186
203
|
...(entry.delegationExpires ? { expires: entry.delegationExpires } : {})
|
|
187
204
|
});
|
|
188
|
-
|
|
205
|
+
// The companion-Space sibling, where the entry records one, is checked
|
|
206
|
+
// on the same two axes; either member going stale re-mints BOTH in one
|
|
207
|
+
// atomic pass (both resealed, one registry-entry rewrite).
|
|
208
|
+
const siblingRecorded = entry.delegatedClientsKeyId !== undefined ||
|
|
209
|
+
entry.delegatedClientsExpires !== undefined;
|
|
210
|
+
const siblingStale = siblingRecorded &&
|
|
211
|
+
(!delegationKeyInDocument({
|
|
212
|
+
doc,
|
|
213
|
+
...(entry.delegatedClientsKeyId
|
|
214
|
+
? { delegationKeyId: entry.delegatedClientsKeyId }
|
|
215
|
+
: {})
|
|
216
|
+
}) ||
|
|
217
|
+
zcapExpiring({
|
|
218
|
+
...(entry.delegatedClientsExpires
|
|
219
|
+
? { expires: entry.delegatedClientsExpires }
|
|
220
|
+
: {})
|
|
221
|
+
}));
|
|
222
|
+
if (stands && !expiring && !siblingStale) {
|
|
189
223
|
continue;
|
|
190
224
|
}
|
|
191
225
|
if (!entry.recoveryClientDid ||
|
|
@@ -200,7 +234,7 @@ export async function remintRecoveryDelegations({ doc, entries, pointer, storage
|
|
|
200
234
|
try {
|
|
201
235
|
// The standing record, whose credential-authenticated core travels
|
|
202
236
|
// verbatim (a record with no binding predates the standing layout and
|
|
203
|
-
// cannot be re-minted -- `
|
|
237
|
+
// cannot be re-minted -- `remintUnlockRecordDelegations` refuses, and the
|
|
204
238
|
// entry is skipped into the health check's regenerate nudge).
|
|
205
239
|
const standing = await getUnlockKeyringWithCapability({
|
|
206
240
|
storageServerUrl,
|
|
@@ -215,6 +249,29 @@ export async function remintRecoveryDelegations({ doc, entries, pointer, storage
|
|
|
215
249
|
pointer,
|
|
216
250
|
recoveryClientDid: entry.recoveryClientDid
|
|
217
251
|
});
|
|
252
|
+
// The fresh companion-Space sibling, for an entry that records one.
|
|
253
|
+
// Its target Space id is read off the account document's
|
|
254
|
+
// delegated-clients service entry; a document not (yet) pointing at a
|
|
255
|
+
// generation leaves nothing to rebuild the target from, so the old
|
|
256
|
+
// sealed member travels verbatim and the pair stays stale-flagged for
|
|
257
|
+
// the login-time health check.
|
|
258
|
+
let delegatedClients;
|
|
259
|
+
if (siblingRecorded) {
|
|
260
|
+
const companionSpaceId = companionSpaceIdFromDocument({ doc });
|
|
261
|
+
if (companionSpaceId) {
|
|
262
|
+
delegatedClients = await mintDelegatedClientsDelegation({
|
|
263
|
+
zcapClient,
|
|
264
|
+
wasServerUrl: pointer.host,
|
|
265
|
+
companionSpaceId,
|
|
266
|
+
controller: entry.recoveryClientDid
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
console.warn(`The account document names no companion generation; the ` +
|
|
271
|
+
`delegatedClients delegation for "${entry.label}" is carried ` +
|
|
272
|
+
'verbatim.');
|
|
273
|
+
}
|
|
274
|
+
}
|
|
218
275
|
// The credential's unlock KAK, public half only -- exactly enough to
|
|
219
276
|
// seal the fresh bridge to the same recipient the credential derives
|
|
220
277
|
// (sealing goes through the encrypt-only cipher, so no secret is
|
|
@@ -225,9 +282,10 @@ export async function remintRecoveryDelegations({ doc, entries, pointer, storage
|
|
|
225
282
|
type: 'X25519KeyAgreementKey2020',
|
|
226
283
|
publicKeyMultibase: entry.unlockKeyAgreementKeyMultibase
|
|
227
284
|
}));
|
|
228
|
-
const wrapped = await
|
|
285
|
+
const wrapped = await remintUnlockRecordDelegations({
|
|
229
286
|
record: standing,
|
|
230
287
|
delegation,
|
|
288
|
+
...(delegatedClients ? { delegatedClients } : {}),
|
|
231
289
|
keyAgreementKey: unlockKak,
|
|
232
290
|
signer: recordSigner
|
|
233
291
|
});
|
|
@@ -242,11 +300,19 @@ export async function remintRecoveryDelegations({ doc, entries, pointer, storage
|
|
|
242
300
|
});
|
|
243
301
|
const delegationKeyId = delegationProofKeyId(delegation);
|
|
244
302
|
const delegationExpires = delegation.expires;
|
|
303
|
+
const delegatedClientsKeyId = delegatedClients
|
|
304
|
+
? delegationProofKeyId(delegatedClients)
|
|
305
|
+
: undefined;
|
|
306
|
+
const delegatedClientsExpires = delegatedClients
|
|
307
|
+
? delegatedClients.expires
|
|
308
|
+
: undefined;
|
|
245
309
|
await recordEntry({
|
|
246
310
|
entry: {
|
|
247
311
|
...entry,
|
|
248
312
|
...(delegationKeyId ? { delegationKeyId } : {}),
|
|
249
|
-
...(delegationExpires ? { delegationExpires } : {})
|
|
313
|
+
...(delegationExpires ? { delegationExpires } : {}),
|
|
314
|
+
...(delegatedClientsKeyId ? { delegatedClientsKeyId } : {}),
|
|
315
|
+
...(delegatedClientsExpires ? { delegatedClientsExpires } : {})
|
|
250
316
|
}
|
|
251
317
|
});
|
|
252
318
|
reminted += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recoveryDelegation.js","sourceRoot":"","sources":["../../src/recovery/recoveryDelegation.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"recoveryDelegation.js","sourceRoot":"","sources":["../../src/recovery/recoveryDelegation.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* the profile's root of authority, resolved and verified by the reader
|
|
7
7
|
* independently of the host serving the log. The interface is the seam --
|
|
8
8
|
* verification consumes only the account DID, the ordered controller-log
|
|
9
|
-
* version list,
|
|
9
|
+
* version list, per-version `assertionMethod` membership, and the
|
|
10
|
+
* per-version credential-posture view the ceremony-tail license reads -- and
|
|
11
|
+
* the
|
|
10
12
|
* did:webvh adapter builds it from an already-verified account log (the
|
|
11
13
|
* `verifyAccountLog` output), answering anchored-version lookups from that
|
|
12
14
|
* verified history rather than from any wire fetch. Handing the verifier a
|
|
@@ -15,15 +17,38 @@
|
|
|
15
17
|
* from.
|
|
16
18
|
*/
|
|
17
19
|
import type { DIDLog } from '@interop/did-method-webvh';
|
|
20
|
+
/**
|
|
21
|
+
* The credential-posture view at one controller-log version, consumed by the
|
|
22
|
+
* ceremony-tail license on ladder-signed appends (clause B of the ladder
|
|
23
|
+
* VM's authority clauses). `ladderKeys` holds the ladder VMs' signing-key
|
|
24
|
+
* multibases, recognized by relation asymmetry -- a `capabilityDelegation`
|
|
25
|
+
* member absent from `capabilityInvocation` is the ladder VM -- and is how a
|
|
26
|
+
* verifier tells a ladder-signed proof from an enrolled client's.
|
|
27
|
+
* `postureKeys` is S(V), the credential-posture key set: the `keyAgreement`
|
|
28
|
+
* methods whose `controller` is the account DID (the deliberately unmarked
|
|
29
|
+
* credential entries -- verbatim `Multikey` keys and `MultikeyCommitment`
|
|
30
|
+
* commitments alike, keyed by their key material), union the ladder VMs. A
|
|
31
|
+
* document entry is posture-changing iff S(V) differs from S(V-1) in either
|
|
32
|
+
* direction; ordinary client enrollment and revocation are excluded
|
|
33
|
+
* structurally, because a client's `keyAgreement` twin carries the `did:key`
|
|
34
|
+
* controller marker rather than the account DID.
|
|
35
|
+
*/
|
|
36
|
+
export interface ControllerPosture {
|
|
37
|
+
ladderKeys: Set<string>;
|
|
38
|
+
postureKeys: Set<string>;
|
|
39
|
+
}
|
|
18
40
|
/**
|
|
19
41
|
* What log verification consumes of the independently verified controller
|
|
20
42
|
* document: the DID the entry proofs must sign under, the verified controller
|
|
21
43
|
* log's `versionId` list in order (empty for an unversioned static
|
|
22
44
|
* controller, degrading every anchor rule to current-document verification),
|
|
23
|
-
*
|
|
45
|
+
* the set of `assertionMethod` key multibases at a given version --
|
|
24
46
|
* membership there is the whole authorization rule, so `keyAgreement`-only
|
|
25
47
|
* recovery keys and `authentication`-only convenience keys are excluded
|
|
26
|
-
* structurally
|
|
48
|
+
* structurally -- and the credential-posture view at a given version, which
|
|
49
|
+
* is what evaluating the ceremony-tail license and recognizing a
|
|
50
|
+
* ladder-signed append require (both invisible through the
|
|
51
|
+
* `assertionMethod` accessor alone).
|
|
27
52
|
*/
|
|
28
53
|
export interface ResourceLogController {
|
|
29
54
|
did: string;
|
|
@@ -37,6 +62,16 @@ export interface ResourceLogController {
|
|
|
37
62
|
* @returns {Promise<Set<string>>}
|
|
38
63
|
*/
|
|
39
64
|
assertionKeysAt(versionId?: string): Promise<Set<string>>;
|
|
65
|
+
/**
|
|
66
|
+
* Resolves the credential-posture view at a controller-log version
|
|
67
|
+
* (`undefined`: the current document): the ladder VM key multibases and
|
|
68
|
+
* the posture set S(V) the ceremony-tail license compares across
|
|
69
|
+
* versions.
|
|
70
|
+
*
|
|
71
|
+
* @param [versionId] {string}
|
|
72
|
+
* @returns {Promise<ControllerPosture>}
|
|
73
|
+
*/
|
|
74
|
+
postureAt(versionId?: string): Promise<ControllerPosture>;
|
|
40
75
|
}
|
|
41
76
|
/**
|
|
42
77
|
* Builds the controller view over an already-verified did:webvh account log
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/resourceLog/controller.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/resourceLog/controller.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAGvD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACvB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB;;;;;;;OAOG;IACH,eAAe,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;IACzD;;;;;;;;OAQG;IACH,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CAC1D;AA6ID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,GAAG,EACJ,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,qBAAqB,CAwCxB"}
|
|
@@ -1,28 +1,109 @@
|
|
|
1
1
|
import { ResourceLogIntegrityError } from './errors.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* `verificationMethod`.
|
|
3
|
+
* Resolves one relation entry: an embedded verification method verbatim, a
|
|
4
|
+
* string reference through the given `verificationMethod` index.
|
|
6
5
|
*
|
|
7
|
-
* @param
|
|
8
|
-
* @
|
|
6
|
+
* @param entry {string | ControllerVerificationMethod}
|
|
7
|
+
* @param byId {Map<string, ControllerVerificationMethod>}
|
|
8
|
+
* @returns {ControllerVerificationMethod | undefined}
|
|
9
9
|
*/
|
|
10
|
-
function
|
|
10
|
+
function resolveMethod(entry, byId) {
|
|
11
|
+
return typeof entry === 'string' ? byId.get(entry) : entry;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Indexes a document's `verificationMethod` array by id.
|
|
15
|
+
*
|
|
16
|
+
* @param doc {ControllerDocument}
|
|
17
|
+
* @returns {Map<string, ControllerVerificationMethod>}
|
|
18
|
+
*/
|
|
19
|
+
function methodsById(doc) {
|
|
11
20
|
const byId = new Map();
|
|
12
21
|
for (const method of doc.verificationMethod ?? []) {
|
|
13
22
|
if (typeof method?.id === 'string') {
|
|
14
23
|
byId.set(method.id, method);
|
|
15
24
|
}
|
|
16
25
|
}
|
|
26
|
+
return byId;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A relation entry's verification-method id: the string reference itself, or
|
|
30
|
+
* an embedded method's `id`.
|
|
31
|
+
*
|
|
32
|
+
* @param entry {string | ControllerVerificationMethod}
|
|
33
|
+
* @returns {string | undefined}
|
|
34
|
+
*/
|
|
35
|
+
function relationIdOf(entry) {
|
|
36
|
+
return typeof entry === 'string' ? entry : entry?.id;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Collects a document's `assertionMethod` key multibases: embedded
|
|
40
|
+
* verification methods verbatim, string references resolved against
|
|
41
|
+
* `verificationMethod`.
|
|
42
|
+
*
|
|
43
|
+
* @param doc {ControllerDocument}
|
|
44
|
+
* @returns {Set<string>}
|
|
45
|
+
*/
|
|
46
|
+
function assertionKeysOf(doc) {
|
|
47
|
+
const byId = methodsById(doc);
|
|
17
48
|
const keys = new Set();
|
|
18
49
|
for (const entry of doc.assertionMethod ?? []) {
|
|
19
|
-
const method =
|
|
50
|
+
const method = resolveMethod(entry, byId);
|
|
20
51
|
if (method && typeof method.publicKeyMultibase === 'string') {
|
|
21
52
|
keys.add(method.publicKeyMultibase);
|
|
22
53
|
}
|
|
23
54
|
}
|
|
24
55
|
return keys;
|
|
25
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Collects a document's credential-posture view (see
|
|
59
|
+
* {@link ControllerPosture}): the ladder VMs by relation asymmetry
|
|
60
|
+
* (`capabilityDelegation` members absent from `capabilityInvocation`,
|
|
61
|
+
* compared by verification-method id), and S(V) as the account-controlled
|
|
62
|
+
* `keyAgreement` methods' key material -- `publicKeyCommitment` where the
|
|
63
|
+
* entry is a commitment, `publicKeyMultibase` where it is verbatim (the two
|
|
64
|
+
* value spaces are disjoint) -- union the ladder keys. A `keyAgreement`
|
|
65
|
+
* method carrying neither is skipped: an unidentifiable entry must not make
|
|
66
|
+
* two distinct postures compare equal.
|
|
67
|
+
*
|
|
68
|
+
* @param doc {ControllerDocument}
|
|
69
|
+
* @param did {string} the account DID posture entries are controlled by
|
|
70
|
+
* @returns {ControllerPosture}
|
|
71
|
+
*/
|
|
72
|
+
function postureOf(doc, did) {
|
|
73
|
+
const byId = methodsById(doc);
|
|
74
|
+
const invocable = new Set();
|
|
75
|
+
for (const entry of doc.capabilityInvocation ?? []) {
|
|
76
|
+
const id = relationIdOf(entry);
|
|
77
|
+
if (id !== undefined) {
|
|
78
|
+
invocable.add(id);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const ladderKeys = new Set();
|
|
82
|
+
for (const entry of doc.capabilityDelegation ?? []) {
|
|
83
|
+
const id = relationIdOf(entry);
|
|
84
|
+
if (id !== undefined && invocable.has(id)) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const method = resolveMethod(entry, byId);
|
|
88
|
+
if (method && typeof method.publicKeyMultibase === 'string') {
|
|
89
|
+
ladderKeys.add(method.publicKeyMultibase);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const postureKeys = new Set(ladderKeys);
|
|
93
|
+
for (const entry of doc.keyAgreement ?? []) {
|
|
94
|
+
const method = resolveMethod(entry, byId);
|
|
95
|
+
if (!method || method.controller !== did) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (typeof method.publicKeyCommitment === 'string') {
|
|
99
|
+
postureKeys.add(method.publicKeyCommitment);
|
|
100
|
+
}
|
|
101
|
+
else if (typeof method.publicKeyMultibase === 'string') {
|
|
102
|
+
postureKeys.add(method.publicKeyMultibase);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { ladderKeys, postureKeys };
|
|
106
|
+
}
|
|
26
107
|
/**
|
|
27
108
|
* Builds the controller view over an already-verified did:webvh account log
|
|
28
109
|
* (the `verifyAccountLog` output -- callers never hand this a log they have
|
|
@@ -41,10 +122,17 @@ function assertionKeysOf(doc) {
|
|
|
41
122
|
export function webvhResourceLogController({ did, log }) {
|
|
42
123
|
const versionIds = log.map(entry => entry.versionId);
|
|
43
124
|
const keysByVersion = new Map();
|
|
125
|
+
const postureByVersion = new Map();
|
|
44
126
|
for (const entry of log) {
|
|
45
|
-
|
|
127
|
+
const doc = entry.state;
|
|
128
|
+
keysByVersion.set(entry.versionId, assertionKeysOf(doc));
|
|
129
|
+
postureByVersion.set(entry.versionId, postureOf(doc, did));
|
|
46
130
|
}
|
|
47
131
|
const head = log.length === 0 ? undefined : log[log.length - 1];
|
|
132
|
+
function versionRefusal(versionId) {
|
|
133
|
+
return new ResourceLogIntegrityError(`The controller document did not resolve at version ` +
|
|
134
|
+
`"${versionId ?? '<head>'}" (no document returned).`);
|
|
135
|
+
}
|
|
48
136
|
return {
|
|
49
137
|
did,
|
|
50
138
|
versionIds,
|
|
@@ -53,8 +141,16 @@ export function webvhResourceLogController({ did, log }) {
|
|
|
53
141
|
? head && keysByVersion.get(head.versionId)
|
|
54
142
|
: keysByVersion.get(versionId);
|
|
55
143
|
if (!resolved) {
|
|
56
|
-
return Promise.reject(
|
|
57
|
-
|
|
144
|
+
return Promise.reject(versionRefusal(versionId));
|
|
145
|
+
}
|
|
146
|
+
return Promise.resolve(resolved);
|
|
147
|
+
},
|
|
148
|
+
postureAt(versionId) {
|
|
149
|
+
const resolved = versionId === undefined
|
|
150
|
+
? head && postureByVersion.get(head.versionId)
|
|
151
|
+
: postureByVersion.get(versionId);
|
|
152
|
+
if (!resolved) {
|
|
153
|
+
return Promise.reject(versionRefusal(versionId));
|
|
58
154
|
}
|
|
59
155
|
return Promise.resolve(resolved);
|
|
60
156
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/resourceLog/controller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/resourceLog/controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* The resource-log refusal taxonomy, carried over from the roster's WC-1
|
|
6
6
|
* detached-signature design onto the log design. Two adversarial classes plus
|
|
7
|
-
*
|
|
7
|
+
* two admission refusals:
|
|
8
8
|
*
|
|
9
9
|
* - {@link ResourceLogIntegrityError} -- fabrication: the served log fails
|
|
10
10
|
* verification on its own terms (parse shape, SCID, chain hashes, proofs,
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
* head is a terminal handover entry. Not an attack: the log's own authors
|
|
20
20
|
* closed it, and a verifier of this profile must refuse to extend a closed
|
|
21
21
|
* log even though nothing currently emits terminal entries.
|
|
22
|
+
* - {@link ResourceLogLicenseError} -- a ladder-signed append outside the
|
|
23
|
+
* ceremony-tail license. An admission refusal, not log corruption: the
|
|
24
|
+
* append (attempted, or already served) is not licensed, and the same
|
|
25
|
+
* append can become licensed after a posture-changing controller-document
|
|
26
|
+
* entry -- callers must not treat it with the reject-the-whole-log
|
|
27
|
+
* severity of the integrity class.
|
|
22
28
|
*/
|
|
23
29
|
/**
|
|
24
30
|
* A served log failed verification: malformed entries, a non-verifying SCID,
|
|
@@ -55,6 +61,21 @@ export declare class ResourceLogContinuityError extends Error {
|
|
|
55
61
|
servedEntries?: unknown[];
|
|
56
62
|
});
|
|
57
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* A ladder-signed append outside the ceremony-tail license: it is not the
|
|
66
|
+
* log's first entry, and it does not anchor at a posture-changing controller
|
|
67
|
+
* document version no verified entry already anchors at or past. Above all
|
|
68
|
+
* this refuses the silent-rekey shape -- a ladder-signed rotation against an
|
|
69
|
+
* unchanged document. Write-time admission class: the log is not corrupt and
|
|
70
|
+
* whoever signed the append genuinely holds the credential; the append is
|
|
71
|
+
* merely unlicensed, and a retry after a posture-changing document entry may
|
|
72
|
+
* succeed.
|
|
73
|
+
*/
|
|
74
|
+
export declare class ResourceLogLicenseError extends Error {
|
|
75
|
+
constructor(message: string, options?: {
|
|
76
|
+
cause?: unknown;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
58
79
|
/**
|
|
59
80
|
* An append was refused because the log's verified head is a terminal
|
|
60
81
|
* handover entry: the log is closed and names a successor, and this profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/resourceLog/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/resourceLog/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;gBACtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED;;;;;;;;GAQG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACnD,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,eAAe,CAAA;IAC7D,UAAU,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,EAAE,CAAA;gBACb,EACV,MAAM,EACN,UAAU,EACV,aAAa,EACd,EAAE;QACD,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,aAAa,GAAG,eAAe,CAAA;QAC7D,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAA;KAC1B;CAUF;AAED;;;;;;;;;GASG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;gBAC7B,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE;CAQvE"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* The resource-log refusal taxonomy, carried over from the roster's WC-1
|
|
6
6
|
* detached-signature design onto the log design. Two adversarial classes plus
|
|
7
|
-
*
|
|
7
|
+
* two admission refusals:
|
|
8
8
|
*
|
|
9
9
|
* - {@link ResourceLogIntegrityError} -- fabrication: the served log fails
|
|
10
10
|
* verification on its own terms (parse shape, SCID, chain hashes, proofs,
|
|
@@ -19,6 +19,12 @@
|
|
|
19
19
|
* head is a terminal handover entry. Not an attack: the log's own authors
|
|
20
20
|
* closed it, and a verifier of this profile must refuse to extend a closed
|
|
21
21
|
* log even though nothing currently emits terminal entries.
|
|
22
|
+
* - {@link ResourceLogLicenseError} -- a ladder-signed append outside the
|
|
23
|
+
* ceremony-tail license. An admission refusal, not log corruption: the
|
|
24
|
+
* append (attempted, or already served) is not licensed, and the same
|
|
25
|
+
* append can become licensed after a posture-changing controller-document
|
|
26
|
+
* entry -- callers must not treat it with the reject-the-whole-log
|
|
27
|
+
* severity of the integrity class.
|
|
22
28
|
*/
|
|
23
29
|
/**
|
|
24
30
|
* A served log failed verification: malformed entries, a non-verifying SCID,
|
|
@@ -59,6 +65,22 @@ export class ResourceLogContinuityError extends Error {
|
|
|
59
65
|
this.servedEntries = servedEntries;
|
|
60
66
|
}
|
|
61
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* A ladder-signed append outside the ceremony-tail license: it is not the
|
|
70
|
+
* log's first entry, and it does not anchor at a posture-changing controller
|
|
71
|
+
* document version no verified entry already anchors at or past. Above all
|
|
72
|
+
* this refuses the silent-rekey shape -- a ladder-signed rotation against an
|
|
73
|
+
* unchanged document. Write-time admission class: the log is not corrupt and
|
|
74
|
+
* whoever signed the append genuinely holds the credential; the append is
|
|
75
|
+
* merely unlicensed, and a retry after a posture-changing document entry may
|
|
76
|
+
* succeed.
|
|
77
|
+
*/
|
|
78
|
+
export class ResourceLogLicenseError extends Error {
|
|
79
|
+
constructor(message, options) {
|
|
80
|
+
super(message, options);
|
|
81
|
+
this.name = 'ResourceLogLicenseError';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
62
84
|
/**
|
|
63
85
|
* An append was refused because the log's verified head is a terminal
|
|
64
86
|
* handover entry: the log is closed and names a successor, and this profile
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/resourceLog/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/resourceLog/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;GAKG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;IACzC,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD,MAAM,CAAuD;IAC7D,UAAU,CAAQ;IAClB;;;;OAIG;IACH,aAAa,CAAY;IACzB,YAAY,EACV,MAAM,EACN,UAAU,EACV,aAAa,EAKd;QACC,KAAK,CACH,sEAAsE;YACpE,IAAI,MAAM,iBAAiB,UAAU,IAAI,CAC5C,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAA;QACxC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QACvB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,OAAO,CAAkC;IACzC,YAAY,EAAE,OAAO,EAAiD;QACpE,KAAK,CACH,wEAAwE;YACtE,0BAA0B,CAC7B,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;CACF"}
|