@interop/wallet-core 0.23.1 → 0.24.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 +33 -18
- package/dist/clients/revocation.d.ts +3 -6
- package/dist/clients/revocation.d.ts.map +1 -1
- package/dist/clients/revocation.js +5 -9
- package/dist/clients/revocation.js.map +1 -1
- package/dist/clients/rosterPolicy.d.ts +11 -17
- package/dist/clients/rosterPolicy.d.ts.map +1 -1
- package/dist/clients/rosterPolicy.js +22 -27
- package/dist/clients/rosterPolicy.js.map +1 -1
- package/dist/enrollment/enrollment.d.ts +2 -2
- package/dist/enrollment/enrollment.d.ts.map +1 -1
- package/dist/enrollment/enrollment.js +15 -10
- package/dist/enrollment/enrollment.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/keys/index.d.ts +11 -8
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +11 -8
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/rosterLogStore.d.ts +34 -0
- package/dist/keys/rosterLogStore.d.ts.map +1 -0
- package/dist/keys/rosterLogStore.js +110 -0
- package/dist/keys/rosterLogStore.js.map +1 -0
- package/dist/keys/rosterStore.d.ts +18 -4
- package/dist/keys/rosterStore.d.ts.map +1 -1
- package/dist/keys/rosterStore.js +35 -16
- package/dist/keys/rosterStore.js.map +1 -1
- package/dist/keys/userKeyCascade.d.ts +1 -1
- package/dist/keys/userKeyCascade.js +1 -1
- package/dist/keys/userKeyRoster.d.ts +50 -97
- package/dist/keys/userKeyRoster.d.ts.map +1 -1
- package/dist/keys/userKeyRoster.js +44 -145
- package/dist/keys/userKeyRoster.js.map +1 -1
- package/dist/request/appKey.d.ts +254 -0
- package/dist/request/appKey.d.ts.map +1 -0
- package/dist/request/appKey.js +498 -0
- package/dist/request/appKey.js.map +1 -0
- package/dist/request/classify.d.ts +54 -3
- package/dist/request/classify.d.ts.map +1 -1
- package/dist/request/classify.js +106 -0
- package/dist/request/classify.js.map +1 -1
- package/dist/request/index.d.ts +4 -0
- package/dist/request/index.d.ts.map +1 -1
- package/dist/request/index.js +4 -0
- package/dist/request/index.js.map +1 -1
- package/dist/request/processRequest.d.ts.map +1 -1
- package/dist/request/processRequest.js +15 -6
- package/dist/request/processRequest.js.map +1 -1
- package/dist/request/types.d.ts +45 -2
- package/dist/request/types.d.ts.map +1 -1
- package/dist/resourceLog/append.d.ts +103 -0
- package/dist/resourceLog/append.d.ts.map +1 -0
- package/dist/resourceLog/append.js +190 -0
- package/dist/resourceLog/append.js.map +1 -0
- package/dist/resourceLog/controller.d.ts +57 -0
- package/dist/resourceLog/controller.d.ts.map +1 -0
- package/dist/resourceLog/controller.js +81 -0
- package/dist/resourceLog/controller.js.map +1 -0
- package/dist/resourceLog/entry.d.ts +68 -0
- package/dist/resourceLog/entry.d.ts.map +1 -0
- package/dist/resourceLog/entry.js +167 -0
- package/dist/resourceLog/entry.js.map +1 -0
- package/dist/resourceLog/errors.d.ts +75 -0
- package/dist/resourceLog/errors.d.ts.map +1 -0
- package/dist/resourceLog/errors.js +76 -0
- package/dist/resourceLog/errors.js.map +1 -0
- package/dist/resourceLog/index.d.ts +23 -0
- package/dist/resourceLog/index.d.ts.map +1 -0
- package/dist/resourceLog/index.js +23 -0
- package/dist/resourceLog/index.js.map +1 -0
- package/dist/resourceLog/pin.d.ts +44 -0
- package/dist/resourceLog/pin.d.ts.map +1 -0
- package/dist/resourceLog/pin.js +32 -0
- package/dist/resourceLog/pin.js.map +1 -0
- package/dist/resourceLog/verify.d.ts +89 -0
- package/dist/resourceLog/verify.d.ts.map +1 -0
- package/dist/resourceLog/verify.js +434 -0
- package/dist/resourceLog/verify.js.map +1 -0
- package/dist/space/collections.d.ts +14 -11
- package/dist/space/collections.d.ts.map +1 -1
- package/dist/space/collections.js +14 -11
- 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/webvh/didWeb.d.ts +4 -6
- package/dist/webvh/didWeb.d.ts.map +1 -1
- package/dist/webvh/didWeb.js.map +1 -1
- package/dist/webvh/didWebvh.d.ts +1 -2
- package/dist/webvh/didWebvh.d.ts.map +1 -1
- package/dist/webvh/didWebvh.js +1 -6
- package/dist/webvh/didWebvh.js.map +1 -1
- package/package.json +10 -4
package/dist/keys/index.js
CHANGED
|
@@ -13,13 +13,15 @@
|
|
|
13
13
|
* strict validation of the local client-key record each client keeps its own
|
|
14
14
|
* key material in (storage and wrapping stay app-side).
|
|
15
15
|
* - `ensureUserKeyRoster` / `addUserKeyRosterRecipient` / `readUserKeyRoster` /
|
|
16
|
-
* `userKeyRosterRecipientResolver` -- the
|
|
17
|
-
* was-client descriptor-store seam, with the
|
|
18
|
-
* resource-hosted descriptor needs (
|
|
19
|
-
* and a recipient resolver backed by the locally
|
|
20
|
-
* document).
|
|
21
|
-
* - `userKeyRosterDescriptorStore` -- that
|
|
22
|
-
*
|
|
16
|
+
* `userKeyRosterRecipientResolver` -- the user key roster over the
|
|
17
|
+
* was-client descriptor-store seam, with the client-side guards a
|
|
18
|
+
* resource-hosted descriptor needs (the governing resource log, the
|
|
19
|
+
* latest-seen epoch pin, and a recipient resolver backed by the locally
|
|
20
|
+
* verified did:webvh document).
|
|
21
|
+
* - `userKeyRosterDescriptorStore` / `logGovernedDescriptorStore` -- that
|
|
22
|
+
* descriptor store: reads resolve to the roster log's verified head
|
|
23
|
+
* (`key-map/user-key.jsonl`), writes append signed entries; built from a
|
|
24
|
+
* bare signing client for the login-time direct read.
|
|
23
25
|
* - `rosterRecipientKid` -- the one builder of a client's roster kid, shared by
|
|
24
26
|
* the enrollment wrap, the roster read, and the rotation that retires it.
|
|
25
27
|
* - `convergeUserKeyRosterToDocument` -- the standing detector for a revocation
|
|
@@ -42,9 +44,10 @@
|
|
|
42
44
|
*/
|
|
43
45
|
export { mintUserKey, userKeyVaultKeys } from './userKey.js';
|
|
44
46
|
export { assertEnrolledClientKeyRecord, decodeClientKeyRecord, encodeClientKeyRecord, parseClientRecordUserKey, parseClientRecordWebvhKeys } from './clientKeyRecord.js';
|
|
45
|
-
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError,
|
|
47
|
+
export { addUserKeyRosterRecipient, convergeUserKeyRosterToDocument, ensureUserKeyRoster, UserKeyRosterContinuityError, UserKeyRosterIntegrityError, UserKeyRosterUnwrapError, userKeyRosterLogSigner, userKeyRosterRecipientResolver, readUserKeyRoster, rosterRecipientKid, rotateUserKeyRoster } from './userKeyRoster.js';
|
|
46
48
|
export { cascadeCollectionsToUserKey, userKeyAsRecipient, rotateCollectionEpochsToUserKey, unwrapUserKeyGenerations } from './userKeyCascade.js';
|
|
47
49
|
export { userKeyRosterDescriptorStore } from './rosterStore.js';
|
|
50
|
+
export { EPOCH_CONFIGURATION_STATE_TYPE, logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
48
51
|
export { ensureWalletSpaceEpochs } from './spaceEpochs.js';
|
|
49
52
|
export { readClientLabels, removeClientLabel, setClientLabel } from './clientLabels.js';
|
|
50
53
|
export { wasClientLabelsStore } from './wasLabelsStore.js';
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;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,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACpB,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;AAC/D,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,EAC3B,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAG1D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
2
|
+
import { type ResourceLogStore } from '@interop/was-client/log';
|
|
3
|
+
import { type ResourceLogController, type ResourceLogPinStore, type ResourceLogSigner } from '../resourceLog/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* The state-document schema identifier an encryption descriptor carries in a
|
|
6
|
+
* governed log entry, per WAS-EC.
|
|
7
|
+
*/
|
|
8
|
+
export declare const EPOCH_CONFIGURATION_STATE_TYPE = "WasEpochConfiguration";
|
|
9
|
+
/**
|
|
10
|
+
* Builds the log-governed `EncryptionDescriptorStore`.
|
|
11
|
+
*
|
|
12
|
+
* The controller view is resolved per operation (never held), so a caller
|
|
13
|
+
* that just edited the account document -- a revocation about to rotate the
|
|
14
|
+
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
15
|
+
* which is exactly what makes its rotation the sealing append.
|
|
16
|
+
*
|
|
17
|
+
* @param options {object}
|
|
18
|
+
* @param options.log {ResourceLogStore} the log's transport seam
|
|
19
|
+
* @param options.resolveController {function} `() => Promise<ResourceLogController>`
|
|
20
|
+
* -- the caller's currently verified controller view
|
|
21
|
+
* (`webvhResourceLogController` over a `verifyAccountLog` result)
|
|
22
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head pin
|
|
23
|
+
* for this log
|
|
24
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
25
|
+
* key, for the appends this store writes
|
|
26
|
+
* @returns {EncryptionDescriptorStore}
|
|
27
|
+
*/
|
|
28
|
+
export declare function logGovernedDescriptorStore({ log, resolveController, pinStore, signer }: {
|
|
29
|
+
log: ResourceLogStore;
|
|
30
|
+
resolveController: () => Promise<ResourceLogController>;
|
|
31
|
+
pinStore: ResourceLogPinStore;
|
|
32
|
+
signer: ResourceLogSigner;
|
|
33
|
+
}): EncryptionDescriptorStore;
|
|
34
|
+
//# sourceMappingURL=rosterLogStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rosterLogStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAOL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEvB,MAAM,yBAAyB,CAAA;AAEhC;;;GAGG;AACH,eAAO,MAAM,8BAA8B,0BAA0B,CAAA;AAErE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,iBAAiB,EACjB,QAAQ,EACR,MAAM,EACP,EAAE;IACD,GAAG,EAAE,gBAAgB,CAAA;IACrB,iBAAiB,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvD,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,GAAG,yBAAyB,CAqG5B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { confirmAppend, WAS_RESOURCE_LOG_METHOD } from '@interop/was-client/log';
|
|
2
|
+
import { buildResourceLogEntry, buildResourceLogGenesis, readResourceLog, ResourceLogClosedError, ResourceLogIntegrityError, verifyResourceLog } from '../resourceLog/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The state-document schema identifier an encryption descriptor carries in a
|
|
5
|
+
* governed log entry, per WAS-EC.
|
|
6
|
+
*/
|
|
7
|
+
export const EPOCH_CONFIGURATION_STATE_TYPE = 'WasEpochConfiguration';
|
|
8
|
+
/**
|
|
9
|
+
* Builds the log-governed `EncryptionDescriptorStore`.
|
|
10
|
+
*
|
|
11
|
+
* The controller view is resolved per operation (never held), so a caller
|
|
12
|
+
* that just edited the account document -- a revocation about to rotate the
|
|
13
|
+
* roster -- writes entries anchored at the post-edit head it now verifies,
|
|
14
|
+
* which is exactly what makes its rotation the sealing append.
|
|
15
|
+
*
|
|
16
|
+
* @param options {object}
|
|
17
|
+
* @param options.log {ResourceLogStore} the log's transport seam
|
|
18
|
+
* @param options.resolveController {function} `() => Promise<ResourceLogController>`
|
|
19
|
+
* -- the caller's currently verified controller view
|
|
20
|
+
* (`webvhResourceLogController` over a `verifyAccountLog` result)
|
|
21
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head pin
|
|
22
|
+
* for this log
|
|
23
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
24
|
+
* key, for the appends this store writes
|
|
25
|
+
* @returns {EncryptionDescriptorStore}
|
|
26
|
+
*/
|
|
27
|
+
export function logGovernedDescriptorStore({ log, resolveController, pinStore, signer }) {
|
|
28
|
+
// The verified log observed by the most recent read on this store instance;
|
|
29
|
+
// a replace builds its entry on that head, pinned to the same read's etag,
|
|
30
|
+
// so a stale head loses the CAS instead of forking.
|
|
31
|
+
let lastVerified = null;
|
|
32
|
+
function toState(descriptor) {
|
|
33
|
+
const { history: _history, ...rest } = descriptor;
|
|
34
|
+
return { ...rest, type: EPOCH_CONFIGURATION_STATE_TYPE };
|
|
35
|
+
}
|
|
36
|
+
async function settle({ entry, controller }) {
|
|
37
|
+
const readBack = await confirmAppend({ store: log, entry });
|
|
38
|
+
const confirmed = await verifyResourceLog({
|
|
39
|
+
entries: readBack.entries,
|
|
40
|
+
controller,
|
|
41
|
+
expectedMethod: WAS_RESOURCE_LOG_METHOD,
|
|
42
|
+
pin: await pinStore.read()
|
|
43
|
+
});
|
|
44
|
+
await pinStore.write(confirmed.pin);
|
|
45
|
+
lastVerified = confirmed;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
async read() {
|
|
49
|
+
const controller = await resolveController();
|
|
50
|
+
const current = await readResourceLog({
|
|
51
|
+
store: log,
|
|
52
|
+
controller,
|
|
53
|
+
expectedMethod: WAS_RESOURCE_LOG_METHOD,
|
|
54
|
+
pinStore
|
|
55
|
+
});
|
|
56
|
+
if (current === null) {
|
|
57
|
+
lastVerified = null;
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const state = current.verified.state;
|
|
61
|
+
if (state.type !== EPOCH_CONFIGURATION_STATE_TYPE) {
|
|
62
|
+
throw new ResourceLogIntegrityError(`The governed descriptor log carries state of type ` +
|
|
63
|
+
`"${state.type}", not "${EPOCH_CONFIGURATION_STATE_TYPE}".`);
|
|
64
|
+
}
|
|
65
|
+
lastVerified = current.verified;
|
|
66
|
+
return {
|
|
67
|
+
descriptor: state,
|
|
68
|
+
etag: current.etag
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
async replace(descriptor, { ifMatch }) {
|
|
72
|
+
if (lastVerified === null) {
|
|
73
|
+
throw new Error('Cannot replace the governed descriptor: replace must follow a ' +
|
|
74
|
+
'read on the same store instance.');
|
|
75
|
+
}
|
|
76
|
+
if (ifMatch === undefined) {
|
|
77
|
+
throw new Error('Cannot replace the governed descriptor: the backend returned no ' +
|
|
78
|
+
'validator, and the profile forbids an unconditional write.');
|
|
79
|
+
}
|
|
80
|
+
if (lastVerified.terminal) {
|
|
81
|
+
throw new ResourceLogClosedError({ nextLog: lastVerified.terminal });
|
|
82
|
+
}
|
|
83
|
+
const controller = await resolveController();
|
|
84
|
+
const entry = await buildResourceLogEntry({
|
|
85
|
+
head: lastVerified.head,
|
|
86
|
+
state: toState(descriptor),
|
|
87
|
+
controller,
|
|
88
|
+
signer
|
|
89
|
+
});
|
|
90
|
+
// A stale validator throws PreconditionFailedError here, which the edv
|
|
91
|
+
// machinery's CAS loop re-reads and rebases on.
|
|
92
|
+
await log.append(entry, { ifMatch });
|
|
93
|
+
await settle({ entry, controller });
|
|
94
|
+
},
|
|
95
|
+
async create(descriptor) {
|
|
96
|
+
const controller = await resolveController();
|
|
97
|
+
const genesis = await buildResourceLogGenesis({
|
|
98
|
+
state: toState(descriptor),
|
|
99
|
+
method: WAS_RESOURCE_LOG_METHOD,
|
|
100
|
+
controller,
|
|
101
|
+
signer
|
|
102
|
+
});
|
|
103
|
+
// A lost guarded-create race throws PreconditionFailedError, and the
|
|
104
|
+
// edv machinery re-reads and adopts the winner's descriptor.
|
|
105
|
+
await log.create(genesis);
|
|
106
|
+
await settle({ entry: genesis, controller });
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=rosterLogStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rosterLogStore.js","sourceRoot":"","sources":["../../src/keys/rosterLogStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import type { ZcapClient } from '@interop/ezcap';
|
|
2
|
-
import {
|
|
2
|
+
import type { EncryptionDescriptorStore } from '@interop/was-client/edv';
|
|
3
|
+
import type { ResourceLogController, ResourceLogPinStore, ResourceLogSigner } from '../resourceLog/index.js';
|
|
3
4
|
/**
|
|
4
|
-
* Builds the
|
|
5
|
-
*
|
|
5
|
+
* Builds the log-governed descriptor store over the user key roster in a
|
|
6
|
+
* data Space: reads resolve to the verified head of
|
|
7
|
+
* `key-map/user-key.jsonl`, writes append to it.
|
|
6
8
|
*
|
|
7
9
|
* @param options {object}
|
|
8
10
|
* @param options.storageServerUrl {string}
|
|
9
11
|
* @param options.zcapClient {ZcapClient} the session's root signing client
|
|
10
12
|
* @param options.spaceId {string} the data Space id
|
|
13
|
+
* @param options.resolveController {function}
|
|
14
|
+
* `() => Promise<ResourceLogController>` -- the caller's currently verified
|
|
15
|
+
* controller view (`webvhResourceLogController` over a `verifyAccountLog`
|
|
16
|
+
* result), resolved per operation so post-edit writers anchor at the head
|
|
17
|
+
* they just verified
|
|
18
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head
|
|
19
|
+
* pin for the roster log
|
|
20
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
21
|
+
* key ({@link userKeyRosterLogSigner})
|
|
11
22
|
* @returns {EncryptionDescriptorStore}
|
|
12
23
|
*/
|
|
13
|
-
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }: {
|
|
24
|
+
export declare function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId, resolveController, pinStore, signer }: {
|
|
14
25
|
storageServerUrl: string;
|
|
15
26
|
zcapClient: ZcapClient;
|
|
16
27
|
spaceId: string;
|
|
28
|
+
resolveController: () => Promise<ResourceLogController>;
|
|
29
|
+
pinStore: ResourceLogPinStore;
|
|
30
|
+
signer: ResourceLogSigner;
|
|
17
31
|
}): EncryptionDescriptorStore;
|
|
18
32
|
//# sourceMappingURL=rosterStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rosterStore.d.ts","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAA;AAExE,OAAO,KAAK,EACV,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,yBAAyB,CAAA;AAOhC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,MAAM,EACP,EAAE;IACD,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,UAAU,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,iBAAiB,EAAE,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACvD,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,MAAM,EAAE,iBAAiB,CAAA;CAC1B,GAAG,yBAAyB,CAa5B"}
|
package/dist/keys/rosterStore.js
CHANGED
|
@@ -2,37 +2,56 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The descriptor store over a Space's user key wrap-set roster
|
|
6
|
-
* (`key-map/user-key.
|
|
7
|
-
* remote-store class, because the
|
|
8
|
-
* BEFORE any storage client (or
|
|
9
|
-
* client instead of a store
|
|
5
|
+
* The descriptor store over a Space's user key wrap-set roster -- since the
|
|
6
|
+
* roster became log-governed, over its resource log (`key-map/user-key.jsonl`).
|
|
7
|
+
* Standalone rather than a method on a wallet's remote-store class, because the
|
|
8
|
+
* login-time direct read checks the roster BEFORE any storage client (or
|
|
9
|
+
* cipher) is built: it takes the bare signing client instead of a store
|
|
10
|
+
* instance.
|
|
10
11
|
*
|
|
11
|
-
* The `plaintext` collection override is load-bearing. Without it
|
|
12
|
-
* decides plaintext vs encrypted by describing the collection
|
|
13
|
-
* from an absent Space or collection then surfaces as an
|
|
14
|
-
* rather than as an absent roster
|
|
12
|
+
* The `plaintext` collection override is load-bearing twice over. Without it
|
|
13
|
+
* the client decides plaintext vs encrypted by describing the collection
|
|
14
|
+
* first, and a 404 from an absent Space or collection then surfaces as an
|
|
15
|
+
* encryption error rather than as an absent roster; and on an encrypted
|
|
16
|
+
* collection the EDV codec would compute the write preconditions itself, so
|
|
17
|
+
* the log's compare-and-swap append guard would not be honored.
|
|
15
18
|
*/
|
|
16
19
|
import { WasClient } from '@interop/was-client';
|
|
17
|
-
import {
|
|
18
|
-
import { KEY_MAP_COLLECTION,
|
|
20
|
+
import { resourceLogStore } from '@interop/was-client/log';
|
|
21
|
+
import { KEY_MAP_COLLECTION, USER_KEY_ROSTER_LOG_RESOURCE } from '../space/collections.js';
|
|
22
|
+
import { logGovernedDescriptorStore } from './rosterLogStore.js';
|
|
19
23
|
/**
|
|
20
|
-
* Builds the
|
|
21
|
-
*
|
|
24
|
+
* Builds the log-governed descriptor store over the user key roster in a
|
|
25
|
+
* data Space: reads resolve to the verified head of
|
|
26
|
+
* `key-map/user-key.jsonl`, writes append to it.
|
|
22
27
|
*
|
|
23
28
|
* @param options {object}
|
|
24
29
|
* @param options.storageServerUrl {string}
|
|
25
30
|
* @param options.zcapClient {ZcapClient} the session's root signing client
|
|
26
31
|
* @param options.spaceId {string} the data Space id
|
|
32
|
+
* @param options.resolveController {function}
|
|
33
|
+
* `() => Promise<ResourceLogController>` -- the caller's currently verified
|
|
34
|
+
* controller view (`webvhResourceLogController` over a `verifyAccountLog`
|
|
35
|
+
* result), resolved per operation so post-edit writers anchor at the head
|
|
36
|
+
* they just verified
|
|
37
|
+
* @param options.pinStore {ResourceLogPinStore} this client's chain-head
|
|
38
|
+
* pin for the roster log
|
|
39
|
+
* @param options.signer {ResourceLogSigner} this client's enrolled signing
|
|
40
|
+
* key ({@link userKeyRosterLogSigner})
|
|
27
41
|
* @returns {EncryptionDescriptorStore}
|
|
28
42
|
*/
|
|
29
|
-
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId }) {
|
|
43
|
+
export function userKeyRosterDescriptorStore({ storageServerUrl, zcapClient, spaceId, resolveController, pinStore, signer }) {
|
|
30
44
|
const was = new WasClient({ serverUrl: storageServerUrl, zcapClient });
|
|
31
45
|
const collection = was
|
|
32
46
|
.space(spaceId)
|
|
33
47
|
.collection(KEY_MAP_COLLECTION.id, { encryption: 'plaintext' });
|
|
34
|
-
return
|
|
35
|
-
|
|
48
|
+
return logGovernedDescriptorStore({
|
|
49
|
+
log: resourceLogStore({
|
|
50
|
+
resource: collection.resource(USER_KEY_ROSTER_LOG_RESOURCE)
|
|
51
|
+
}),
|
|
52
|
+
resolveController,
|
|
53
|
+
pinStore,
|
|
54
|
+
signer
|
|
36
55
|
});
|
|
37
56
|
}
|
|
38
57
|
//# sourceMappingURL=rosterStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"rosterStore.js","sourceRoot":"","sources":["../../src/keys/rosterStore.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAM1D,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC7B,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAEhE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,4BAA4B,CAAC,EAC3C,gBAAgB,EAChB,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,QAAQ,EACR,MAAM,EAQP;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,0BAA0B,CAAC;QAChC,GAAG,EAAE,gBAAgB,CAAC;YACpB,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SAC5D,CAAC;QACF,iBAAiB;QACjB,QAAQ;QACR,MAAM;KACP,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -138,7 +138,7 @@ export interface UserKeyCascadeResult {
|
|
|
138
138
|
* own task so a throwing check lands in that collection's `failed` entry
|
|
139
139
|
* (e.g. a standard collection an account never provisioned server-side)
|
|
140
140
|
* @param options.rosterDescriptor {CollectionEncryption} the freshly read
|
|
141
|
-
* `key-map/user-key.
|
|
141
|
+
* `key-map/user-key.jsonl` roster (the source of the user key generations)
|
|
142
142
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
143
143
|
* (identity) key-agreement key, unwrapping the generations
|
|
144
144
|
* @param options.userKey {UserKey} the roster's current user key
|
|
@@ -170,7 +170,7 @@ export async function rotateCollectionEpochsToUserKey({ store, userKey, generati
|
|
|
170
170
|
* own task so a throwing check lands in that collection's `failed` entry
|
|
171
171
|
* (e.g. a standard collection an account never provisioned server-side)
|
|
172
172
|
* @param options.rosterDescriptor {CollectionEncryption} the freshly read
|
|
173
|
-
* `key-map/user-key.
|
|
173
|
+
* `key-map/user-key.jsonl` roster (the source of the user key generations)
|
|
174
174
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
175
175
|
* (identity) key-agreement key, unwrapping the generations
|
|
176
176
|
* @param options.userKey {UserKey} the roster's current user key
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2026 Interop Alliance. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
|
-
* The user key wrap set: the `key-map/user-key.
|
|
5
|
+
* The user key wrap set: the roster governed by `key-map/user-key.jsonl`. Its state
|
|
6
6
|
* is a `CollectionEncryption` descriptor verbatim, whose current epoch IS the
|
|
7
7
|
* current user key -- the epoch id is the user key's did:key and the wrapped
|
|
8
8
|
* secret is the user key's raw 32-byte key, wrapped to each enrolled client's
|
|
@@ -10,25 +10,34 @@
|
|
|
10
10
|
* each client keeps the user key in its own local state under the unlock layer,
|
|
11
11
|
* and the roster's epoch stamp marks a cached copy stale.
|
|
12
12
|
*
|
|
13
|
-
* Everything mutates through was-client's descriptor-store seam
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* Everything mutates through was-client's descriptor-store seam -- since the
|
|
14
|
+
* roster became log-governed, the log-backed adapter
|
|
15
|
+
* (`logGovernedDescriptorStore`): reads resolve to the roster log's VERIFIED
|
|
16
|
+
* head state, writes append signed entries. No descriptor logic is
|
|
16
17
|
* reimplemented here.
|
|
17
18
|
*
|
|
18
19
|
* A resource-hosted descriptor gets NONE of the server-side epoch invariants a
|
|
19
20
|
* Collection Description enforces (append-only epochs, monotone
|
|
20
|
-
* `currentEpoch`), so
|
|
21
|
+
* `currentEpoch`), so the client-side compensations are load-bearing alone
|
|
21
22
|
* against a tampering host:
|
|
22
23
|
*
|
|
23
|
-
* -
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* - **The resource log** -- the roster is governed by a hash-linked log whose
|
|
25
|
+
* every entry is signed by an enrolled client's key, anchored in the
|
|
26
|
+
* locally verified did:webvh document, and continuity-checked against the
|
|
27
|
+
* client's chain-head pin (the `resourceLog` module). A fabricated roster
|
|
28
|
+
* fails entry-proof verification (`ResourceLogIntegrityError`); a rolled
|
|
29
|
+
* back, forked, or format-switched log fails continuity
|
|
30
|
+
* (`ResourceLogContinuityError`). This is the successor of the retired
|
|
31
|
+
* detached `epochsSig`: the entry proof covers the whole configuration, on
|
|
32
|
+
* every read instead of only the adopt path. (The `epochsMac`
|
|
33
|
+
* epoch-configuration MAC that used to sit beneath it is retired stack-wide:
|
|
34
|
+
* on a log-governed resource its coverage was a strict subset of chain
|
|
35
|
+
* verification.)
|
|
26
36
|
* - **The epoch pin** -- the latest-seen roster epoch is pinned locally by the
|
|
27
37
|
* consuming app (beside the account-pointer pin); a served
|
|
28
38
|
* roster that rolls back behind the pin is refused
|
|
29
|
-
* (`UserKeyRosterContinuityError`) rather than followed
|
|
30
|
-
*
|
|
31
|
-
* account pointer.
|
|
39
|
+
* (`UserKeyRosterContinuityError`) rather than followed, even where the
|
|
40
|
+
* chain-head pin was lost with a reinstalled client.
|
|
32
41
|
* - **The roster delivers, never sources** -- the recipient-key source of
|
|
33
42
|
* record is the locally verified did:webvh document (one `keyAgreement`
|
|
34
43
|
* verification method per enrolled client). When an epoch rotates, each
|
|
@@ -37,28 +46,18 @@
|
|
|
37
46
|
* verification method is dropped and never receives a wrap, so a
|
|
38
47
|
* server-injected entry sits ignored. Wraps are minted only by enrolled
|
|
39
48
|
* clients, against log-verified keys.
|
|
40
|
-
* - **`epochsSig`** -- the epoch configuration is additionally SIGNED by the
|
|
41
|
-
* writing client's enrolled Ed25519 key (`userKeyRosterEpochsSigner`), and a
|
|
42
|
-
* read that adopts an epoch this client has not vouched for itself (a
|
|
43
|
-
* rotated read, or a freshly enrolled client's first read) verifies that
|
|
44
|
-
* signature against the locally verified did:webvh document
|
|
45
|
-
* (`verifyUserKeyRosterEpochsSig`). This is the check the `epochsMac` alone
|
|
46
|
-
* cannot make on those paths: the MAC is keyed by a secret unwrapped from
|
|
47
|
-
* the served descriptor itself, so a host that mints its own epoch, wraps
|
|
48
|
-
* it to this client's world-readable key-agreement key, and MACs the
|
|
49
|
-
* fabricated configuration under the same minted secret passes the MAC --
|
|
50
|
-
* but it cannot produce a signature by a key the document backs.
|
|
51
49
|
*/
|
|
52
50
|
import type { IKeyAgreementKey } from '@interop/data-integrity-core';
|
|
53
51
|
import type { CollectionEncryption } from '@interop/was-client';
|
|
54
|
-
import { type EncryptionDescriptorStore, type
|
|
52
|
+
import { type EncryptionDescriptorStore, type RecipientPublicKey } from '@interop/was-client/edv';
|
|
53
|
+
import type { ResourceLogSigner } from '../resourceLog/index.js';
|
|
55
54
|
import { type ICapabilityAgent } from '../webvh/zcap.js';
|
|
56
55
|
import type { UserKey } from './userKey.js';
|
|
57
56
|
/**
|
|
58
|
-
* Thrown when a served roster fails its client-side
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
57
|
+
* Thrown when a served roster fails its client-side consistency checks: a
|
|
58
|
+
* descriptor whose `currentEpoch` names no epoch in its own list. The server
|
|
59
|
+
* (or whoever can write to it) has produced a configuration no enrolled
|
|
60
|
+
* client authenticated.
|
|
62
61
|
*/
|
|
63
62
|
export declare class UserKeyRosterIntegrityError extends Error {
|
|
64
63
|
constructor(message: string);
|
|
@@ -67,8 +66,7 @@ export declare class UserKeyRosterIntegrityError extends Error {
|
|
|
67
66
|
* Thrown when a served roster conflicts with the locally pinned latest-seen
|
|
68
67
|
* epoch -- the epochs list no longer contains the pinned epoch, or
|
|
69
68
|
* `currentEpoch` precedes it in the (append-only) list. A rollback/replay of
|
|
70
|
-
* an older consistent configuration
|
|
71
|
-
* catch; refused rather than followed.
|
|
69
|
+
* an older consistent configuration; refused rather than followed.
|
|
72
70
|
*/
|
|
73
71
|
export declare class UserKeyRosterContinuityError extends Error {
|
|
74
72
|
pinnedEpochId: string;
|
|
@@ -101,40 +99,22 @@ export interface RosterRecipientDocument {
|
|
|
101
99
|
}>;
|
|
102
100
|
}
|
|
103
101
|
/**
|
|
104
|
-
* The roster's
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
102
|
+
* The roster's log signer: signs each roster log append with this client's
|
|
103
|
+
* own Ed25519 signing key, named by its public multibase -- exactly the
|
|
104
|
+
* string enrolled as this client's verification method in the did:webvh
|
|
105
|
+
* document, so a reader resolves the entry proof against the document rather
|
|
106
|
+
* than anything the roster (or the server) supplies. Successor of the retired
|
|
107
|
+
* `epochsSig` signer under the log design.
|
|
110
108
|
*
|
|
111
109
|
* @param options {object}
|
|
112
110
|
* @param options.keyAgent {ICapabilityAgent} this client's signing key
|
|
113
111
|
* agent (the `keyAgent` of `agentsFromSeed`)
|
|
114
|
-
* @returns {
|
|
112
|
+
* @returns {ResourceLogSigner} the signer for the log-governed store's
|
|
113
|
+
* appends
|
|
115
114
|
*/
|
|
116
|
-
export declare function
|
|
115
|
+
export declare function userKeyRosterLogSigner({ keyAgent }: {
|
|
117
116
|
keyAgent: ICapabilityAgent;
|
|
118
|
-
}):
|
|
119
|
-
/**
|
|
120
|
-
* Verifies a served roster's `epochsSig` against the locally verified
|
|
121
|
-
* did:webvh document -- the root of trust the server cannot mint. The
|
|
122
|
-
* signature must be present and supported, its `kid` must be the public
|
|
123
|
-
* multibase of one of the document's verification methods (an enrolled
|
|
124
|
-
* client's signing key), and it must verify over the canonical
|
|
125
|
-
* epoch-configuration payload. Throws {@link UserKeyRosterIntegrityError}
|
|
126
|
-
* otherwise: a configuration no enrolled client signed.
|
|
127
|
-
*
|
|
128
|
-
* @param options {object}
|
|
129
|
-
* @param options.descriptor {CollectionEncryption} the served roster
|
|
130
|
-
* @param options.document {RosterRecipientDocument} the locally verified
|
|
131
|
-
* did:webvh document (never a server-supplied roster field)
|
|
132
|
-
* @returns {Promise<void>}
|
|
133
|
-
*/
|
|
134
|
-
export declare function verifyUserKeyRosterEpochsSig({ descriptor, document }: {
|
|
135
|
-
descriptor: CollectionEncryption;
|
|
136
|
-
document: RosterRecipientDocument;
|
|
137
|
-
}): Promise<void>;
|
|
117
|
+
}): ResourceLogSigner;
|
|
138
118
|
/**
|
|
139
119
|
* A wallet client's roster kid: its key-agreement key's id exactly as
|
|
140
120
|
* `agentsFromSeed` derives it at the client's own logins
|
|
@@ -185,16 +165,12 @@ export declare function userKeyRosterRecipientResolver({ document }: {
|
|
|
185
165
|
* @param options.userKey {UserKey} the account's user key
|
|
186
166
|
* @param options.clientKeyAgreementKey {IKeyAgreementKey} this client's own
|
|
187
167
|
* (identity) key-agreement key -- the roster recipient
|
|
188
|
-
* @param options.signEpochs {EpochsSigner} this client's epoch-configuration
|
|
189
|
-
* signer ({@link userKeyRosterEpochsSigner}), so the first configuration is
|
|
190
|
-
* vouched for by an enrollable key rather than only its own MAC
|
|
191
168
|
* @returns {Promise<CollectionEncryption>} the roster descriptor
|
|
192
169
|
*/
|
|
193
|
-
export declare function ensureUserKeyRoster({ store, userKey, clientKeyAgreementKey
|
|
170
|
+
export declare function ensureUserKeyRoster({ store, userKey, clientKeyAgreementKey }: {
|
|
194
171
|
store: EncryptionDescriptorStore;
|
|
195
172
|
userKey: UserKey;
|
|
196
173
|
clientKeyAgreementKey: IKeyAgreementKey;
|
|
197
|
-
signEpochs: EpochsSigner;
|
|
198
174
|
}): Promise<CollectionEncryption>;
|
|
199
175
|
/**
|
|
200
176
|
* Wraps the user key to a client being enrolled -- the roster half of the
|
|
@@ -246,16 +222,12 @@ export declare function addUserKeyRosterRecipient({ store, recipient, ownerKeyAg
|
|
|
246
222
|
* did:webvh document, AFTER the removal edit
|
|
247
223
|
* @param options.retireRecipientId {string} the removed recipient's roster
|
|
248
224
|
* kid
|
|
249
|
-
* @param options.signEpochs {EpochsSigner} the rotating client's
|
|
250
|
-
* epoch-configuration signer ({@link userKeyRosterEpochsSigner}), vouching for
|
|
251
|
-
* the fresh epoch so other clients' rotated reads accept it
|
|
252
225
|
* @returns {Promise<CollectionEncryption>} the rotated roster descriptor
|
|
253
226
|
*/
|
|
254
|
-
export declare function rotateUserKeyRoster({ store, document, retireRecipientId
|
|
227
|
+
export declare function rotateUserKeyRoster({ store, document, retireRecipientId }: {
|
|
255
228
|
store: EncryptionDescriptorStore;
|
|
256
229
|
document: RosterRecipientDocument;
|
|
257
230
|
retireRecipientId: string;
|
|
258
|
-
signEpochs: EpochsSigner;
|
|
259
231
|
}): Promise<CollectionEncryption>;
|
|
260
232
|
/**
|
|
261
233
|
* Converges the roster onto the account document: the standing detector for a
|
|
@@ -291,18 +263,14 @@ export declare function rotateUserKeyRoster({ store, document, retireRecipientId
|
|
|
291
263
|
* @param [options.descriptor] {CollectionEncryption} a descriptor the caller
|
|
292
264
|
* has just read (a login-time roster read), to save a re-read; omitted, the
|
|
293
265
|
* roster is read fresh
|
|
294
|
-
* @param options.signEpochs {EpochsSigner} the converging client's
|
|
295
|
-
* epoch-configuration signer ({@link userKeyRosterEpochsSigner}), for the
|
|
296
|
-
* rotation this call may perform
|
|
297
266
|
* @returns {Promise<object>} whether the roster rotated on this call, the
|
|
298
267
|
* stale recipient kids found, and the roster descriptor as it now stands
|
|
299
268
|
* (`null` when the account has no roster yet)
|
|
300
269
|
*/
|
|
301
|
-
export declare function convergeUserKeyRosterToDocument({ store, document, descriptor
|
|
270
|
+
export declare function convergeUserKeyRosterToDocument({ store, document, descriptor }: {
|
|
302
271
|
store: EncryptionDescriptorStore;
|
|
303
272
|
document: RosterRecipientDocument;
|
|
304
273
|
descriptor?: CollectionEncryption;
|
|
305
|
-
signEpochs: EpochsSigner;
|
|
306
274
|
}): Promise<{
|
|
307
275
|
rotated: boolean;
|
|
308
276
|
staleRecipientIds: string[];
|
|
@@ -325,24 +293,19 @@ export interface UserKeyRosterReadResult {
|
|
|
325
293
|
* mismatch. Resolves `null` when the roster does not exist yet (an account
|
|
326
294
|
* provisioned before the roster, or provisioning still in flight); otherwise:
|
|
327
295
|
*
|
|
328
|
-
* 1. **
|
|
296
|
+
* 1. **Provenance** is the store's: a log-governed store resolves the read
|
|
297
|
+
* from the roster log's verified head -- entry proofs checked against the
|
|
298
|
+
* locally verified did:webvh document, chain-head pin enforced -- so
|
|
299
|
+
* every epoch this read can deliver was signed onto the log by an
|
|
300
|
+
* enrolled client. (The detached `epochsSig` this step used to verify on
|
|
301
|
+
* the adopt path is retired; the entry proof covers every read.)
|
|
302
|
+
* 2. **Continuity**: the served epochs must contain the pinned latest-seen
|
|
329
303
|
* epoch, and `currentEpoch` must not precede it in the append-only list
|
|
330
304
|
* (`UserKeyRosterContinuityError` -- the rollback/replay refusal).
|
|
331
|
-
*
|
|
305
|
+
* 3. **Possession**: `currentEpoch === userKey.id` confirms the cached user key
|
|
332
306
|
* current; otherwise the current epoch was rotated by another client and
|
|
333
307
|
* this client's wrap is unwrapped with its own key-agreement key
|
|
334
308
|
* (`UserKeyRosterUnwrapError` when it holds none).
|
|
335
|
-
* 3. **Provenance** (the rotated/first-read path only): the epoch
|
|
336
|
-
* configuration's `epochsSig` is verified against the locally verified
|
|
337
|
-
* did:webvh document ({@link verifyUserKeyRosterEpochsSig}) BEFORE the epoch
|
|
338
|
-
* it delivers is adopted. On this path the `epochsMac` alone proves
|
|
339
|
-
* nothing against the host -- its key is unwrapped from the served
|
|
340
|
-
* descriptor itself -- so an epoch no enrolled client signed is refused
|
|
341
|
-
* (`UserKeyRosterIntegrityError`). The cached-current path needs no signature:
|
|
342
|
-
* there the MAC is keyed by a secret this client already trusts.
|
|
343
|
-
* 4. **Authentication**: the descriptor's `epochsMac` is verified under the
|
|
344
|
-
* current epoch's secret (`UserKeyRosterIntegrityError` on any mismatch -- a
|
|
345
|
-
* fabricated configuration).
|
|
346
309
|
*
|
|
347
310
|
* A rotated read returns the fresh user key; its Ed25519 signing seed does not
|
|
348
311
|
* travel through the roster (the roster wraps the key-agreement secret
|
|
@@ -351,10 +314,7 @@ export interface UserKeyRosterReadResult {
|
|
|
351
314
|
* A caller with no cached user key at all -- a freshly enrolled client making
|
|
352
315
|
* its first post-enrollment read -- omits `userKey` and always takes the unwrap
|
|
353
316
|
* path; the result's `rotated` is then true (the user key was adopted from the
|
|
354
|
-
* roster).
|
|
355
|
-
* (or a way to resolve it): `document` when it already holds a verified copy,
|
|
356
|
-
* or `resolveDocument` to fetch-and-verify lazily, only when the read actually
|
|
357
|
-
* rotates.
|
|
317
|
+
* roster).
|
|
358
318
|
*
|
|
359
319
|
* @param options {object}
|
|
360
320
|
* @param options.store {EncryptionDescriptorStore} the roster's descriptor
|
|
@@ -364,19 +324,12 @@ export interface UserKeyRosterReadResult {
|
|
|
364
324
|
* (identity) key-agreement key, unwrapping a rotated epoch
|
|
365
325
|
* @param [options.pinnedEpochId] {string} the locally pinned latest-seen
|
|
366
326
|
* roster epoch, when this client has seen the roster before
|
|
367
|
-
* @param [options.document] {RosterRecipientDocument} the locally verified
|
|
368
|
-
* did:webvh document, when the caller already holds one
|
|
369
|
-
* @param [options.resolveDocument] {function} resolves the locally verified
|
|
370
|
-
* did:webvh document on demand; called only when the read takes the
|
|
371
|
-
* rotated/first-read path
|
|
372
327
|
* @returns {Promise<UserKeyRosterReadResult | null>}
|
|
373
328
|
*/
|
|
374
|
-
export declare function readUserKeyRoster({ store, userKey, clientKeyAgreementKey, pinnedEpochId
|
|
329
|
+
export declare function readUserKeyRoster({ store, userKey, clientKeyAgreementKey, pinnedEpochId }: {
|
|
375
330
|
store: EncryptionDescriptorStore;
|
|
376
331
|
userKey?: UserKey;
|
|
377
332
|
clientKeyAgreementKey: IKeyAgreementKey;
|
|
378
333
|
pinnedEpochId?: string | null;
|
|
379
|
-
document?: RosterRecipientDocument;
|
|
380
|
-
resolveDocument?: () => Promise<RosterRecipientDocument>;
|
|
381
334
|
}): Promise<UserKeyRosterReadResult | null>;
|
|
382
335
|
//# sourceMappingURL=userKeyRoster.d.ts.map
|