@serfab/cadre-core 0.8.1 → 0.9.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 (93) hide show
  1. package/README.md +2 -2
  2. package/dist/cadre-node.d.ts +101 -61
  3. package/dist/cadre-node.js +165 -124
  4. package/dist/cadre-node.js.map +1 -1
  5. package/dist/control-cohort.d.ts +15 -15
  6. package/dist/control-cohort.js +14 -14
  7. package/dist/control-cohort.js.map +1 -1
  8. package/dist/control-database.d.ts +51 -34
  9. package/dist/control-database.js +72 -56
  10. package/dist/control-database.js.map +1 -1
  11. package/dist/control-formation-recorder.d.ts +2 -2
  12. package/dist/control-formation-recorder.js +2 -2
  13. package/dist/control-schema.d.ts +1 -1
  14. package/dist/control-schema.js +57 -33
  15. package/dist/control-schema.js.map +1 -1
  16. package/dist/device-token.d.ts +1 -1
  17. package/dist/device-token.js +1 -1
  18. package/dist/{authority-key.d.ts → ed25519-key.d.ts} +11 -10
  19. package/dist/{authority-key.js → ed25519-key.js} +9 -10
  20. package/dist/ed25519-key.js.map +1 -0
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +8 -8
  23. package/dist/index.js.map +1 -1
  24. package/dist/key-store.d.ts +1 -1
  25. package/dist/key-store.js +1 -1
  26. package/dist/peer-authorization.d.ts +28 -6
  27. package/dist/peer-authorization.js +33 -7
  28. package/dist/peer-authorization.js.map +1 -1
  29. package/dist/peer-record.d.ts +3 -3
  30. package/dist/peer-record.js +3 -3
  31. package/dist/push-node.d.ts +38 -0
  32. package/dist/push-node.js +48 -0
  33. package/dist/push-node.js.map +1 -0
  34. package/dist/push-notifier-apns.d.ts +10 -2
  35. package/dist/push-notifier-apns.js +14 -10
  36. package/dist/push-notifier-apns.js.map +1 -1
  37. package/dist/push-notifier-fcm.d.ts +7 -1
  38. package/dist/push-notifier-fcm.js +9 -10
  39. package/dist/push-notifier-fcm.js.map +1 -1
  40. package/dist/push-notifier.d.ts +16 -35
  41. package/dist/push-notifier.js +16 -44
  42. package/dist/push-notifier.js.map +1 -1
  43. package/dist/seed-bootstrap.d.ts +70 -51
  44. package/dist/seed-bootstrap.js +168 -106
  45. package/dist/seed-bootstrap.js.map +1 -1
  46. package/dist/seed-trust-policy.d.ts +11 -11
  47. package/dist/seed-trust-policy.js +11 -11
  48. package/dist/seed-trust-policy.js.map +1 -1
  49. package/dist/strand-database.d.ts +5 -5
  50. package/dist/strand-database.js +4 -4
  51. package/dist/strand-database.js.map +1 -1
  52. package/dist/strand-formation-protocol.d.ts +1 -1
  53. package/dist/strand-formation-protocol.js +1 -1
  54. package/dist/strand-instance-manager.d.ts +1 -1
  55. package/dist/strand-instance-manager.js +1 -1
  56. package/dist/strand-instance-manager.js.map +1 -1
  57. package/dist/strand-member-key.d.ts +6 -6
  58. package/dist/strand-member-key.js +6 -6
  59. package/dist/strand-member-key.js.map +1 -1
  60. package/dist/strand-member-registry.d.ts +7 -7
  61. package/dist/strand-member-registry.js +5 -5
  62. package/dist/strand-member-registry.js.map +1 -1
  63. package/dist/strand-membership-writer.d.ts +84 -84
  64. package/dist/strand-membership-writer.js +90 -90
  65. package/dist/strand-membership-writer.js.map +1 -1
  66. package/dist/types.d.ts +52 -32
  67. package/dist/types.js.map +1 -1
  68. package/package.json +7 -3
  69. package/src/cadre-node.ts +170 -126
  70. package/src/control-cohort.ts +17 -17
  71. package/src/control-database.ts +76 -59
  72. package/src/control-formation-recorder.ts +2 -2
  73. package/src/control-schema.ts +57 -33
  74. package/src/device-token.ts +1 -1
  75. package/src/{authority-key.ts → ed25519-key.ts} +12 -11
  76. package/src/index.ts +21 -19
  77. package/src/key-store.ts +1 -1
  78. package/src/peer-authorization.ts +35 -7
  79. package/src/peer-record.ts +3 -3
  80. package/src/push-node.ts +64 -0
  81. package/src/push-notifier-apns.ts +16 -12
  82. package/src/push-notifier-fcm.ts +9 -10
  83. package/src/push-notifier.ts +16 -57
  84. package/src/seed-bootstrap.ts +179 -115
  85. package/src/seed-trust-policy.ts +18 -18
  86. package/src/strand-database.ts +6 -6
  87. package/src/strand-formation-protocol.ts +1 -1
  88. package/src/strand-instance-manager.ts +2 -2
  89. package/src/strand-member-key.ts +7 -7
  90. package/src/strand-member-registry.ts +10 -10
  91. package/src/strand-membership-writer.ts +127 -127
  92. package/src/types.ts +52 -32
  93. package/dist/authority-key.js.map +0 -1
@@ -3,20 +3,20 @@
3
3
  *
4
4
  * A seed carries an ed25519 signature over its body and the `signerKey` that
5
5
  * produced it. Verifying that signature only proves the seed is internally
6
- * consistent — it does NOT prove the signer is an authority, because both the
7
- * signer key and the seed's own `isAuthority` peer flags are attacker-supplied.
6
+ * consistent — it does NOT prove the signer is an owner, because both the
7
+ * signer key and the seed's own `isOwner` peer flags are attacker-supplied.
8
8
  * The trust decision must therefore rest on an anchor that does not come from
9
9
  * the seed body:
10
10
  *
11
- * 1. DB-anchored — keys already in the receiver's `CadreControl.AuthorityKey`
11
+ * 1. DB-anchored — keys already in the receiver's `CadreControl.OwnerKey`
12
12
  * table (steady state: the node is enrolled / has synced control state).
13
13
  * 2. Pinned out-of-band — keys handed to the node from outside the seed
14
- * (carried by a `CadreInvite.authorityKeys`, or pinned by an operator).
14
+ * (carried by a `CadreInvite.ownerKeys`, or pinned by an operator).
15
15
  * 3. TOFU (opt-in) — an explicit confirmation callback invoked on first sight
16
16
  * of an unknown signer key. Interactive hosts only; off by default.
17
17
  *
18
18
  * Secure default (`dbAnchoredTrustPolicy`): a cold-start node with an empty
19
- * `AuthorityKey` table and no pinned keys rejects the seed — a seed can no
19
+ * `OwnerKey` table and no pinned keys rejects the seed — a seed can no
20
20
  * longer vouch for its own signer.
21
21
  */
22
22
  export interface SeedTrustContext {
@@ -25,10 +25,10 @@ export interface SeedTrustContext {
25
25
  /** ed25519 base64url signer key — already signature-verified by `applySeed`. */
26
26
  signerKey: string;
27
27
  /**
28
- * The receiver's known authority keys, sourced from its `AuthorityKey`
28
+ * The receiver's known owner keys, sourced from its `OwnerKey`
29
29
  * table — NOT from the seed. Empty for a cold-start node.
30
30
  */
31
- knownAuthorityKeys: ReadonlySet<string>;
31
+ knownOwnerKeys: ReadonlySet<string>;
32
32
  }
33
33
 
34
34
  export interface SeedTrustDecision {
@@ -48,45 +48,45 @@ export interface SeedTrustPolicy {
48
48
 
49
49
  /**
50
50
  * Default policy: trust only keys already present in the receiver's
51
- * `AuthorityKey` table. A cold-start node (empty table) rejects every seed.
51
+ * `OwnerKey` table. A cold-start node (empty table) rejects every seed.
52
52
  */
53
53
  export function dbAnchoredTrustPolicy(): SeedTrustPolicy {
54
54
  return {
55
- evaluate({ signerKey, knownAuthorityKeys }) {
56
- if (knownAuthorityKeys.has(signerKey)) {
55
+ evaluate({ signerKey, knownOwnerKeys }) {
56
+ if (knownOwnerKeys.has(signerKey)) {
57
57
  return { trusted: true };
58
58
  }
59
59
  return {
60
60
  trusted: false,
61
- reason: 'Signer key is not a known authority (DB-anchored trust policy)',
61
+ reason: 'Signer key is not a known owner (DB-anchored trust policy)',
62
62
  };
63
63
  },
64
64
  };
65
65
  }
66
66
 
67
67
  /**
68
- * Cold-start policy: trust keys in the receiver's `AuthorityKey` table plus a
69
- * set pinned out-of-band (typically `CadreInvite.authorityKeys` or operator
68
+ * Cold-start policy: trust keys in the receiver's `OwnerKey` table plus a
69
+ * set pinned out-of-band (typically `CadreInvite.ownerKeys` or operator
70
70
  * config). Lets an unenrolled invitee accept its first seed without the seed
71
71
  * vouching for itself.
72
72
  */
73
73
  export function pinnedKeyTrustPolicy(pinned: Iterable<string>): SeedTrustPolicy {
74
74
  const pinnedSet = new Set(pinned);
75
75
  return {
76
- evaluate({ signerKey, knownAuthorityKeys }) {
77
- if (knownAuthorityKeys.has(signerKey) || pinnedSet.has(signerKey)) {
76
+ evaluate({ signerKey, knownOwnerKeys }) {
77
+ if (knownOwnerKeys.has(signerKey) || pinnedSet.has(signerKey)) {
78
78
  return { trusted: true };
79
79
  }
80
80
  return {
81
81
  trusted: false,
82
- reason: 'Signer key is neither a known nor a pinned authority (pinned-key trust policy)',
82
+ reason: 'Signer key is neither a known nor a pinned owner (pinned-key trust policy)',
83
83
  };
84
84
  },
85
85
  };
86
86
  }
87
87
 
88
88
  /**
89
- * Opt-in interactive policy: trust keys already in the `AuthorityKey` table,
89
+ * Opt-in interactive policy: trust keys already in the `OwnerKey` table,
90
90
  * and on an unknown key invoke `confirm` (e.g. a trust-circle UI prompt). The
91
91
  * key is trusted iff `confirm` resolves true. Not enabled by default.
92
92
  */
@@ -95,7 +95,7 @@ export function tofuTrustPolicy(
95
95
  ): SeedTrustPolicy {
96
96
  return {
97
97
  async evaluate(ctx) {
98
- if (ctx.knownAuthorityKeys.has(ctx.signerKey)) {
98
+ if (ctx.knownOwnerKeys.has(ctx.signerKey)) {
99
99
  return { trusted: true };
100
100
  }
101
101
  const accepted = await confirm(ctx);
@@ -38,13 +38,13 @@ export interface StrandDatabaseConfig {
38
38
  /**
39
39
  * Strand type (`'o'` open / `'c'` closed) from the control-network strand row.
40
40
  * Drives the founder bootstrap: open strands get a `Header` only; closed strands
41
- * also get the founding `Member`+`Authority`.
41
+ * also get the founding `Member`+`Manager`.
42
42
  */
43
43
  strandType: 'o' | 'c';
44
44
  /**
45
45
  * The closed-strand `MemberPrivateKey` (base64 protobuf) from the strand row.
46
46
  * Required when `founder` is true and `strandType` is `'c'` — it derives the
47
- * founding `Member.Key`/`Authority.MemberKey`. Absent for open strands.
47
+ * founding `Member.Key`/`Manager.MemberKey`. Absent for open strands.
48
48
  */
49
49
  memberPrivateKey?: string;
50
50
  /**
@@ -136,8 +136,8 @@ export class StrandDatabase {
136
136
  * Run the founder membership bootstrap against the freshly-composed strand DB.
137
137
  *
138
138
  * Derives the founding keypair from the closed-strand `memberPrivateKey` (the
139
- * `Member.Key`/`Authority.MemberKey` are its public key); a closed strand with no
140
- * `memberPrivateKey` throws, because it could never seat a founding authority.
139
+ * `Member.Key`/`Manager.MemberKey` are its public key); a closed strand with no
140
+ * `memberPrivateKey` throws, because it could never seat a founding manager.
141
141
  * Open strands derive no keypair (Header only). Idempotent — see
142
142
  * {@link bootstrapFounderMembership}.
143
143
  */
@@ -157,13 +157,13 @@ export class StrandDatabase {
157
157
  /**
158
158
  * Derive the founding keypair for a closed strand from its `memberPrivateKey`,
159
159
  * failing loudly when the key is absent (a closed strand with no founding
160
- * Authority can never admit anyone).
160
+ * Manager can never admit anyone).
161
161
  */
162
162
  private deriveFounderKeyPair(strandId: string, memberPrivateKey: string | undefined) {
163
163
  if (!memberPrivateKey) {
164
164
  throw new Error(
165
165
  `Cannot found closed strand ${strandId}: the strand row has no MemberPrivateKey. ` +
166
- 'A closed strand needs a founding Member/Authority derived from that key.',
166
+ 'A closed strand needs a founding Member/Manager derived from that key.',
167
167
  );
168
168
  }
169
169
  return strandMemberKeyPair(memberPrivateKey);
@@ -174,7 +174,7 @@ const PLACEHOLDER_CADRE_ADDR = /^cadre-[ab]-\d+\.local$/;
174
174
  * placeholders), and returned a strand vouched for by the responder party with a real id.
175
175
  *
176
176
  * `createdBy: 'responder'` means "the responder party vouches for / returns this strand."
177
- * Under provision-then-record that strand was minted authority-signed earlier (not created
177
+ * Under provision-then-record that strand was minted owner-signed earlier (not created
178
178
  * in-session), but it is still the responder party returning its own strand, so the marker
179
179
  * — and this structural validator — stay unchanged.
180
180
  *
@@ -48,7 +48,7 @@ export interface StartStrandConfig {
48
48
  requireSignedSchemas?: boolean;
49
49
  /**
50
50
  * Whether this node founds the strand (vs. joins it). Forwarded to the
51
- * StrandDatabase so the founder bootstrap (Header, founding Member/Authority)
51
+ * StrandDatabase so the founder bootstrap (Header, founding Member/Manager)
52
52
  * runs once at bring-up. Joiners leave this unset and write nothing. See
53
53
  * {@link StrandConfig.founder}.
54
54
  */
@@ -292,7 +292,7 @@ export class StrandInstanceManager {
292
292
  rawStorage: strandStorage,
293
293
  // Founder bootstrap inputs: the strand's type drives which membership rows
294
294
  // are written, and the closed-strand MemberPrivateKey derives the founding
295
- // Member/Authority key. Both come off the control-network strand row.
295
+ // Member/Manager key. Both come off the control-network strand row.
296
296
  strandType: config.strandRow.Type,
297
297
  memberPrivateKey: config.strandRow.MemberPrivateKey ?? undefined,
298
298
  founder: config.founder
@@ -1,6 +1,6 @@
1
1
  import { generateKeyPair, privateKeyToProtobuf, privateKeyFromProtobuf } from '@libp2p/crypto/keys';
2
2
  import { toString as uint8ArrayToString, fromString as uint8ArrayFromString } from 'uint8arrays';
3
- import { authorityKeyFromLibp2p, type AuthorityKeyPair } from './authority-key.js';
3
+ import { ed25519KeyPairFromLibp2p, type Ed25519KeyPair } from './ed25519-key.js';
4
4
 
5
5
  /**
6
6
  * Mint a fresh ed25519 strand member private key, encoded as base64 protobuf.
@@ -22,18 +22,18 @@ export async function generateStrandMemberKey(): Promise<string> {
22
22
  * base64url keypair the strand RBAC constraints consume.
23
23
  *
24
24
  * The `Strand` control-layer `MemberPrivateKey` is the closed-strand read-gating
25
- * secret; the founding `Member.Key`/`Authority.MemberKey` (the strand RBAC layer)
25
+ * secret; the founding `Member.Key`/`Manager.MemberKey` (the strand RBAC layer)
26
26
  * are *derived from it* — they are the `publicKeyB64` of the keypair this returns.
27
27
  * Decode the protobuf to a libp2p private key, then reuse
28
- * {@link authorityKeyFromLibp2p} so the same seed→public derivation used for node
29
- * authority keys yields a stable `{ privateKeyB64, publicKeyB64 }` whose public
28
+ * {@link ed25519KeyPairFromLibp2p} so the same seed→public derivation used for node
29
+ * owner keys yields a stable `{ privateKeyB64, publicKeyB64 }` whose public
30
30
  * key a later strand signature verifies against.
31
31
  *
32
32
  * @param memberPrivateKey - The strand's `MemberPrivateKey` (base64 protobuf).
33
- * @returns The base64url seed/public-key pair for founding membership/authority.
33
+ * @returns The base64url seed/public-key pair for founding membership/manager.
34
34
  * @throws If the decoded key is not Ed25519 or the raw bytes are malformed.
35
35
  */
36
- export function strandMemberKeyPair(memberPrivateKey: string): AuthorityKeyPair {
36
+ export function strandMemberKeyPair(memberPrivateKey: string): Ed25519KeyPair {
37
37
  const privateKey = privateKeyFromProtobuf(uint8ArrayFromString(memberPrivateKey, 'base64'));
38
- return authorityKeyFromLibp2p(privateKey);
38
+ return ed25519KeyPairFromLibp2p(privateKey);
39
39
  }
@@ -2,11 +2,11 @@ import debug from 'debug';
2
2
  import type { Database, SqlValue } from '@quereus/quereus';
3
3
  import type { MemberRegistration } from './types.js';
4
4
  import type { MemberRegistry, MemberVerifier } from './enrollment.js';
5
- import type { AuthorityKeyPair } from './authority-key.js';
5
+ import type { Ed25519KeyPair } from './ed25519-key.js';
6
6
  import {
7
7
  verifyStrandPayload,
8
8
  consumeInvite,
9
- addMemberByAuthority,
9
+ addMemberByManager,
10
10
  } from './strand-membership-writer.js';
11
11
  import { canonicalDatetime } from './canonical-datetime.js';
12
12
 
@@ -37,10 +37,10 @@ export type StrandAdmission =
37
37
  readonly invitePrivateKey: string;
38
38
  }
39
39
  | {
40
- /** Admit directly by authority signature (the authority-side join). */
41
- readonly mode: 'authority';
42
- /** The admitting authority's strand keypair. */
43
- readonly authorityKeyPair: AuthorityKeyPair;
40
+ /** Admit directly by manager signature (the manager-side join). */
41
+ readonly mode: 'manager';
42
+ /** The admitting manager's strand keypair. */
43
+ readonly managerKeyPair: Ed25519KeyPair;
44
44
  };
45
45
 
46
46
  /**
@@ -115,8 +115,8 @@ export class StrandMemberVerifier implements MemberVerifier {
115
115
  * `Member.Authorized` is taken:
116
116
  * - `invite` → {@link consumeInvite} (atomic `Member` + `ConsumedInvite`), the
117
117
  * invitee-side flow that redeems a single-use invite.
118
- * - `authority` → {@link addMemberByAuthority}, the authority-side flow that
119
- * seats a member already trusted by an authority.
118
+ * - `manager` → {@link addMemberByManager}, the manager-side flow that
119
+ * seats a member already trusted by a manager.
120
120
  *
121
121
  * Scoped to one strand's db; the `strandId` argument is accepted for interface
122
122
  * compatibility but writes target this db's `Strand.*` tables.
@@ -152,8 +152,8 @@ export class StrandMemberRegistry implements MemberRegistry {
152
152
  return;
153
153
  }
154
154
 
155
- await addMemberByAuthority(this.db, {
156
- authorityKeyPair: this.admission.authorityKeyPair,
155
+ await addMemberByManager(this.db, {
156
+ managerKeyPair: this.admission.managerKeyPair,
157
157
  memberKey,
158
158
  });
159
159
  }