@ibgib/core-gib 0.1.60 → 0.1.62

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 (181) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/common/other/graph-helper.d.mts.map +1 -1
  3. package/dist/common/other/graph-helper.mjs +7 -6
  4. package/dist/common/other/graph-helper.mjs.map +1 -1
  5. package/dist/keystone/keystone-config-builder.d.mts +1 -2
  6. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  7. package/dist/keystone/keystone-config-builder.mjs +4 -19
  8. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  9. package/dist/keystone/keystone-constants.d.mts +2 -1
  10. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  11. package/dist/keystone/keystone-constants.mjs +2 -1
  12. package/dist/keystone/keystone-constants.mjs.map +1 -1
  13. package/dist/keystone/keystone-helpers.d.mts +28 -16
  14. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  15. package/dist/keystone/keystone-helpers.mjs +155 -76
  16. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  17. package/dist/keystone/keystone-policy-types.d.mts +6 -4
  18. package/dist/keystone/keystone-policy-types.d.mts.map +1 -1
  19. package/dist/keystone/keystone-service-v1.d.mts +38 -2
  20. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  21. package/dist/keystone/keystone-service-v1.mjs +177 -11
  22. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  23. package/dist/keystone/keystone-service-v1.respec.mjs +527 -41
  24. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  25. package/dist/keystone/keystone-types.d.mts +53 -11
  26. package/dist/keystone/keystone-types.d.mts.map +1 -1
  27. package/dist/keystone/policy/keystone-profile-builder.d.mts +25 -0
  28. package/dist/keystone/policy/keystone-profile-builder.d.mts.map +1 -0
  29. package/dist/keystone/policy/keystone-profile-builder.mjs +117 -0
  30. package/dist/keystone/policy/keystone-profile-builder.mjs.map +1 -0
  31. package/dist/keystone/policy/profiles/profile-high.json +84 -0
  32. package/dist/keystone/policy/profiles/profile-low.json +84 -0
  33. package/dist/keystone/policy/profiles/profile-medium.json +84 -0
  34. package/dist/keystone/policy/profiles/profile-session.json +84 -0
  35. package/dist/keystone/policy/profiles/profile-test.json +84 -0
  36. package/dist/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  37. package/dist/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  38. package/dist/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  39. package/dist/keystone/policy/schemas/keystone.high.schema.json +26 -0
  40. package/dist/keystone/policy/schemas/keystone.low.schema.json +26 -0
  41. package/dist/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  42. package/dist/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  43. package/dist/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  44. package/dist/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  45. package/dist/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  46. package/dist/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  47. package/dist/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  48. package/dist/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  49. package/dist/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  50. package/dist/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  51. package/dist/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  52. package/dist/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  53. package/dist/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  54. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts +8 -0
  55. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts.map +1 -0
  56. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs +582 -0
  57. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs.map +1 -0
  58. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts +7 -0
  59. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts.map +1 -0
  60. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs +274 -0
  61. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs.map +1 -0
  62. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts +8 -0
  63. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts.map +1 -0
  64. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs +322 -0
  65. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs.map +1 -0
  66. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts +7 -0
  67. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts.map +1 -0
  68. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs +307 -0
  69. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs.map +1 -0
  70. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts +8 -0
  71. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts.map +1 -0
  72. package/dist/sync/sync-innerspace-constants.withid.respec.mjs +233 -0
  73. package/dist/sync/sync-innerspace-constants.withid.respec.mjs.map +1 -0
  74. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts +7 -0
  75. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts.map +1 -0
  76. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs +233 -0
  77. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs.map +1 -0
  78. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts +7 -0
  79. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts.map +1 -0
  80. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs +225 -0
  81. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs.map +1 -0
  82. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  83. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts +7 -0
  84. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts.map +1 -0
  85. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs +235 -0
  86. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs.map +1 -0
  87. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts +7 -0
  88. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts.map +1 -0
  89. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs +211 -0
  90. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs.map +1 -0
  91. package/dist/sync/sync-innerspace.withid.respec.d.mts +8 -0
  92. package/dist/sync/sync-innerspace.withid.respec.d.mts.map +1 -0
  93. package/dist/sync/sync-innerspace.withid.respec.mjs +260 -0
  94. package/dist/sync/sync-innerspace.withid.respec.mjs.map +1 -0
  95. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +1 -0
  96. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -1
  97. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +13 -4
  98. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -1
  99. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +1 -1
  100. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -1
  101. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +5 -3
  102. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -1
  103. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  104. package/dist/sync/sync-saga-coordinator.mjs +165 -145
  105. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  106. package/dist/sync/sync-withid.pingpong.respec.mjs +8 -8
  107. package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -1
  108. package/dist/timeline/timeline-api.d.mts.map +1 -1
  109. package/dist/timeline/timeline-api.mjs +1 -14
  110. package/dist/timeline/timeline-api.mjs.map +1 -1
  111. package/dist/witness/space/reconciliation-space/reconciliation-space-base.d.mts.map +1 -1
  112. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs +0 -40
  113. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
  114. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.d.mts.map +1 -1
  115. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs +6 -6
  116. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
  117. package/ibgib-foundations.md +2 -1
  118. package/package.json +1 -1
  119. package/src/common/other/graph-helper.mts +7 -6
  120. package/src/keystone/README.md +34 -17
  121. package/src/keystone/docs/CRYPTANALYSIS.md +185 -0
  122. package/src/keystone/docs/architecture.md +45 -3
  123. package/src/keystone/docs/delegation.md +57 -0
  124. package/src/keystone/docs/profiles.md +124 -0
  125. package/src/keystone/keystone-config-builder.mts +3 -21
  126. package/src/keystone/keystone-constants.mts +2 -1
  127. package/src/keystone/keystone-helpers.mts +204 -81
  128. package/src/keystone/keystone-policy-types.mts +6 -4
  129. package/src/keystone/keystone-service-v1.mts +223 -11
  130. package/src/keystone/keystone-service-v1.respec.mts +596 -39
  131. package/src/keystone/keystone-types.mts +55 -9
  132. package/src/keystone/policy/IMPLEMENTATION.md +60 -0
  133. package/src/keystone/policy/README.md +94 -0
  134. package/src/keystone/policy/keystone-profile-builder.mts +131 -0
  135. package/src/keystone/policy/profiles/profile-high.json +84 -0
  136. package/src/keystone/policy/profiles/profile-low.json +84 -0
  137. package/src/keystone/policy/profiles/profile-medium.json +84 -0
  138. package/src/keystone/policy/profiles/profile-session.json +84 -0
  139. package/src/keystone/policy/profiles/profile-test.json +84 -0
  140. package/src/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  141. package/src/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  142. package/src/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  143. package/src/keystone/policy/schemas/keystone.high.schema.json +26 -0
  144. package/src/keystone/policy/schemas/keystone.low.schema.json +26 -0
  145. package/src/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  146. package/src/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  147. package/src/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  148. package/src/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  149. package/src/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  150. package/src/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  151. package/src/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  152. package/src/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  153. package/src/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  154. package/src/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  155. package/src/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  156. package/src/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  157. package/src/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  158. package/src/sync/docs/security.md +54 -21
  159. package/src/sync/sync-conflict-adv-multitimelines.withid.respec.mts +706 -0
  160. package/src/sync/sync-conflict-basic-divergence.withid.respec.mts +321 -0
  161. package/src/sync/sync-conflict-basic-multitimelines.withid.respec.mts +374 -0
  162. package/src/sync/sync-conflict-text-merge.withid.respec.mts +347 -0
  163. package/src/sync/sync-innerspace-constants.withid.respec.mts +264 -0
  164. package/src/sync/sync-innerspace-deep-updates.withid.respec.mts +272 -0
  165. package/src/sync/sync-innerspace-dest-ahead.withid.respec.mts +266 -0
  166. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +0 -1
  167. package/src/sync/sync-innerspace-multiple-timelines.withid.respec.mts +273 -0
  168. package/src/sync/sync-innerspace-partial-update.withid.respec.mts +249 -0
  169. package/src/sync/sync-innerspace.withid.respec.mts +265 -0
  170. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +12 -4
  171. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +5 -3
  172. package/src/sync/sync-saga-coordinator.mts +159 -143
  173. package/src/sync/sync-withid.pingpong.respec.mts +8 -8
  174. package/src/timeline/timeline-api.mts +1 -15
  175. package/src/timeline/timeline-api.respec.mts +3 -3
  176. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts +0 -46
  177. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts +6 -5
  178. package/tsconfig.json +6 -1
  179. package/src/keystone/keystone-policy.schema.json +0 -51
  180. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts.OLD.md +0 -884
  181. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts.OLD.md +0 -125
@@ -111,10 +111,12 @@ export interface KeystonePoolBehavior {
111
111
  selectRandomly: number;
112
112
 
113
113
  /**
114
- * Number of hex characters from the Target's Gib to match.
114
+ * Number of challenges to draw deterministically from the pool using
115
+ * next-gen hash-based index selection (drawing without replacement)
116
+ * bound to the full target address (`ib` + `gib`).
115
117
  * @default 0
116
118
  */
117
- targetBindingChars: number;
119
+ targetBindingCount: number;
118
120
  }
119
121
 
120
122
  export interface KeystonePoolConfigBase {
@@ -227,13 +229,7 @@ export interface KeystoneChallengePool {
227
229
  */
228
230
  challenges: { [challengeId: string]: KeystoneChallenge };
229
231
 
230
- /**
231
- * Explicit Buckets for Target Binding.
232
- * Key: Hex Character ('0'-'f').
233
- * Value: Array of Challenge IDs that satisfy this bucket.
234
- * Note: A single ID may appear in multiple buckets (Coverage Strategy).
235
- */
236
- bindingMap: { [hexChar: string]: string[] };
232
+
237
233
 
238
234
  /**
239
235
  * If true, this pool's secrets are NOT derived from the Keystone's
@@ -318,6 +314,50 @@ export interface KeystoneRevocationInfo {
318
314
  proof: KeystoneProof;
319
315
  }
320
316
 
317
+ /**
318
+ * Shape of info we collect about delegated keystones. We can check
319
+ * against this info later when validating any identity delegation requests.
320
+ */
321
+ export interface DelegateKeystoneInfo {
322
+ /**
323
+ * The Timeline Junction Point (TJP) address of the delegate keystone.
324
+ * Serves as its immutable, unique identifier.
325
+ */
326
+ delegateTjpAddr: IbGibAddr;
327
+ /**
328
+ * concrete addr of **DELEGATE** keystone **at the time when the
329
+ * delegate was added.**
330
+ *
331
+ * So if we have a delegate keystone at D3, then this value would be the
332
+ * addr of that D3 keystone. This will have both a `punctiliarHash` and a
333
+ * `tjpGib` in its `GibInfo`.
334
+ */
335
+ delegateAddr: IbGibAddr;
336
+ /**
337
+ * concrete keystone addr of **THIS** parent keystone **at the time
338
+ * when the delegate was added.**
339
+ *
340
+ * So if we have a delegate keystone at D3, then this value would be the
341
+ * addr of that D3 keystone. This will have both a `punctiliarHash` and a
342
+ * `tjpGib` in its `GibInfo`.
343
+ */
344
+ thisAddr: IbGibAddr;
345
+ }
346
+
347
+ /**
348
+ * Status response when checking if a delegate keystone is registered.
349
+ */
350
+ export interface DelegateKeystoneStatus {
351
+ /**
352
+ * True if the delegate is currently registered on the parent.
353
+ */
354
+ registered: boolean;
355
+ /**
356
+ * Truthy only if registered is true.
357
+ */
358
+ delegateInfo?: DelegateKeystoneInfo;
359
+ }
360
+
321
361
  // ===========================================================================
322
362
  // TOP LEVEL IBGIB DATA
323
363
  // ===========================================================================
@@ -355,6 +395,12 @@ export interface KeystoneData_V1 extends IbGibData_V1 {
355
395
  * Acts as a snapshot to avoid walking the entire timeline.
356
396
  */
357
397
  checkpointDetails?: any;
398
+
399
+ /**
400
+ * Map of delegated keystones soft-linked to this parent keystone.
401
+ * Keyed by the delegate keystone's tjp address.
402
+ */
403
+ delegates?: { [delegateTjpAddr: IbGibAddr]: DelegateKeystoneInfo };
358
404
  }
359
405
 
360
406
  export interface KeystoneRel8ns_V1 extends IbGibRel8ns_V1 {
@@ -0,0 +1,60 @@
1
+ # Implementation Plan: Modular Policy Schemas & Keystone Profile Builder
2
+
3
+ This document outlines the step-by-step development tasks to transition the Keystone policy engine to a modular JSON-schema composed architecture with a fluent builder.
4
+
5
+ Parent Architecture Doc: [ARCHITECTURE.md](../../../../../docs/identity/ARCHITECTURE.md)
6
+
7
+ ---
8
+
9
+ ## 📋 Task Checklist
10
+
11
+ - [x] **1. Modular JSON Schema & Profiles Definitions**
12
+ - [x] Create schemas: `sync-pool.schema.json`, `manage-pool.schema.json`, `revoke-pool.schema.json`, `connect-pool.schema.json`, `sign-pool.schema.json` under `libs/core-gib/src/keystone/policy/schemas/`.
13
+ - [x] Define composite schemas `keystone.high.schema.json`, `keystone.medium.schema.json`, `keystone.low.schema.json`.
14
+ - [x] Migrate JSON profile files to use new schema locations.
15
+
16
+ - [x] **2. Type System Refactoring**
17
+ - [x] Update [keystone-policy-types.mts](../keystone-policy-types.mts) to support composite profiles and new metadata schemas.
18
+
19
+ - [x] **3. Implement `KeystoneProfileBuilder`**
20
+ - [x] Create `keystone-profile-builder.mts` inside `libs/core-gib/src/keystone/policy/`.
21
+ - [x] Implement `buildKeystone`, `withUsername`, `withEmail`, `withDescription`, `withDetails`.
22
+ - [x] Implement `customizePool` and `compileConfigs` with unique salt derivation and `frameDetails` unification.
23
+
24
+ - [x] **4. Build Pipeline Integration**
25
+ - [x] Update `build-core-gib.mts` to copy new schema/profile directories to `dist`.
26
+
27
+ - [x] **5. Downstream Consumption Refactoring**
28
+ - [x] Refactor space-gib's `keystone-creator.mts` to use the new builder.
29
+
30
+ - [x] **6. Automated Verification**
31
+ - [x] Add integration tests in `keystone-service-v1.respec.mts` ensuring the builder and modular schemas are correctly parsed, validated, and applied.
32
+
33
+ - [x] **7. Documentation & Architecture Sync**
34
+ - [x] Update [ARCHITECTURE.md](../../../../../docs/identity/ARCHITECTURE.md) with corrected code snippets (including fluent builder code samples) and clickable links to the actual code files (like schemas and builder implementation) for reference.
35
+
36
+ ---
37
+
38
+ ## 🛠️ Build & Verification Guide
39
+
40
+ Use the following commands from the monorepo root to build and verify your changes:
41
+
42
+ ### 1. Build core-gib
43
+ Check if core-gib compiles clean:
44
+ ```powershell
45
+ npm run build:core-gib
46
+ ```
47
+
48
+ ### 2. Monorepo Chain Build
49
+ Build all libraries and compile the downstream `space-gib` application to test integration:
50
+ ```powershell
51
+ npm run chain:build:core-gib
52
+ ```
53
+
54
+ ### 3. Run Space-Gib Client
55
+ To manually test the Keystone creation process via the space-gib UI, run:
56
+ ```powershell
57
+ npm run dev:space-gib
58
+ ```
59
+
60
+
@@ -0,0 +1,94 @@
1
+ # Keystone Identity Policies & Fluent Builder
2
+
3
+ This module manages Keystone Identity Policies, including security preset profiles (`high`, `medium`, `low`), modular schema composition, and the fluent configuration builder.
4
+
5
+ ---
6
+
7
+ ## 📖 Documentation Index
8
+
9
+ * **[Policy Architecture](../../../../../docs/identity/ARCHITECTURE.md)**: Conceptual design of separate pool behaviors, verbs, and composed schemas.
10
+ * **[Implementation Roadmap](./IMPLEMENTATION.md)**: Current development checklist and tasks.
11
+
12
+ ---
13
+
14
+ ## 🛠️ Usage: Fluent Builder API
15
+
16
+ The `KeystoneProfileBuilder` provides a fluid interface to construct, enrich, and customize Keystone configurations before genesis.
17
+
18
+ ### Basic Identity Creation
19
+
20
+ ```typescript
21
+ import { KeystoneProfileBuilder } from "@ibgib/core-gib/dist/keystone/policy/keystone-profile-builder.mjs";
22
+
23
+ // Build a medium-security identity config salted for a specific user
24
+ const configs = KeystoneProfileBuilder
25
+ .buildKeystone('medium')
26
+ .withUsername('alice')
27
+ .withEmail('alice@example.com')
28
+ .withDescription('Main user identity for Space-Gib')
29
+ .compileConfigs();
30
+
31
+ // Pass these configurations directly to genesis
32
+ const identity = await keystoneService.genesis({
33
+ masterSecret,
34
+ configs,
35
+ metaspace,
36
+ space
37
+ });
38
+ ```
39
+
40
+ ### Unifying Identity Details
41
+
42
+ The metadata provided to `withUsername`, `withEmail`, `withDescription`, and `withDetails` are automatically consolidated into the unified `frameDetails` field of the genesis frame:
43
+
44
+ ```typescript
45
+ const configs = KeystoneProfileBuilder
46
+ .buildKeystone('low')
47
+ .withUsername('bob')
48
+ .withDetails({
49
+ device: 'Pixel 8 Pro',
50
+ os: 'Android 14'
51
+ })
52
+ .compileConfigs();
53
+ ```
54
+
55
+ ### Runtime Customizations
56
+
57
+ If an application needs to customize a specific pool's parameters dynamically (for example, raising KDF hash rounds on the sync pool for higher-security environments), use `customizePool`:
58
+
59
+ ```typescript
60
+ const configs = KeystoneProfileBuilder
61
+ .buildKeystone('medium')
62
+ .withUsername('charlie')
63
+ .customizePool('sync', {
64
+ rounds: 5, // Override base medium profile rounds
65
+ })
66
+ .compileConfigs();
67
+ ```
68
+
69
+ ---
70
+
71
+ ## ⚠️ TypeScript & JSON Config Integration
72
+
73
+ If downstream projects import or load their own JSON configurations (e.g., custom `.json` files representing schemas or behavior configurations) rather than relying solely on the built-in profiles, TypeScript requires explicit path tracking in projects using `"composite": true`.
74
+
75
+ To prevent compiler errors like `TS6307: File '...' is not listed within the file list...`, ensure your project's `tsconfig.json` contains:
76
+
77
+ 1. `"resolveJsonModule": true` under `compilerOptions` to allow static importing of JSON files as ES modules.
78
+ 2. The folder/wildcard path of the JSON files added to the `"include"` array. For example:
79
+
80
+ ```json
81
+ {
82
+ "compilerOptions": {
83
+ "composite": true,
84
+ "resolveJsonModule": true,
85
+ "module": "ESNext"
86
+ },
87
+ "include": [
88
+ "src/**/*.ts",
89
+ "src/**/*.mts",
90
+ "src/custom-policies/*.json"
91
+ ]
92
+ }
93
+ ```
94
+
@@ -0,0 +1,131 @@
1
+ import { hash } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
2
+ import { KeystonePoolConfig } from "../keystone-types.mjs";
3
+ import { KeystonePoolTemplate, KeystonePolicyConfigTemplate, KeystoneBehaviorProfileTemplate } from "../keystone-policy-types.mjs";
4
+ import { createPoolConfigFromJson } from "../keystone-config-builder.mjs";
5
+
6
+ import profileHigh from "./profiles/profile-high.json" assert { type: "json" };
7
+ import profileMedium from "./profiles/profile-medium.json" assert { type: "json" };
8
+ import profileLow from "./profiles/profile-low.json" assert { type: "json" };
9
+ import profileSession from "./profiles/profile-session.json" assert { type: "json" };
10
+ import profileTest from "./profiles/profile-test.json" assert { type: "json" };
11
+
12
+ export class KeystoneProfileBuilder {
13
+ private _template: KeystonePolicyConfigTemplate;
14
+ private _username?: string;
15
+ private _email?: string;
16
+ private _description?: string;
17
+ private _details?: any;
18
+ private _customizations: { [poolId: string]: { template?: Partial<KeystonePoolTemplate>, behavior?: Partial<KeystoneBehaviorProfileTemplate> } } = {};
19
+
20
+ private constructor(template: KeystonePolicyConfigTemplate) {
21
+ // Deep copy the template to avoid modifying shared imports
22
+ this._template = JSON.parse(JSON.stringify(template));
23
+ }
24
+
25
+ static buildKeystone(profileName: 'high' | 'medium' | 'low' | 'session' | 'test'): KeystoneProfileBuilder {
26
+ let selected: KeystonePolicyConfigTemplate;
27
+ switch (profileName) {
28
+ case 'high':
29
+ selected = profileHigh as any;
30
+ break;
31
+ case 'medium':
32
+ selected = profileMedium as any;
33
+ break;
34
+ case 'low':
35
+ selected = profileLow as any;
36
+ break;
37
+ case 'session':
38
+ selected = profileSession as any;
39
+ break;
40
+ case 'test':
41
+ selected = profileTest as any;
42
+ break;
43
+ default:
44
+ throw new Error(`Unknown profile name: ${profileName} (E: fc10a8ad482ef2bda871ac567d268d26)`);
45
+ }
46
+ return new KeystoneProfileBuilder(selected);
47
+ }
48
+
49
+ withUsername(username: string): this {
50
+ this._username = username;
51
+ return this;
52
+ }
53
+
54
+ withEmail(email: string): this {
55
+ this._email = email;
56
+ return this;
57
+ }
58
+
59
+ withDescription(description: string): this {
60
+ this._description = description;
61
+ return this;
62
+ }
63
+
64
+ withDetails(details: any): this {
65
+ this._details = details;
66
+ return this;
67
+ }
68
+
69
+ customizePool(
70
+ poolId: string,
71
+ overrides: Omit<Partial<KeystonePoolTemplate>, 'behavior'> & { behavior?: Partial<KeystoneBehaviorProfileTemplate> }
72
+ ): this {
73
+ const { behavior, ...templateOverrides } = overrides;
74
+ this._customizations[poolId] = {
75
+ template: templateOverrides as any,
76
+ behavior
77
+ };
78
+ return this;
79
+ }
80
+
81
+ /**
82
+ * Unifies username, email, description, and details into a frameDetails object for genesis.
83
+ */
84
+ getFrameDetails(): any {
85
+ const details: any = { ...this._details };
86
+ if (this._username) { details.username = this._username; }
87
+ if (this._email) { details.email = this._email; }
88
+ if (this._description) { details.description = this._description; }
89
+ return details;
90
+ }
91
+
92
+ async compileConfigs(): Promise<KeystonePoolConfig[]> {
93
+ const poolConfigs: KeystonePoolConfig[] = [];
94
+
95
+ // Derive a unique user-specific base salt if username/email is provided
96
+ let userSalt = "";
97
+ if (this._username || this._email) {
98
+ const seed = `${this._username || ""}:${this._email || ""}`;
99
+ userSalt = await hash({ s: seed });
100
+ } else {
101
+ // Fallback salt to guarantee unique challenge IDs even without user details
102
+ userSalt = await hash({ s: "default-keystone-salt" });
103
+ }
104
+
105
+ for (const [poolKey, poolTemplate] of Object.entries(this._template.pools)) {
106
+ // Apply customization overrides
107
+ const custom = this._customizations[poolTemplate.id];
108
+ if (custom) {
109
+ if (custom.template) {
110
+ Object.assign(poolTemplate, custom.template);
111
+ }
112
+ if (custom.behavior && poolTemplate.behavior) {
113
+ Object.assign(poolTemplate.behavior, custom.behavior);
114
+ }
115
+ }
116
+
117
+ // Derive a unique salt for this specific pool by hashing userSalt + poolId
118
+ const saltSeed = `${userSalt}-${poolTemplate.id}`;
119
+ const derivedSalt = await hash({ s: saltSeed });
120
+
121
+ const poolConfig = createPoolConfigFromJson({
122
+ template: poolTemplate,
123
+ salt: derivedSalt
124
+ });
125
+
126
+ poolConfigs.push(poolConfig);
127
+ }
128
+
129
+ return poolConfigs;
130
+ }
131
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "../schemas/keystone.high.schema.json",
3
+ "metadata": {
4
+ "name": "High Security Profile",
5
+ "securityLevel": "high"
6
+ },
7
+ "pools": {
8
+ "sync": {
9
+ "id": "sync",
10
+ "allowedVerbs": [
11
+ "sync"
12
+ ],
13
+ "algo": "SHA-512",
14
+ "rounds": 4,
15
+ "behavior": {
16
+ "size": 2000,
17
+ "replenish": "top-up",
18
+ "selectSequentially": 10,
19
+ "selectRandomly": 10,
20
+ "targetBindingCount": 16
21
+ }
22
+ },
23
+ "manage": {
24
+ "id": "manage",
25
+ "allowedVerbs": [
26
+ "manage"
27
+ ],
28
+ "algo": "SHA-512",
29
+ "rounds": 4,
30
+ "behavior": {
31
+ "size": 2000,
32
+ "replenish": "replace-all",
33
+ "selectSequentially": 10,
34
+ "selectRandomly": 10,
35
+ "targetBindingCount": 16
36
+ }
37
+ },
38
+ "revoke": {
39
+ "id": "revoke",
40
+ "allowedVerbs": [
41
+ "revoke"
42
+ ],
43
+ "algo": "SHA-512",
44
+ "rounds": 20,
45
+ "behavior": {
46
+ "size": 2000,
47
+ "replenish": "delete-all",
48
+ "selectSequentially": 50,
49
+ "selectRandomly": 50,
50
+ "targetBindingCount": 0
51
+ }
52
+ },
53
+ "connect": {
54
+ "id": "connect",
55
+ "allowedVerbs": [
56
+ "connect"
57
+ ],
58
+ "algo": "SHA-512",
59
+ "rounds": 4,
60
+ "behavior": {
61
+ "size": 2000,
62
+ "replenish": "top-up",
63
+ "selectSequentially": 10,
64
+ "selectRandomly": 10,
65
+ "targetBindingCount": 16
66
+ }
67
+ },
68
+ "sign": {
69
+ "id": "default",
70
+ "allowedVerbs": [
71
+ "sign"
72
+ ],
73
+ "algo": "SHA-512",
74
+ "rounds": 4,
75
+ "behavior": {
76
+ "size": 2000,
77
+ "replenish": "top-up",
78
+ "selectSequentially": 10,
79
+ "selectRandomly": 10,
80
+ "targetBindingCount": 16
81
+ }
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "../schemas/keystone.low.schema.json",
3
+ "metadata": {
4
+ "name": "Low Security Profile",
5
+ "securityLevel": "low"
6
+ },
7
+ "pools": {
8
+ "sync": {
9
+ "id": "sync",
10
+ "allowedVerbs": [
11
+ "sync"
12
+ ],
13
+ "algo": "SHA-256",
14
+ "rounds": 1,
15
+ "behavior": {
16
+ "size": 100,
17
+ "replenish": "top-up",
18
+ "selectSequentially": 3,
19
+ "selectRandomly": 3,
20
+ "targetBindingCount": 8
21
+ }
22
+ },
23
+ "manage": {
24
+ "id": "manage",
25
+ "allowedVerbs": [
26
+ "manage"
27
+ ],
28
+ "algo": "SHA-256",
29
+ "rounds": 2,
30
+ "behavior": {
31
+ "size": 100,
32
+ "replenish": "replace-all",
33
+ "selectSequentially": 3,
34
+ "selectRandomly": 3,
35
+ "targetBindingCount": 8
36
+ }
37
+ },
38
+ "revoke": {
39
+ "id": "revoke",
40
+ "allowedVerbs": [
41
+ "revoke"
42
+ ],
43
+ "algo": "SHA-256",
44
+ "rounds": 5,
45
+ "behavior": {
46
+ "size": 100,
47
+ "replenish": "delete-all",
48
+ "selectSequentially": 3,
49
+ "selectRandomly": 3,
50
+ "targetBindingCount": 0
51
+ }
52
+ },
53
+ "connect": {
54
+ "id": "connect",
55
+ "allowedVerbs": [
56
+ "connect"
57
+ ],
58
+ "algo": "SHA-256",
59
+ "rounds": 1,
60
+ "behavior": {
61
+ "size": 100,
62
+ "replenish": "top-up",
63
+ "selectSequentially": 3,
64
+ "selectRandomly": 3,
65
+ "targetBindingCount": 8
66
+ }
67
+ },
68
+ "sign": {
69
+ "id": "default",
70
+ "allowedVerbs": [
71
+ "sign"
72
+ ],
73
+ "algo": "SHA-256",
74
+ "rounds": 2,
75
+ "behavior": {
76
+ "size": 100,
77
+ "replenish": "top-up",
78
+ "selectSequentially": 3,
79
+ "selectRandomly": 3,
80
+ "targetBindingCount": 8
81
+ }
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,84 @@
1
+ {
2
+ "$schema": "../schemas/keystone.medium.schema.json",
3
+ "metadata": {
4
+ "name": "Medium Security Profile",
5
+ "securityLevel": "medium"
6
+ },
7
+ "pools": {
8
+ "sync": {
9
+ "id": "sync",
10
+ "allowedVerbs": [
11
+ "sync"
12
+ ],
13
+ "algo": "SHA-256",
14
+ "rounds": 2,
15
+ "behavior": {
16
+ "size": 500,
17
+ "replenish": "top-up",
18
+ "selectSequentially": 5,
19
+ "selectRandomly": 5,
20
+ "targetBindingCount": 10
21
+ }
22
+ },
23
+ "manage": {
24
+ "id": "manage",
25
+ "allowedVerbs": [
26
+ "manage"
27
+ ],
28
+ "algo": "SHA-256",
29
+ "rounds": 2,
30
+ "behavior": {
31
+ "size": 500,
32
+ "replenish": "replace-all",
33
+ "selectSequentially": 5,
34
+ "selectRandomly": 5,
35
+ "targetBindingCount": 10
36
+ }
37
+ },
38
+ "revoke": {
39
+ "id": "revoke",
40
+ "allowedVerbs": [
41
+ "revoke"
42
+ ],
43
+ "algo": "SHA-256",
44
+ "rounds": 10,
45
+ "behavior": {
46
+ "size": 500,
47
+ "replenish": "delete-all",
48
+ "selectSequentially": 20,
49
+ "selectRandomly": 20,
50
+ "targetBindingCount": 0
51
+ }
52
+ },
53
+ "connect": {
54
+ "id": "connect",
55
+ "allowedVerbs": [
56
+ "connect"
57
+ ],
58
+ "algo": "SHA-256",
59
+ "rounds": 2,
60
+ "behavior": {
61
+ "size": 500,
62
+ "replenish": "top-up",
63
+ "selectSequentially": 5,
64
+ "selectRandomly": 5,
65
+ "targetBindingCount": 10
66
+ }
67
+ },
68
+ "sign": {
69
+ "id": "default",
70
+ "allowedVerbs": [
71
+ "sign"
72
+ ],
73
+ "algo": "SHA-256",
74
+ "rounds": 2,
75
+ "behavior": {
76
+ "size": 500,
77
+ "replenish": "top-up",
78
+ "selectSequentially": 5,
79
+ "selectRandomly": 5,
80
+ "targetBindingCount": 10
81
+ }
82
+ }
83
+ }
84
+ }