@serfab/cadre-core 1.13.0 → 1.14.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.
Files changed (120) hide show
  1. package/dist/cadre-invite-protocol.d.ts +348 -0
  2. package/dist/cadre-invite-protocol.js +605 -0
  3. package/dist/cadre-invite-protocol.js.map +1 -0
  4. package/dist/cadre-node.d.ts +523 -180
  5. package/dist/cadre-node.js +921 -293
  6. package/dist/cadre-node.js.map +1 -1
  7. package/dist/claim-proof.d.ts +45 -0
  8. package/dist/claim-proof.js +132 -0
  9. package/dist/claim-proof.js.map +1 -0
  10. package/dist/control-authorization.d.ts +80 -19
  11. package/dist/control-authorization.js +55 -13
  12. package/dist/control-authorization.js.map +1 -1
  13. package/dist/control-cohort.js +1 -1
  14. package/dist/control-cohort.js.map +1 -1
  15. package/dist/control-database.d.ts +514 -97
  16. package/dist/control-database.js +1033 -195
  17. package/dist/control-database.js.map +1 -1
  18. package/dist/control-protocol-guard.d.ts +142 -0
  19. package/dist/control-protocol-guard.js +293 -0
  20. package/dist/control-protocol-guard.js.map +1 -0
  21. package/dist/control-schema.d.ts +1 -1
  22. package/dist/control-schema.js +801 -1067
  23. package/dist/control-schema.js.map +1 -1
  24. package/dist/control-stream.d.ts +4 -0
  25. package/dist/control-stream.js +22 -7
  26. package/dist/control-stream.js.map +1 -1
  27. package/dist/delegate-admission.d.ts +1 -1
  28. package/dist/delegate-admission.js +1 -1
  29. package/dist/device-token.d.ts +11 -9
  30. package/dist/device-token.js +14 -12
  31. package/dist/device-token.js.map +1 -1
  32. package/dist/ed25519-key.d.ts +15 -0
  33. package/dist/ed25519-key.js +28 -1
  34. package/dist/ed25519-key.js.map +1 -1
  35. package/dist/index.d.ts +14 -9
  36. package/dist/index.js +27 -9
  37. package/dist/index.js.map +1 -1
  38. package/dist/link-budget.d.ts +16 -29
  39. package/dist/link-budget.js +16 -31
  40. package/dist/link-budget.js.map +1 -1
  41. package/dist/membership-connection-gater.d.ts +190 -151
  42. package/dist/membership-connection-gater.js +235 -173
  43. package/dist/membership-connection-gater.js.map +1 -1
  44. package/dist/node-claim-payload.d.ts +19 -0
  45. package/dist/node-claim-payload.js +120 -0
  46. package/dist/node-claim-payload.js.map +1 -0
  47. package/dist/owner-anchor-sync.d.ts +22 -0
  48. package/dist/owner-anchor-sync.js +143 -0
  49. package/dist/owner-anchor-sync.js.map +1 -0
  50. package/dist/peer-authorization.d.ts +113 -18
  51. package/dist/peer-authorization.js +225 -29
  52. package/dist/peer-authorization.js.map +1 -1
  53. package/dist/peer-dial.d.ts +19 -0
  54. package/dist/peer-dial.js +22 -1
  55. package/dist/peer-dial.js.map +1 -1
  56. package/dist/peer-join-backfill.d.ts +26 -2
  57. package/dist/peer-join-backfill.js +54 -12
  58. package/dist/peer-join-backfill.js.map +1 -1
  59. package/dist/peer-record.d.ts +13 -9
  60. package/dist/peer-record.js +16 -12
  61. package/dist/peer-record.js.map +1 -1
  62. package/dist/pending-join-runner.d.ts +66 -58
  63. package/dist/pending-join-runner.js +136 -145
  64. package/dist/pending-join-runner.js.map +1 -1
  65. package/dist/push-fanout.d.ts +8 -2
  66. package/dist/push-fanout.js +8 -2
  67. package/dist/push-fanout.js.map +1 -1
  68. package/dist/seed-bootstrap.d.ts +147 -122
  69. package/dist/seed-bootstrap.js +284 -269
  70. package/dist/seed-bootstrap.js.map +1 -1
  71. package/dist/seed-trust-policy.d.ts +98 -37
  72. package/dist/seed-trust-policy.js +188 -2
  73. package/dist/seed-trust-policy.js.map +1 -1
  74. package/dist/strand-addr-protocol.d.ts +24 -26
  75. package/dist/strand-addr-protocol.js +19 -26
  76. package/dist/strand-addr-protocol.js.map +1 -1
  77. package/dist/strand-formation-protocol.js +1 -1
  78. package/dist/strand-formation-protocol.js.map +1 -1
  79. package/dist/strand-revocation-enforcer.d.ts +11 -11
  80. package/dist/strand-revocation-enforcer.js +11 -11
  81. package/dist/strand-wake-protocol.d.ts +13 -16
  82. package/dist/strand-wake-protocol.js +13 -20
  83. package/dist/strand-wake-protocol.js.map +1 -1
  84. package/dist/trusted-owner-store.d.ts +35 -5
  85. package/dist/trusted-owner-store.js +50 -8
  86. package/dist/trusted-owner-store.js.map +1 -1
  87. package/dist/types.d.ts +302 -87
  88. package/dist/types.js.map +1 -1
  89. package/package.json +8 -7
  90. package/src/cadre-invite-protocol.ts +864 -0
  91. package/src/cadre-node.ts +9381 -8686
  92. package/src/claim-proof.ts +147 -0
  93. package/src/control-authorization.ts +203 -117
  94. package/src/control-cohort.ts +1 -1
  95. package/src/control-database.ts +1216 -218
  96. package/src/control-protocol-guard.ts +348 -0
  97. package/src/control-schema.ts +812 -1078
  98. package/src/control-stream.ts +26 -7
  99. package/src/delegate-admission.ts +1 -1
  100. package/src/device-token.ts +14 -10
  101. package/src/ed25519-key.ts +28 -1
  102. package/src/index.ts +84 -10
  103. package/src/link-budget.ts +16 -32
  104. package/src/membership-connection-gater.ts +637 -570
  105. package/src/node-claim-payload.ts +125 -0
  106. package/src/owner-anchor-sync.ts +171 -0
  107. package/src/peer-authorization.ts +258 -29
  108. package/src/peer-dial.ts +22 -1
  109. package/src/peer-join-backfill.ts +56 -11
  110. package/src/peer-record.ts +16 -11
  111. package/src/pending-join-runner.ts +729 -735
  112. package/src/push-fanout.ts +8 -2
  113. package/src/seed-bootstrap.ts +344 -321
  114. package/src/seed-trust-policy.ts +353 -140
  115. package/src/strand-addr-protocol.ts +26 -35
  116. package/src/strand-formation-protocol.ts +1 -1
  117. package/src/strand-revocation-enforcer.ts +11 -11
  118. package/src/strand-wake-protocol.ts +13 -23
  119. package/src/trusted-owner-store.ts +242 -171
  120. package/src/types.ts +2471 -2242
@@ -0,0 +1,293 @@
1
+ /**
2
+ * The per-stream protocol guard on the control node: ONE declaration of what a peer must be to
3
+ * open a stream on each protocol the control node serves ({@link controlProtocolClasses}), and
4
+ * ONE place that enforces it for every handler, whoever registered it — Sereus, Optimystic,
5
+ * FRET or libp2p ({@link installControlProtocolGuard}).
6
+ *
7
+ * It is the fail-closed layer behind the fail-open connection gate
8
+ * (`membership-connection-gater.ts`). That gate decides per CONNECTION and must admit strangers
9
+ * in several windows (an open formation invitation, a live cadre invitation, relay-only
10
+ * admission on a node running the relay server, a delegate grant); this guard is what keeps a
11
+ * stranger on such a connection to the protocols declared open to it. A handler therefore never
12
+ * checks membership itself, and a handler added later cannot open a hole by forgetting to: a
13
+ * protocol missing from the table is guarded as members-only (see "Unclassified protocols").
14
+ *
15
+ * ## The classes
16
+ *
17
+ * - `stranger-open` — seed delivery, strand formation, cadre-invitation redemption. Any peer;
18
+ * each handler makes its own trust decision in-protocol (a seed signature against the
19
+ * anchored trust policy, a formation token, an invitation's possession proof).
20
+ * - `transport` — libp2p plumbing (identify, ping, hole punching, AutoNAT, the circuit-relay
21
+ * stop and hop protocols, WebRTC signaling). Every connection runs these, the redeeming
22
+ * device's own included: refusing identify would make that device treat the member as
23
+ * off-network. What they expose is the node's listen and observed addresses, its protocol
24
+ * list (whose `/optimystic/control-<partyId>` prefix names the party id, which an invitation
25
+ * bundle already carries) and its public key. AutoNAT v1 (`@libp2p/autonat` 3.0.28) dials
26
+ * back only public addresses on the requester's own observed host, and refuses a request made
27
+ * on another peer's behalf, so it cannot be pointed at a third machine. Relay reservations
28
+ * are decided separately, at the connection gate's reservation hook.
29
+ * - `members` — wake and strand-addr. Authorized members by the voucher-anchored LIVE read
30
+ * (`CadreNode.isAuthorizedMember`), the check those handlers made themselves before this
31
+ * guard existed, so moving it here changes nobody's admission. That matters most for
32
+ * strand-addr's delegate grant, which hands out connection and relay admission. The live read
33
+ * also has no window during `start()` where it admits everyone, which the snapshot does.
34
+ * - `members-snapshot` — the four Optimystic control-database protocols and the five FRET
35
+ * protocols. Authorized members by the in-memory snapshot
36
+ * (`CadreNode.authorizeInboundControlStream`). These serve the reads a live membership check
37
+ * would itself make, so a live read from inside their guard would deadlock two machines into
38
+ * refusing each other; the snapshot is synchronous and reads nothing.
39
+ *
40
+ * ## Mechanism: the registrar's handler lookup
41
+ *
42
+ * libp2p dispatches every inbound stream through `components.registrar.getHandler(protocol)`
43
+ * (`libp2p/dist/src/connection.js`, `onIncomingStream`). The guard replaces `getHandler` on the
44
+ * control node's registrar instance with one that returns the registered record with its
45
+ * handler wrapped for the protocol's class. A handler registered at any time, before or after
46
+ * the guard, is therefore guarded at dispatch, with no sweep over registrations and no race
47
+ * against a late one (the seed listener, a replaced formation handler).
48
+ *
49
+ * The record's `options` object is passed through unchanged: libp2p also reads it through
50
+ * `getHandler` for stream limits (`findIncomingStreamLimit`, `findOutgoingStreamLimit`) and for
51
+ * `runOnLimitedConnection`.
52
+ *
53
+ * NOTE: a libp2p that stopped dispatching through `getHandler` would leave this guard installed
54
+ * and inert, and the class-completeness spec would still pass. Only the stranger probe in
55
+ * `control-stream-authz.integration.ts` (step 5) observes dispatch, so run it on every libp2p
56
+ * upgrade.
57
+ *
58
+ * libp2p's own stream middleware (`libp2p.use`) is NOT used. In libp2p 3.3.11 `onIncomingStream`
59
+ * pushes the handler call onto the very array `registrar.getMiddleware` returns, so every inbound
60
+ * stream appends another handler call to the stored chain and outbound streams then run those
61
+ * too (read from the source, not run). Revisit if a libp2p upgrade stops mutating that array.
62
+ *
63
+ * ## Denial
64
+ *
65
+ * A refused stream is aborted with {@link ControlStreamRefusedError} before its handler runs, so
66
+ * nothing is decoded and nothing goes on the wire: telling a stranger "you are not a member"
67
+ * would confirm membership state to it. The refusal is logged on this node with peer, protocol
68
+ * and reason. The live read fails closed: a false result, a throw and a read slower than
69
+ * {@link ControlProtocolGuardOptions.liveDecisionTimeoutMs} all refuse.
70
+ *
71
+ * ## Unclassified protocols
72
+ *
73
+ * A protocol missing from the table is guarded as `members-snapshot`, with one `console.warn` per
74
+ * protocol: it works for members and refuses strangers until someone classes it.
75
+ * `control-protocol-guard.spec.ts` starts a node with every conditional protocol on and fails
76
+ * when any protocol it serves is unclassified, so an upgrade that adds one fails CI.
77
+ */
78
+ import debug from 'debug';
79
+ import { SEED_PROTOCOL } from './seed-bootstrap.js';
80
+ import { FORMATION_PROTOCOL } from './strand-formation-protocol.js';
81
+ import { CADRE_INVITE_PROTOCOL } from './cadre-invite-protocol.js';
82
+ import { WAKE_PROTOCOL } from './strand-wake-protocol.js';
83
+ import { STRAND_ADDR_PROTOCOL } from './strand-addr-protocol.js';
84
+ import { withTimeout } from './control-stream.js';
85
+ const log = debug('sereus:cadre:control-protocol-guard');
86
+ /** The class a protocol missing from {@link controlProtocolClasses} is guarded as. */
87
+ export const UNCLASSIFIED_PROTOCOL_CLASS = 'members-snapshot';
88
+ /** Stable error code carried by {@link ControlStreamRefusedError}. */
89
+ export const CONTROL_STREAM_REFUSED_CODE = 'ERR_CONTROL_STREAM_REFUSED';
90
+ /**
91
+ * The reason a control-node stream was aborted by the guard, so this node's logs can tell a
92
+ * refusal from a transport fault. The remote only ever sees the stream reset.
93
+ */
94
+ export class ControlStreamRefusedError extends Error {
95
+ constructor(remotePeerId, protocol, reason) {
96
+ super(`control stream refused: peer=${remotePeerId} protocol=${protocol} reason=${reason}`);
97
+ this.code = CONTROL_STREAM_REFUSED_CODE;
98
+ this.name = 'ControlStreamRefusedError';
99
+ }
100
+ }
101
+ /**
102
+ * The control libp2p node's Optimystic network name. `db-p2p` namespaces the node's protocol ids
103
+ * as `/optimystic/<networkName>/...`, so this is the one binding every control-network derivation
104
+ * starts from: the node options, the block-transfer prefix the control backfill dials, and the
105
+ * class table below.
106
+ *
107
+ * NOTE: the party id goes in UNENCODED here, unlike in `controlStorageScope`. Safe today because a
108
+ * party id is locally configured rather than replicated in, and both ends of a connection derive
109
+ * this string identically: an odd party id yields an odd but consistent protocol id, not a
110
+ * mismatch or an escaped name. If a party id ever arrives from the network, encode it here as the
111
+ * storage scope key already does.
112
+ */
113
+ export function controlNetworkName(partyId) {
114
+ return `control-${partyId}`;
115
+ }
116
+ /**
117
+ * The class of every protocol a control node serves, by exact protocol id: the single
118
+ * declaration the guard enforces. See the module doc for what each class admits and why each
119
+ * protocol is in it.
120
+ */
121
+ export function controlProtocolClasses(partyId) {
122
+ const prefix = `/optimystic/${controlNetworkName(partyId)}`;
123
+ const fret = `${prefix}/fret/1.0.0`;
124
+ return new Map([
125
+ [SEED_PROTOCOL, 'stranger-open'],
126
+ [FORMATION_PROTOCOL, 'stranger-open'],
127
+ [CADRE_INVITE_PROTOCOL, 'stranger-open'],
128
+ [WAKE_PROTOCOL, 'members'],
129
+ [STRAND_ADDR_PROTOCOL, 'members'],
130
+ [`${prefix}/repo/1.0.0`, 'members-snapshot'],
131
+ [`${prefix}/cluster/1.0.0`, 'members-snapshot'],
132
+ [`${prefix}/db-p2p/sync/1.0.0`, 'members-snapshot'],
133
+ [`${prefix}/db-p2p/block-transfer/1.0.0`, 'members-snapshot'],
134
+ [`${fret}/neighbors`, 'members-snapshot'],
135
+ [`${fret}/neighbors/announce`, 'members-snapshot'],
136
+ [`${fret}/maybeAct`, 'members-snapshot'],
137
+ [`${fret}/leave`, 'members-snapshot'],
138
+ [`${fret}/ping`, 'members-snapshot'],
139
+ [`${prefix}/id/1.0.0`, 'transport'],
140
+ [`${prefix}/id/push/1.0.0`, 'transport'],
141
+ ['/ipfs/ping/1.0.0', 'transport'],
142
+ ['/libp2p/dcutr', 'transport'],
143
+ ['/libp2p/autonat/1.0.0', 'transport'],
144
+ ['/libp2p/circuit/relay/0.2.0/stop', 'transport'],
145
+ // Registered only while the relay server runs (the storage profile's default).
146
+ ['/libp2p/circuit/relay/0.2.0/hop', 'transport'],
147
+ // Registered only when an embedder's `network.transports` includes WebRTC.
148
+ ['/webrtc-signaling/0.0.1', 'transport'],
149
+ ]);
150
+ }
151
+ function isGuardableRegistrar(value) {
152
+ return typeof value === 'object' && value !== null
153
+ && typeof value.getHandler === 'function';
154
+ }
155
+ /**
156
+ * The control node's registrar, which is not on libp2p's public `Libp2p` type. Throws when the
157
+ * shape is absent (a libp2p upgrade that moved it), which fails `CadreNode.start()`: a control
158
+ * node without the guard must not run.
159
+ */
160
+ function controlRegistrar(node) {
161
+ let registrar;
162
+ try {
163
+ // libp2p's components object is a Proxy that throws for a component it does not hold.
164
+ registrar = node.components?.registrar;
165
+ }
166
+ catch (error) {
167
+ throw new Error('control-protocol guard: the control node exposes no registrar component; refusing to run unguarded', { cause: error });
168
+ }
169
+ if (!isGuardableRegistrar(registrar)) {
170
+ throw new Error('control-protocol guard: the control node\'s registrar has no getHandler; refusing to run unguarded');
171
+ }
172
+ return registrar;
173
+ }
174
+ /**
175
+ * Guard every inbound stream on `node` by its protocol's class (see the module doc). Call once,
176
+ * on the control node, before it holds any connection: `CadreNode.start()` calls it right after
177
+ * the node is built, inside the bring-up quiet period. Throws when the node's registrar is not
178
+ * the shape the guard replaces.
179
+ */
180
+ export function installControlProtocolGuard(node, options) {
181
+ const registrar = controlRegistrar(node);
182
+ const guard = new ControlProtocolGuard(options);
183
+ const lookup = registrar.getHandler.bind(registrar);
184
+ // An unregistered protocol still throws libp2p's own UnhandledProtocolError, from `lookup`.
185
+ registrar.getHandler = (protocol) => guard.recordFor(protocol, lookup(protocol));
186
+ log('Guarding the control node\'s inbound streams for party %s', options.partyId);
187
+ }
188
+ /** The per-node state behind {@link installControlProtocolGuard}. */
189
+ class ControlProtocolGuard {
190
+ constructor(options) {
191
+ this.options = options;
192
+ /**
193
+ * The guarded copy of each registered record, so the lookups libp2p makes per stream (the
194
+ * stream-limit read, then the dispatch) allocate nothing. Keyed on the registrar's own record,
195
+ * which a re-registration replaces, so a replaced handler gets a fresh wrapper.
196
+ */
197
+ this.guarded = new WeakMap();
198
+ this.warnedUnclassified = new Set();
199
+ this.classes = controlProtocolClasses(options.partyId);
200
+ }
201
+ recordFor(protocol, record) {
202
+ const protocolClass = this.classOf(protocol);
203
+ if (protocolClass === 'stranger-open' || protocolClass === 'transport') {
204
+ return record;
205
+ }
206
+ let guarded = this.guarded.get(record);
207
+ if (!guarded) {
208
+ guarded = { ...record, handler: this.wrap(protocol, protocolClass, record.handler) };
209
+ this.guarded.set(record, guarded);
210
+ }
211
+ return guarded;
212
+ }
213
+ classOf(protocol) {
214
+ const declared = this.classes.get(protocol);
215
+ if (declared) {
216
+ return declared;
217
+ }
218
+ if (!this.warnedUnclassified.has(protocol)) {
219
+ this.warnedUnclassified.add(protocol);
220
+ console.warn(`Control node serves ${protocol}, which has no class in controlProtocolClasses ` +
221
+ `(control-protocol-guard.ts); guarding it as ${UNCLASSIFIED_PROTOCOL_CLASS}, so strangers are refused on it. ` +
222
+ 'Declare its class.');
223
+ }
224
+ return UNCLASSIFIED_PROTOCOL_CLASS;
225
+ }
226
+ wrap(protocol, protocolClass, handler) {
227
+ if (protocolClass === 'members') {
228
+ // NOTE: the handler starts reading only once the live read settles, usually after the
229
+ // asker has half-closed, and a plain `for await` over a libp2p 3.3.11 stream never ends
230
+ // there (see `collect` in control-stream.ts). Wake and strand-addr read through
231
+ // `readStreamToEnd`, which handles it; a handler added to this class must too.
232
+ return async (stream, connection) => {
233
+ const remotePeerId = connection.remotePeer.toString();
234
+ const refusal = await this.liveRefusal(remotePeerId);
235
+ if (refusal !== undefined) {
236
+ refuse(stream, remotePeerId, protocol, refusal);
237
+ return;
238
+ }
239
+ await handler(stream, connection);
240
+ };
241
+ }
242
+ return (stream, connection) => {
243
+ const remotePeerId = connection.remotePeer.toString();
244
+ const refusal = this.snapshotRefusal(remotePeerId, protocol);
245
+ if (refusal !== undefined) {
246
+ refuse(stream, remotePeerId, protocol, refusal);
247
+ return;
248
+ }
249
+ return handler(stream, connection);
250
+ };
251
+ }
252
+ /**
253
+ * Why the live read refuses `remotePeerId`, or undefined when it admits.
254
+ *
255
+ * NOTE: a stranger's stream now costs one live membership read before it is refused, and the
256
+ * handlers' concurrency caps no longer bound those reads; libp2p's per-connection
257
+ * `maxInboundStreams` (32 per protocol) does. Fine while that read touches only held blocks.
258
+ * If refused strangers ever show up as load, refuse a peer absent from the snapshot before the
259
+ * live read.
260
+ */
261
+ async liveRefusal(remotePeerId) {
262
+ try {
263
+ const member = await withTimeout(this.options.liveDecisionTimeoutMs, `membership check for ${remotePeerId}`, () => this.options.isMemberLive(remotePeerId));
264
+ return member === true ? undefined : 'not an authorized member';
265
+ }
266
+ catch (error) {
267
+ return `membership check failed: ${error instanceof Error ? error.message : String(error)}`;
268
+ }
269
+ }
270
+ /** Why the snapshot refuses `remotePeerId` on `protocol`, or undefined when it admits. */
271
+ snapshotRefusal(remotePeerId, protocol) {
272
+ try {
273
+ return this.options.isMemberSnapshot(remotePeerId, protocol) === true
274
+ ? undefined
275
+ : 'not in the authorized-member snapshot';
276
+ }
277
+ catch (error) {
278
+ return `snapshot check threw: ${error instanceof Error ? error.message : String(error)}`;
279
+ }
280
+ }
281
+ }
282
+ /** Log a refusal and reset the stream before its handler runs. */
283
+ function refuse(stream, remotePeerId, protocol, reason) {
284
+ log('Refusing %s on %s: %s', remotePeerId, protocol, reason);
285
+ try {
286
+ stream.abort(new ControlStreamRefusedError(remotePeerId, protocol, reason));
287
+ }
288
+ catch (error) {
289
+ // The stream may already be gone; the refusal stands either way.
290
+ log('Aborting the refused stream from %s on %s failed: %o', remotePeerId, protocol, error);
291
+ }
292
+ }
293
+ //# sourceMappingURL=control-protocol-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-protocol-guard.js","sourceRoot":"","sources":["../src/control-protocol-guard.ts"],"names":[],"mappings":"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"}