@interop/wallet-core 0.16.0 → 0.18.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 +13 -13
- package/dist/clients/index.d.ts +4 -3
- package/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +3 -2
- package/dist/clients/index.js.map +1 -1
- package/dist/clients/policy.d.ts +3 -3
- package/dist/clients/policy.d.ts.map +1 -1
- package/dist/clients/policy.js +1 -1
- package/dist/clients/revocation.d.ts +18 -15
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +42 -26
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +46 -24
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +106 -48
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/descriptors/refresh.d.ts +3 -1
- package/dist/descriptors/refresh.d.ts.map +1 -1
- package/dist/descriptors/refresh.js +3 -1
- package/dist/descriptors/refresh.js.map +1 -1
- package/dist/display/alignment.d.ts +8 -2
- package/dist/display/alignment.d.ts.map +1 -1
- package/dist/display/alignment.js +11 -8
- package/dist/display/alignment.js.map +1 -1
- package/dist/display/displayFields.d.ts +6 -2
- package/dist/display/displayFields.d.ts.map +1 -1
- package/dist/display/displayFields.js.map +1 -1
- package/dist/display/evidence.d.ts +9 -3
- package/dist/display/evidence.d.ts.map +1 -1
- package/dist/display/evidence.js +3 -1
- package/dist/display/evidence.js.map +1 -1
- package/dist/display/index.d.ts +1 -1
- package/dist/display/index.d.ts.map +1 -1
- package/dist/display/index.js +1 -1
- package/dist/display/index.js.map +1 -1
- package/dist/display/issuer.d.ts +12 -4
- package/dist/display/issuer.d.ts.map +1 -1
- package/dist/display/issuer.js.map +1 -1
- package/dist/display/obv3.d.ts +7 -2
- package/dist/display/obv3.d.ts.map +1 -1
- package/dist/display/obv3.js +14 -24
- package/dist/display/obv3.js.map +1 -1
- package/dist/display/parse.d.ts +6 -2
- package/dist/display/parse.d.ts.map +1 -1
- package/dist/display/parse.js +6 -2
- package/dist/display/parse.js.map +1 -1
- package/dist/display/subject.d.ts +4 -0
- package/dist/display/subject.d.ts.map +1 -1
- package/dist/display/subject.js +12 -10
- package/dist/display/subject.js.map +1 -1
- package/dist/display/text.d.ts +11 -0
- package/dist/display/text.d.ts.map +1 -1
- package/dist/display/text.js +20 -4
- package/dist/display/text.js.map +1 -1
- package/dist/display/types.js +1 -1
- package/dist/display/types.js.map +1 -1
- package/dist/display/validity.js +4 -4
- package/dist/display/validity.js.map +1 -1
- package/dist/display/verificationView.d.ts +21 -7
- package/dist/display/verificationView.d.ts.map +1 -1
- package/dist/display/verificationView.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +21 -19
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +98 -34
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/enrollment/index.d.ts +1 -1
- package/dist/enrollment/index.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/keys/clientKeyRecord.d.ts +19 -17
- package/dist/keys/clientKeyRecord.d.ts.map +1 -1
- package/dist/keys/clientKeyRecord.js +77 -41
- package/dist/keys/clientKeyRecord.js.map +1 -1
- package/dist/keys/index.d.ts +19 -17
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +16 -14
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterStore.d.ts +3 -3
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +13 -13
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/keys/userKey.d.ts +43 -0
- package/dist/keys/userKey.d.ts.map +1 -0
- package/dist/keys/{puk.js → userKey.js} +23 -21
- package/dist/keys/userKey.js.map +1 -0
- package/dist/keys/{pukCascade.d.ts → userKeyCascade.d.ts} +69 -69
- package/dist/keys/userKeyCascade.d.ts.map +1 -0
- package/dist/keys/{pukCascade.js → userKeyCascade.js} +77 -75
- package/dist/keys/userKeyCascade.js.map +1 -0
- package/dist/keys/{pukRoster.d.ts → userKeyRoster.d.ts} +141 -64
- package/dist/keys/userKeyRoster.d.ts.map +1 -0
- package/dist/keys/{pukRoster.js → userKeyRoster.js} +200 -72
- package/dist/keys/userKeyRoster.js.map +1 -0
- package/dist/recovery/index.d.ts +1 -1
- package/dist/recovery/index.js +1 -1
- package/dist/recovery/recoveryCode.d.ts +1 -1
- package/dist/recovery/recoveryCode.js +6 -6
- package/dist/recovery/recoveryRecord.d.ts +1 -1
- package/dist/recovery/recoveryWebvh.d.ts +1 -1
- package/dist/recovery/recoveryWebvh.js +1 -1
- package/dist/request/classify.d.ts +15 -1
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +38 -14
- package/dist/request/classify.js.map +1 -1
- package/dist/request/composeVp.d.ts.map +1 -1
- package/dist/request/composeVp.js +10 -3
- package/dist/request/composeVp.js.map +1 -1
- package/dist/request/matching.d.ts +6 -0
- package/dist/request/matching.d.ts.map +1 -1
- package/dist/request/matching.js +33 -8
- package/dist/request/matching.js.map +1 -1
- package/dist/request/parse.d.ts +5 -2
- package/dist/request/parse.d.ts.map +1 -1
- package/dist/request/parse.js +30 -5
- package/dist/request/parse.js.map +1 -1
- package/dist/request/presentationSuite.d.ts.map +1 -1
- package/dist/request/presentationSuite.js +6 -2
- package/dist/request/presentationSuite.js.map +1 -1
- package/dist/request/processRequest.js +1 -1
- package/dist/request/processRequest.js.map +1 -1
- package/dist/space/activity.d.ts +22 -8
- package/dist/space/activity.d.ts.map +1 -1
- package/dist/space/activity.js +19 -7
- package/dist/space/activity.js.map +1 -1
- package/dist/space/collections.d.ts +33 -21
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +34 -22
- package/dist/space/collections.js.map +1 -1
- package/dist/space/index.d.ts +2 -2
- package/dist/space/index.d.ts.map +1 -1
- package/dist/space/index.js +2 -2
- package/dist/space/index.js.map +1 -1
- package/dist/space/wasLink.d.ts +6 -2
- package/dist/space/wasLink.d.ts.map +1 -1
- package/dist/space/wasLink.js +5 -2
- package/dist/space/wasLink.js.map +1 -1
- package/dist/sync/contactsConflict.d.ts +1 -1
- package/dist/sync/contactsConflict.js +1 -1
- package/dist/sync/engine.d.ts +33 -11
- package/dist/sync/engine.d.ts.map +1 -1
- package/dist/sync/engine.js +4 -3
- package/dist/sync/engine.js.map +1 -1
- package/dist/sync/pull.d.ts +5 -3
- package/dist/sync/pull.d.ts.map +1 -1
- package/dist/sync/pull.js +34 -10
- package/dist/sync/pull.js.map +1 -1
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +24 -8
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/types.d.ts +30 -6
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/webvh/didWebvh.d.ts +29 -1
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +46 -11
- package/dist/webvh/didWebvh.js.map +1 -1
- package/dist/webvh/index.d.ts +1 -1
- package/dist/webvh/index.d.ts.map +1 -1
- package/dist/webvh/index.js +1 -1
- package/dist/webvh/index.js.map +1 -1
- package/dist/webvh/listClients.d.ts +19 -0
- package/dist/webvh/listClients.d.ts.map +1 -1
- package/dist/webvh/listClients.js +37 -1
- package/dist/webvh/listClients.js.map +1 -1
- package/dist/webvh/revokeClient.d.ts +11 -3
- package/dist/webvh/revokeClient.d.ts.map +1 -1
- package/dist/webvh/revokeClient.js +83 -14
- package/dist/webvh/revokeClient.js.map +1 -1
- package/package.json +3 -3
- package/dist/keys/puk.d.ts +0 -42
- package/dist/keys/puk.d.ts.map +0 -1
- package/dist/keys/puk.js.map +0 -1
- package/dist/keys/pukCascade.d.ts.map +0 -1
- package/dist/keys/pukCascade.js.map +0 -1
- package/dist/keys/pukRoster.d.ts.map +0 -1
- package/dist/keys/pukRoster.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientKeyRecord.js","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"clientKeyRecord.js","sourceRoot":"","sources":["../../src/keys/clientKeyRecord.ts"],"names":[],"mappings":"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"}
|
package/dist/keys/index.d.ts
CHANGED
|
@@ -2,48 +2,50 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The `@interop/wallet-core/keys` subpath: the
|
|
5
|
+
* The `@interop/wallet-core/keys` subpath: the user key and its
|
|
6
6
|
* wrap-set roster -- recipient zero of every encrypted collection, and the one
|
|
7
7
|
* channel that delivers it to each enrolled wallet client.
|
|
8
8
|
*
|
|
9
|
-
* - `
|
|
9
|
+
* - `mintUserKey` / `userKeyVaultKeys` -- minting the account's user key and
|
|
10
|
+
* rebuilding the
|
|
10
11
|
* vault key-agreement key + resolver from stored material.
|
|
11
12
|
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
13
|
* strict validation of the local client-key record each client keeps its own
|
|
13
14
|
* key material in (storage and wrapping stay app-side).
|
|
14
|
-
* - `
|
|
15
|
-
* `
|
|
15
|
+
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the `key-map/user-key.json` roster over the
|
|
16
17
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
17
18
|
* resource-hosted descriptor needs (`epochsMac`, the latest-seen epoch pin,
|
|
18
19
|
* and a recipient resolver backed by the locally verified did:webvh
|
|
19
20
|
* document).
|
|
20
|
-
* - `
|
|
21
|
+
* - `userKeyRosterDescriptorStore` -- that descriptor store, built from a bare
|
|
21
22
|
* signing client for the login-time direct read.
|
|
22
23
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
23
24
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
24
|
-
* - `
|
|
25
|
+
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
25
26
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
26
27
|
* recipient the document no longer keys is rotated away from.
|
|
27
28
|
* - `readClientLabels` / `setClientLabel` / `removeClientLabel` /
|
|
28
29
|
* `wasClientLabelsStore` -- the enrolled-client display labels
|
|
29
30
|
* (`key-map/client-labels.json`), the record a "your wallets" surface names
|
|
30
31
|
* clients from, and the WAS-backed store they run through.
|
|
31
|
-
* - `
|
|
32
|
-
*
|
|
32
|
+
* - `rotateUserKeyRoster` / `unwrapUserKeyGenerations` /
|
|
33
|
+
* `rotateCollectionEpochsToUserKey`
|
|
34
|
+
* / `cascadeCollectionsToUserKey` / `userKeyAsRecipient` -- the user key rotation
|
|
33
35
|
* cascade: the roster rotation off a revoked recipient, the per-collection
|
|
34
36
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
35
|
-
*
|
|
37
|
+
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
36
38
|
* names (also the completion sweep's driver).
|
|
37
39
|
*/
|
|
38
|
-
export {
|
|
39
|
-
export type {
|
|
40
|
-
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord,
|
|
40
|
+
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
41
|
+
export type { UserKey } from './userKey.js';
|
|
42
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
41
43
|
export type { ClientKeyRecord, ClientKeyRecordJson, EnrolledClientKeyRecord } from './clientKeyRecord.js';
|
|
42
|
-
export {
|
|
43
|
-
export {
|
|
44
|
-
export type {
|
|
45
|
-
export type {
|
|
46
|
-
export {
|
|
44
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterEpochsSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster, verifyUserKeyRosterEpochsSig } from './userKeyRoster.js';
|
|
45
|
+
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
46
|
+
export type { CollectionUserKeyRotationOutcome, UserKeyCascadeResult } from './userKeyCascade.js';
|
|
47
|
+
export type { UserKeyRosterReadResult, RosterRecipientDocument } from './userKeyRoster.js';
|
|
48
|
+
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
47
49
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
48
50
|
export type { ClientLabelsRecord, ClientLabelsStore } from './clientLabels.js';
|
|
49
51
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
package/dist/keys/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC5D,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,gCAAgC,EAChC,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
package/dist/keys/index.js
CHANGED
|
@@ -2,44 +2,46 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The `@interop/wallet-core/keys` subpath: the
|
|
5
|
+
* The `@interop/wallet-core/keys` subpath: the user key and its
|
|
6
6
|
* wrap-set roster -- recipient zero of every encrypted collection, and the one
|
|
7
7
|
* channel that delivers it to each enrolled wallet client.
|
|
8
8
|
*
|
|
9
|
-
* - `
|
|
9
|
+
* - `mintUserKey` / `userKeyVaultKeys` -- minting the account's user key and
|
|
10
|
+
* rebuilding the
|
|
10
11
|
* vault key-agreement key + resolver from stored material.
|
|
11
12
|
* - `encodeClientKeyRecord` / `decodeClientKeyRecord` -- the contents codec and
|
|
12
13
|
* strict validation of the local client-key record each client keeps its own
|
|
13
14
|
* key material in (storage and wrapping stay app-side).
|
|
14
|
-
* - `
|
|
15
|
-
* `
|
|
15
|
+
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the `key-map/user-key.json` roster over the
|
|
16
17
|
* was-client descriptor-store seam, with the three client-side guards a
|
|
17
18
|
* resource-hosted descriptor needs (`epochsMac`, the latest-seen epoch pin,
|
|
18
19
|
* and a recipient resolver backed by the locally verified did:webvh
|
|
19
20
|
* document).
|
|
20
|
-
* - `
|
|
21
|
+
* - `userKeyRosterDescriptorStore` -- that descriptor store, built from a bare
|
|
21
22
|
* signing client for the login-time direct read.
|
|
22
23
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
23
24
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
24
|
-
* - `
|
|
25
|
+
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
25
26
|
* cascade torn between the document edit and the roster rotation: a roster
|
|
26
27
|
* recipient the document no longer keys is rotated away from.
|
|
27
28
|
* - `readClientLabels` / `setClientLabel` / `removeClientLabel` /
|
|
28
29
|
* `wasClientLabelsStore` -- the enrolled-client display labels
|
|
29
30
|
* (`key-map/client-labels.json`), the record a "your wallets" surface names
|
|
30
31
|
* clients from, and the WAS-backed store they run through.
|
|
31
|
-
* - `
|
|
32
|
-
*
|
|
32
|
+
* - `rotateUserKeyRoster` / `unwrapUserKeyGenerations` /
|
|
33
|
+
* `rotateCollectionEpochsToUserKey`
|
|
34
|
+
* / `cascadeCollectionsToUserKey` / `userKeyAsRecipient` -- the user key rotation
|
|
33
35
|
* cascade: the roster rotation off a revoked recipient, the per-collection
|
|
34
36
|
* re-epoch that brings an encrypted collection onto the roster's current
|
|
35
|
-
*
|
|
37
|
+
* user key, and the parallel best-effort fan-out over the collections the wallet
|
|
36
38
|
* names (also the completion sweep's driver).
|
|
37
39
|
*/
|
|
38
|
-
export {
|
|
39
|
-
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord,
|
|
40
|
-
export {
|
|
41
|
-
export {
|
|
42
|
-
export {
|
|
40
|
+
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
41
|
+
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
42
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterEpochsSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster, verifyUserKeyRosterEpochsSig } from './userKeyRoster.js';
|
|
43
|
+
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
44
|
+
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
43
45
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
44
46
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
|
45
47
|
//# sourceMappingURL=index.js.map
|
package/dist/keys/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/keys/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG5D,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EACL,yBAAyB,EACzB,+BAA+B,EAC/B,mBAAmB,EACnB,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,4BAA4B,EAC7B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAU5B,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ZcapClient } from '@interop/ezcap';
|
|
2
2
|
import { type EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
3
3
|
/**
|
|
4
|
-
* Builds the compare-and-swap descriptor store over `key-map/
|
|
5
|
-
* data Space.
|
|
4
|
+
* Builds the compare-and-swap descriptor store over `key-map/user-key.json` in
|
|
5
|
+
* a data Space.
|
|
6
6
|
*
|
|
7
7
|
* @param options {object}
|
|
8
8
|
* @param options.storageServerUrl {string}
|
|
@@ -10,7 +10,7 @@ import { type EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
|
10
10
|
* @param options.spaceId {string} the data Space id
|
|
11
11
|
* @returns {EncryptionDescriptorStore}
|
|
12
12
|
*/
|
|
13
|
-
export declare function
|
|
13
|
+
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }: {
|
|
14
14
|
storageServerUrl: string;
|
|
15
15
|
zcapClient: ZcapClient;
|
|
16
16
|
spaceId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAMhC;;;;;;;;;GASG;AACH,wBAAgB,
|
|
1
|
+
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAMhC;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACR,EAAE;IACD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,yBAAyB,CAQ5B"}
|
package/dist/keys/rosterStore.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The descriptor store over a Space's
|
|
6
|
-
* Standalone rather than a method on a wallet's
|
|
7
|
-
* the login-time direct read checks the roster
|
|
8
|
-
* cipher) is built: it takes the bare signing
|
|
9
|
-
* instance.
|
|
5
|
+
* The descriptor store over a Space's user key wrap-set roster
|
|
6
|
+
* (`key-map/user-key.json`). Standalone rather than a method on a wallet's
|
|
7
|
+
* remote-store class, because the login-time direct read checks the roster
|
|
8
|
+
* BEFORE any storage client (or cipher) is built: it takes the bare signing
|
|
9
|
+
* client instead of a store instance.
|
|
10
10
|
*
|
|
11
11
|
* The `plaintext` collection override is load-bearing. Without it the client
|
|
12
12
|
* decides plaintext vs encrypted by describing the collection first, and a 404
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { WasClient } from '@interop/was-client';
|
|
17
17
|
import { resourceDescriptorStore } from '@interop/was-client/edv';
|
|
18
|
-
import { KEY_MAP_COLLECTION,
|
|
18
|
+
import { KEY_MAP_COLLECTION, USER_KEY_ROSTER_RESOURCE } from '../space/collections.js';
|
|
19
19
|
/**
|
|
20
|
-
* Builds the compare-and-swap descriptor store over `key-map/
|
|
21
|
-
* data Space.
|
|
20
|
+
* Builds the compare-and-swap descriptor store over `key-map/user-key.json` in
|
|
21
|
+
* a data Space.
|
|
22
22
|
*
|
|
23
23
|
* @param options {object}
|
|
24
24
|
* @param options.storageServerUrl {string}
|
|
@@ -26,13 +26,13 @@ import { KEY_MAP_COLLECTION, PUK_ROSTER_RESOURCE } from '../space/collections.js
|
|
|
26
26
|
* @param options.spaceId {string} the data Space id
|
|
27
27
|
* @returns {EncryptionDescriptorStore}
|
|
28
28
|
*/
|
|
29
|
-
export function
|
|
29
|
+
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }) {
|
|
30
30
|
const was = new WasClient({ serverUrl: storageServerUrl, zcapClient });
|
|
31
|
+
const collection = was
|
|
32
|
+
.space(spaceId)
|
|
33
|
+
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' });
|
|
31
34
|
return resourceDescriptorStore({
|
|
32
|
-
resource:
|
|
33
|
-
.space(spaceId)
|
|
34
|
-
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' })
|
|
35
|
-
.resource(PUK_ROSTER_RESOURCE)
|
|
35
|
+
resource: collection.resource(USER_KEY_ROSTER_RESOURCE)
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
//# sourceMappingURL=rosterStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EACL,uBAAuB,EAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,kBAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,OAAO,EACL,uBAAuB,EAExB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,yBAAyB,CAAA;AAEhC;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EAKR;IACC,MAAM,GAAG,GAAG,IAAI,SAAS,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,CAAA;IACtE,MAAM,UAAU,GAAG,GAAG;SACnB,KAAK,CAAC,OAAO,CAAC;SACd,UAAU,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC,CAAA;IACjE,OAAO,uBAAuB,CAAC;QAC7B,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,wBAAwB,CAAC;KACxD,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { IKeyAgreementKey, IKeyResolver } from '@interop/data-integrity-core';
|
|
2
|
+
/**
|
|
3
|
+
* The user key material: the X25519 key-agreement half as minted by the epoch
|
|
4
|
+
* construction (`id` is the key's own did:key; `secret` its raw 32-byte private
|
|
5
|
+
* key), plus the 32-byte seed of the user key's Ed25519 signing pair. Random
|
|
6
|
+
* per account; held in memory for the life of a session and persisted only
|
|
7
|
+
* inside a wrapped client-key record. The signing seed is absent on a user key
|
|
8
|
+
* adopted from a roster rotation -- the roster wraps the key-agreement secret
|
|
9
|
+
* alone, and the signing half has no consumer yet.
|
|
10
|
+
*/
|
|
11
|
+
export interface UserKey {
|
|
12
|
+
id: string;
|
|
13
|
+
secret: Uint8Array;
|
|
14
|
+
signingSeed?: Uint8Array;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Mints a fresh user key: the X25519 key-agreement pair via the was-client
|
|
18
|
+
* epoch construction (its did:key is the key id, its raw secret is what wraps),
|
|
19
|
+
* plus a random 32-byte Ed25519 signing seed -- a minted user key is always a
|
|
20
|
+
* complete identity (only a rotation-adopted one lacks the signing half).
|
|
21
|
+
*
|
|
22
|
+
* @returns {Promise<Required<UserKey>>}
|
|
23
|
+
*/
|
|
24
|
+
export declare function mintUserKey(): Promise<Required<UserKey>>;
|
|
25
|
+
/**
|
|
26
|
+
* Reconstructs the user key's key-agreement key and its single-key resolver
|
|
27
|
+
* from the stored material -- the vault-key pair a session supplies to the
|
|
28
|
+
* storage layer, making the user key recipient zero of every encrypted
|
|
29
|
+
* collection. The key id is the self-describing `<did:key>#<fingerprint>` form,
|
|
30
|
+
* so grantee-side did:key recipient resolution routes it like any other roster
|
|
31
|
+
* entry.
|
|
32
|
+
*
|
|
33
|
+
* @param options {object}
|
|
34
|
+
* @param options.userKey {UserKey}
|
|
35
|
+
* @returns {{ keyAgreementKey: IKeyAgreementKey, keyResolver: IKeyResolver }}
|
|
36
|
+
*/
|
|
37
|
+
export declare function userKeyVaultKeys({ userKey }: {
|
|
38
|
+
userKey: UserKey;
|
|
39
|
+
}): {
|
|
40
|
+
keyAgreementKey: IKeyAgreementKey;
|
|
41
|
+
keyResolver: IKeyResolver;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=userKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKey.d.ts","sourceRoot":"","sources":["../../src/keys/userKey.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACb,MAAM,8BAA8B,CAAA;AAIrC;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,UAAU,CAAA;IAClB,WAAW,CAAC,EAAE,UAAU,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAK9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG;IACnE,eAAe,EAAE,gBAAgB,CAAA;IACjC,WAAW,EAAE,YAAY,CAAA;CAC1B,CAQA"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
5
|
+
* The user key: the user's single roster identity for encrypted
|
|
6
6
|
* collections, standing in as "recipient zero" of every key-epoch roster. It is
|
|
7
7
|
* minted at wallet provisioning -- random, client-side, never server-held, and
|
|
8
8
|
* never derivable from any passphrase or seed -- and delivered to each enrolled
|
|
@@ -12,45 +12,47 @@
|
|
|
12
12
|
* The key-agreement half is exactly what `@interop/was-client`'s epoch
|
|
13
13
|
* construction mints: a fresh X25519 pair whose did:key is the key's id and
|
|
14
14
|
* whose raw 32-byte secret is what gets wrapped to recipients -- so the roster
|
|
15
|
-
* machinery consumes the
|
|
16
|
-
* independent 32-byte seed, minted now so the
|
|
17
|
-
* no consumer yet (the pair derives from the seed on demand once
|
|
15
|
+
* machinery consumes the user key unchanged. The Ed25519 signing half is a
|
|
16
|
+
* second independent 32-byte seed, minted now so the user key is a complete
|
|
17
|
+
* identity, with no consumer yet (the pair derives from the seed on demand once
|
|
18
|
+
* one lands).
|
|
18
19
|
*/
|
|
19
20
|
import { X25519KeyAgreementKey2020 } from '@interop/x25519-key-agreement-key';
|
|
20
21
|
import { epochKeyIdFor, mintEpoch } from '@interop/was-client/edv';
|
|
21
22
|
import { singleKeyResolver } from '../identity/keyResolver.js';
|
|
22
23
|
/**
|
|
23
|
-
* Mints a fresh
|
|
24
|
-
* construction (its did:key is the key id, its raw secret is what wraps),
|
|
25
|
-
* a random 32-byte Ed25519 signing seed -- a minted
|
|
26
|
-
* identity (only a rotation-adopted one lacks the signing half).
|
|
24
|
+
* Mints a fresh user key: the X25519 key-agreement pair via the was-client
|
|
25
|
+
* epoch construction (its did:key is the key id, its raw secret is what wraps),
|
|
26
|
+
* plus a random 32-byte Ed25519 signing seed -- a minted user key is always a
|
|
27
|
+
* complete identity (only a rotation-adopted one lacks the signing half).
|
|
27
28
|
*
|
|
28
|
-
* @returns {Promise<Required<
|
|
29
|
+
* @returns {Promise<Required<UserKey>>}
|
|
29
30
|
*/
|
|
30
|
-
export async function
|
|
31
|
+
export async function mintUserKey() {
|
|
31
32
|
const { epochId, secret } = await mintEpoch();
|
|
32
33
|
const signingSeed = new Uint8Array(32);
|
|
33
34
|
crypto.getRandomValues(signingSeed);
|
|
34
35
|
return { id: epochId, secret, signingSeed };
|
|
35
36
|
}
|
|
36
37
|
/**
|
|
37
|
-
* Reconstructs the
|
|
38
|
-
* the stored material -- the vault-key pair a session supplies to the
|
|
39
|
-
* layer, making the
|
|
40
|
-
* id is the self-describing `<did:key>#<fingerprint>` form,
|
|
41
|
-
* did:key recipient resolution routes it like any other roster
|
|
38
|
+
* Reconstructs the user key's key-agreement key and its single-key resolver
|
|
39
|
+
* from the stored material -- the vault-key pair a session supplies to the
|
|
40
|
+
* storage layer, making the user key recipient zero of every encrypted
|
|
41
|
+
* collection. The key id is the self-describing `<did:key>#<fingerprint>` form,
|
|
42
|
+
* so grantee-side did:key recipient resolution routes it like any other roster
|
|
43
|
+
* entry.
|
|
42
44
|
*
|
|
43
45
|
* @param options {object}
|
|
44
|
-
* @param options.
|
|
46
|
+
* @param options.userKey {UserKey}
|
|
45
47
|
* @returns {{ keyAgreementKey: IKeyAgreementKey, keyResolver: IKeyResolver }}
|
|
46
48
|
*/
|
|
47
|
-
export function
|
|
49
|
+
export function userKeyVaultKeys({ userKey }) {
|
|
48
50
|
const keyAgreementKey = X25519KeyAgreementKey2020.fromRawSecret({
|
|
49
|
-
secret:
|
|
50
|
-
controller:
|
|
51
|
-
id: epochKeyIdFor(
|
|
51
|
+
secret: userKey.secret,
|
|
52
|
+
controller: userKey.id,
|
|
53
|
+
id: epochKeyIdFor(userKey.id)
|
|
52
54
|
});
|
|
53
55
|
const keyResolver = singleKeyResolver({ keyAgreementKey });
|
|
54
56
|
return { keyAgreementKey, keyResolver };
|
|
55
57
|
}
|
|
56
|
-
//# sourceMappingURL=
|
|
58
|
+
//# sourceMappingURL=userKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"userKey.js","sourceRoot":"","sources":["../../src/keys/userKey.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAK7E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAiB9D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,EAAE,CAAA;IAC7C,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,eAAe,CAAC,WAAW,CAAC,CAAA;IACnC,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAA;AAC7C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAAwB;IAIhE,MAAM,eAAe,GAAG,yBAAyB,CAAC,aAAa,CAAC;QAC9D,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,UAAU,EAAE,OAAO,CAAC,EAAE;QACtB,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;KAC9B,CAAqB,CAAA;IACtB,MAAM,WAAW,GAAG,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAC,CAAA;IAC1D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,CAAA;AACzC,CAAC"}
|
|
@@ -2,92 +2,92 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The per-collection half of the
|
|
6
|
-
* current epoch has moved to a fresh
|
|
7
|
-
* spent or revoked), every encrypted collection must take a new epoch
|
|
8
|
-
* the fresh
|
|
9
|
-
* an epoch key the revoked party still holds.
|
|
5
|
+
* The per-collection half of the user key rotation cascade: once the roster's
|
|
6
|
+
* current epoch has moved to a fresh user key (a client revoked, a recovery
|
|
7
|
+
* code spent or revoked), every encrypted collection must take a new epoch
|
|
8
|
+
* naming the fresh user key and retire the old one -- otherwise writes keep
|
|
9
|
+
* landing under an epoch key the revoked party still holds.
|
|
10
10
|
*
|
|
11
11
|
* The staleness rule is the one the revocation spike verified: **a collection
|
|
12
|
-
* is stale exactly when its current epoch names a
|
|
12
|
+
* is stale exactly when its current epoch names a user key KAK other than the
|
|
13
13
|
* roster's current** -- detectable from durable data alone, no checkpoint
|
|
14
|
-
* resource anywhere, which is what makes a crashed cascade resumable by a
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
14
|
+
* resource anywhere, which is what makes a crashed cascade resumable by a naive
|
|
15
|
+
* full re-run (and what the login-time completion sweep re-checks). Which KAKs
|
|
16
|
+
* are "user key generations" is read from the roster itself: its epochs ARE the
|
|
17
|
+
* user key generations, each escrow-wrapped to every enrolled client, so any
|
|
18
|
+
* enrolled client can recover any generation's key ({@link
|
|
19
|
+
* unwrapUserKeyGenerations}) -- needed both to recognize a stale epoch and to
|
|
20
|
+
* escrow the fresh user key into a stranded collection's history.
|
|
21
21
|
*
|
|
22
22
|
* One residue, accepted: a collection with NO epochs gets the newest prior
|
|
23
23
|
* generation installed as its first epoch (pre-epoch envelopes are sealed to
|
|
24
|
-
* the era's
|
|
25
|
-
* epoch-of-that-generation envelopes) -- envelopes older than that
|
|
26
|
-
* generation, on a collection every prior cascade missed, stay readable only
|
|
27
|
-
*
|
|
24
|
+
* the era's user key KAK, and the user key IS the epoch construction, so they
|
|
25
|
+
* ARE epoch-of-that-generation envelopes) -- envelopes older than that
|
|
26
|
+
* generation, on a collection every prior cascade missed, stay readable only to
|
|
27
|
+
* sessions that held the older key.
|
|
28
28
|
*/
|
|
29
29
|
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
30
30
|
import type { CollectionEncryption } from '@interop/was-client';
|
|
31
31
|
import { type EncryptionDescriptorStore, type RecipientPublicKey } from '@interop/was-client/edv';
|
|
32
|
-
import { type
|
|
32
|
+
import { type UserKey } from './userKey.js';
|
|
33
33
|
/**
|
|
34
|
-
* A
|
|
34
|
+
* A user key presented as an epoch-roster recipient: the kid is the
|
|
35
35
|
* self-describing `<did:key>#<fingerprint>` form every collection epoch names
|
|
36
36
|
* the user under, and the public key is the did:key's own multibase.
|
|
37
37
|
*
|
|
38
38
|
* @param options {object}
|
|
39
|
-
* @param options.
|
|
39
|
+
* @param options.userKey {UserKey}
|
|
40
40
|
* @returns {RecipientPublicKey}
|
|
41
41
|
*/
|
|
42
|
-
export declare function
|
|
43
|
-
|
|
42
|
+
export declare function userKeyAsRecipient({ userKey }: {
|
|
43
|
+
userKey: UserKey;
|
|
44
44
|
}): RecipientPublicKey;
|
|
45
45
|
/**
|
|
46
|
-
* Recovers every
|
|
47
|
-
* is one generation (its id the generation's did:key, its wrapped secret
|
|
48
|
-
* generation's raw key), escrow-wrapped to every enrolled client -- so this
|
|
49
|
-
* client's key-agreement key unwraps them all, in roster (chronological)
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
46
|
+
* Recovers every user key generation from the roster descriptor: each roster
|
|
47
|
+
* epoch is one generation (its id the generation's did:key, its wrapped secret
|
|
48
|
+
* the generation's raw key), escrow-wrapped to every enrolled client -- so this
|
|
49
|
+
* client's key-agreement key unwraps them all, in roster (chronological) order.
|
|
50
|
+
* A generation whose wrap is missing or fails to unwrap is skipped rather than
|
|
51
|
+
* fatal (the cascade then simply cannot recognize or escrow that generation;
|
|
52
|
+
* the current epoch always unwraps or the roster read itself would have
|
|
53
|
+
* refused).
|
|
54
54
|
*
|
|
55
55
|
* @param options {object}
|
|
56
56
|
* @param options.descriptor {CollectionEncryption} the roster descriptor
|
|
57
57
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
58
58
|
* (identity) key-agreement key
|
|
59
|
-
* @returns {Promise<
|
|
59
|
+
* @returns {Promise<UserKey[]>} the generations, oldest first
|
|
60
60
|
*/
|
|
61
|
-
export declare function
|
|
61
|
+
export declare function unwrapUserKeyGenerations({ descriptor, clientKeyAgreementKey }: {
|
|
62
62
|
descriptor: CollectionEncryption;
|
|
63
63
|
clientKeyAgreementKey: IKeyAgreementKey;
|
|
64
|
-
}): Promise<
|
|
64
|
+
}): Promise<UserKey[]>;
|
|
65
65
|
/**
|
|
66
|
-
* What one collection's cascade step did: `noop` (already on the current
|
|
67
|
-
*
|
|
68
|
-
* gained its first epoch; nothing to retire), `escrowed` (the current
|
|
69
|
-
* wrap was completed into history with no stale epoch to rotate), or
|
|
70
|
-
* `rotated` (a fresh epoch sealed to the current
|
|
71
|
-
* retired -- the pre-epoch install falls through to this).
|
|
66
|
+
* What one collection's cascade step did: `noop` (already on the current user
|
|
67
|
+
* key), `installed` (a pre-epoch collection on a first-generation account
|
|
68
|
+
* gained its first epoch; nothing to retire), `escrowed` (the current user
|
|
69
|
+
* key's wrap was completed into history with no stale epoch to rotate), or
|
|
70
|
+
* `rotated` (a fresh epoch sealed to the current user key, the stale
|
|
71
|
+
* generations retired -- the pre-epoch install falls through to this).
|
|
72
72
|
*/
|
|
73
|
-
export type
|
|
73
|
+
export type CollectionUserKeyRotationOutcome = 'noop' | 'installed' | 'escrowed' | 'rotated';
|
|
74
74
|
/**
|
|
75
|
-
* Brings ONE encrypted collection's epoch roster onto the current
|
|
76
|
-
* per-collection op of the revocation cascade and of the completion sweep:
|
|
75
|
+
* Brings ONE encrypted collection's epoch roster onto the current user key --
|
|
76
|
+
* the per-collection op of the revocation cascade and of the completion sweep:
|
|
77
77
|
*
|
|
78
78
|
* - **No epochs yet**: install the newest PRIOR generation as the first epoch
|
|
79
|
-
* (see the module doc), wrapped to that generation and the current
|
|
79
|
+
* (see the module doc), wrapped to that generation and the current user key,
|
|
80
80
|
* then fall through to the rotation. A first-generation account (nothing
|
|
81
|
-
* prior) installs the current
|
|
81
|
+
* prior) installs the current user key alone and is done.
|
|
82
82
|
* - **Stale current epoch** (names a non-current generation): one
|
|
83
|
-
* `replaceRecipient` write -- the current
|
|
83
|
+
* `replaceRecipient` write -- the current user key escrowed into every epoch,
|
|
84
84
|
* a fresh epoch minted without the stale generations. Two requests per
|
|
85
85
|
* collection; app recipients and other readers ride through untouched (the
|
|
86
86
|
* default did:key resolver re-wraps them).
|
|
87
87
|
* - **Current already** and fully escrowed: no write at all, so a naive
|
|
88
88
|
* re-run after a mid-cascade crash converges with zero redundant epochs.
|
|
89
89
|
*
|
|
90
|
-
* The pull axis is deliberately a no-op here: a
|
|
90
|
+
* The pull axis is deliberately a no-op here: a user key rotation follows a
|
|
91
91
|
* document edit (client revocation, code retirement) that already killed the
|
|
92
92
|
* revoked party's server-side access everywhere under the current-key-set
|
|
93
93
|
* rule -- there is no per-collection revoke.
|
|
@@ -95,35 +95,35 @@ export type CollectionPukRotationOutcome = 'noop' | 'installed' | 'escrowed' | '
|
|
|
95
95
|
* @param options {object}
|
|
96
96
|
* @param options.store {EncryptionDescriptorStore} the collection's
|
|
97
97
|
* descriptor store
|
|
98
|
-
* @param options.
|
|
99
|
-
* @param options.generations {
|
|
100
|
-
* could unwrap ({@link
|
|
101
|
-
* @returns {Promise<
|
|
98
|
+
* @param options.userKey {UserKey} the roster's CURRENT user key
|
|
99
|
+
* @param options.generations {UserKey[]} every roster generation this client
|
|
100
|
+
* could unwrap ({@link unwrapUserKeyGenerations}), oldest first
|
|
101
|
+
* @returns {Promise<CollectionUserKeyRotationOutcome>}
|
|
102
102
|
*/
|
|
103
|
-
export declare function
|
|
103
|
+
export declare function rotateCollectionEpochsToUserKey({ store, userKey, generations }: {
|
|
104
104
|
store: EncryptionDescriptorStore;
|
|
105
|
-
|
|
106
|
-
generations:
|
|
107
|
-
}): Promise<
|
|
105
|
+
userKey: UserKey;
|
|
106
|
+
generations: UserKey[];
|
|
107
|
+
}): Promise<CollectionUserKeyRotationOutcome>;
|
|
108
108
|
/**
|
|
109
109
|
* What the collection fan-out did, per collection id: the outcomes for every
|
|
110
110
|
* collection that needed (or took) work, and the per-collection failures the
|
|
111
111
|
* caller surfaces -- the cascade never aborts on one stuck collection.
|
|
112
112
|
*/
|
|
113
|
-
export interface
|
|
114
|
-
outcomes: Record<string,
|
|
113
|
+
export interface UserKeyCascadeResult {
|
|
114
|
+
outcomes: Record<string, CollectionUserKeyRotationOutcome>;
|
|
115
115
|
failed: Array<{
|
|
116
116
|
collectionId: string;
|
|
117
117
|
error: unknown;
|
|
118
118
|
}>;
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
|
-
* The collection fan-out of the
|
|
122
|
-
* collection onto the roster's current
|
|
123
|
-
* generations from the roster once. The wallet supplies what only
|
|
124
|
-
* which collections exist (`collectionIds`) and how to reach each
|
|
125
|
-
* descriptor (`storeFor`); the per-collection staleness rule and re-epoch
|
|
126
|
-
* in {@link
|
|
121
|
+
* The collection fan-out of the user key rotation cascade: re-epochs every
|
|
122
|
+
* named collection onto the roster's current user key, in parallel, unwrapping
|
|
123
|
+
* the user key generations from the roster once. The wallet supplies what only
|
|
124
|
+
* it knows -- which collections exist (`collectionIds`) and how to reach each
|
|
125
|
+
* one's descriptor (`storeFor`); the per-collection staleness rule and re-epoch
|
|
126
|
+
* live in {@link rotateCollectionEpochsToUserKey}.
|
|
127
127
|
*
|
|
128
128
|
* A collection that fails is reported in `failed` and the rest proceed; the
|
|
129
129
|
* caller decides what a failure means (the login-time completion sweep is the
|
|
@@ -140,18 +140,18 @@ export interface PukCascadeResult {
|
|
|
140
140
|
* own task so a throwing check lands in that collection's `failed` entry
|
|
141
141
|
* (e.g. a standard collection an account never provisioned server-side)
|
|
142
142
|
* @param options.rosterDescriptor {CollectionEncryption} the freshly read
|
|
143
|
-
* `key-map/
|
|
143
|
+
* `key-map/user-key.json` roster (the source of the user key generations)
|
|
144
144
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
145
145
|
* (identity) key-agreement key, unwrapping the generations
|
|
146
|
-
* @param options.
|
|
147
|
-
* @returns {Promise<
|
|
146
|
+
* @param options.userKey {UserKey} the roster's current user key
|
|
147
|
+
* @returns {Promise<UserKeyCascadeResult>}
|
|
148
148
|
*/
|
|
149
|
-
export declare function
|
|
149
|
+
export declare function cascadeCollectionsToUserKey({ collectionIds, storeFor, isEncrypted, rosterDescriptor, clientKeyAgreementKey, userKey }: {
|
|
150
150
|
collectionIds: string[];
|
|
151
151
|
storeFor: (collectionId: string) => EncryptionDescriptorStore;
|
|
152
152
|
isEncrypted?: (collectionId: string) => Promise<boolean>;
|
|
153
153
|
rosterDescriptor: CollectionEncryption;
|
|
154
154
|
clientKeyAgreementKey: IKeyAgreementKey;
|
|
155
|
-
|
|
156
|
-
}): Promise<
|
|
157
|
-
//# sourceMappingURL=
|
|
155
|
+
userKey: UserKey;
|
|
156
|
+
}): Promise<UserKeyCascadeResult>;
|
|
157
|
+
//# sourceMappingURL=userKeyCascade.d.ts.map
|