@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.
- package/CHANGELOG.md +16 -0
- package/dist/common/other/graph-helper.d.mts.map +1 -1
- package/dist/common/other/graph-helper.mjs +7 -6
- package/dist/common/other/graph-helper.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.d.mts +1 -2
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +4 -19
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +2 -1
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +2 -1
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts +28 -16
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +155 -76
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-policy-types.d.mts +6 -4
- package/dist/keystone/keystone-policy-types.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.d.mts +38 -2
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.mjs +177 -11
- package/dist/keystone/keystone-service-v1.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.respec.mjs +527 -41
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
- package/dist/keystone/keystone-types.d.mts +53 -11
- package/dist/keystone/keystone-types.d.mts.map +1 -1
- package/dist/keystone/policy/keystone-profile-builder.d.mts +25 -0
- package/dist/keystone/policy/keystone-profile-builder.d.mts.map +1 -0
- package/dist/keystone/policy/keystone-profile-builder.mjs +117 -0
- package/dist/keystone/policy/keystone-profile-builder.mjs.map +1 -0
- package/dist/keystone/policy/profiles/profile-high.json +84 -0
- package/dist/keystone/policy/profiles/profile-low.json +84 -0
- package/dist/keystone/policy/profiles/profile-medium.json +84 -0
- package/dist/keystone/policy/profiles/profile-session.json +84 -0
- package/dist/keystone/policy/profiles/profile-test.json +84 -0
- package/dist/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/keystone.high.schema.json +26 -0
- package/dist/keystone/policy/schemas/keystone.low.schema.json +26 -0
- package/dist/keystone/policy/schemas/keystone.medium.schema.json +26 -0
- package/dist/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
- package/dist/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts +8 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs +582 -0
- package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts +7 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs +274 -0
- package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts +8 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs +322 -0
- package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts +7 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.mjs +307 -0
- package/dist/sync/sync-conflict-text-merge.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.d.mts +8 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.mjs +233 -0
- package/dist/sync/sync-innerspace-constants.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs +233 -0
- package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs +225 -0
- package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs +235 -0
- package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs +211 -0
- package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-innerspace.withid.respec.d.mts +8 -0
- package/dist/sync/sync-innerspace.withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace.withid.respec.mjs +260 -0
- package/dist/sync/sync-innerspace.withid.respec.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +1 -0
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +13 -4
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +5 -3
- package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +165 -145
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-withid.pingpong.respec.mjs +8 -8
- package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -1
- package/dist/timeline/timeline-api.d.mts.map +1 -1
- package/dist/timeline/timeline-api.mjs +1 -14
- package/dist/timeline/timeline-api.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.d.mts.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs +0 -40
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.d.mts.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs +6 -6
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
- package/ibgib-foundations.md +2 -1
- package/package.json +1 -1
- package/src/common/other/graph-helper.mts +7 -6
- package/src/keystone/README.md +34 -17
- package/src/keystone/docs/CRYPTANALYSIS.md +185 -0
- package/src/keystone/docs/architecture.md +45 -3
- package/src/keystone/docs/delegation.md +57 -0
- package/src/keystone/docs/profiles.md +124 -0
- package/src/keystone/keystone-config-builder.mts +3 -21
- package/src/keystone/keystone-constants.mts +2 -1
- package/src/keystone/keystone-helpers.mts +204 -81
- package/src/keystone/keystone-policy-types.mts +6 -4
- package/src/keystone/keystone-service-v1.mts +223 -11
- package/src/keystone/keystone-service-v1.respec.mts +596 -39
- package/src/keystone/keystone-types.mts +55 -9
- package/src/keystone/policy/IMPLEMENTATION.md +60 -0
- package/src/keystone/policy/README.md +94 -0
- package/src/keystone/policy/keystone-profile-builder.mts +131 -0
- package/src/keystone/policy/profiles/profile-high.json +84 -0
- package/src/keystone/policy/profiles/profile-low.json +84 -0
- package/src/keystone/policy/profiles/profile-medium.json +84 -0
- package/src/keystone/policy/profiles/profile-session.json +84 -0
- package/src/keystone/policy/profiles/profile-test.json +84 -0
- package/src/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/keystone.high.schema.json +26 -0
- package/src/keystone/policy/schemas/keystone.low.schema.json +26 -0
- package/src/keystone/policy/schemas/keystone.medium.schema.json +26 -0
- package/src/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
- package/src/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
- package/src/sync/docs/security.md +54 -21
- package/src/sync/sync-conflict-adv-multitimelines.withid.respec.mts +706 -0
- package/src/sync/sync-conflict-basic-divergence.withid.respec.mts +321 -0
- package/src/sync/sync-conflict-basic-multitimelines.withid.respec.mts +374 -0
- package/src/sync/sync-conflict-text-merge.withid.respec.mts +347 -0
- package/src/sync/sync-innerspace-constants.withid.respec.mts +264 -0
- package/src/sync/sync-innerspace-deep-updates.withid.respec.mts +272 -0
- package/src/sync/sync-innerspace-dest-ahead.withid.respec.mts +266 -0
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +0 -1
- package/src/sync/sync-innerspace-multiple-timelines.withid.respec.mts +273 -0
- package/src/sync/sync-innerspace-partial-update.withid.respec.mts +249 -0
- package/src/sync/sync-innerspace.withid.respec.mts +265 -0
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +12 -4
- package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +5 -3
- package/src/sync/sync-saga-coordinator.mts +159 -143
- package/src/sync/sync-withid.pingpong.respec.mts +8 -8
- package/src/timeline/timeline-api.mts +1 -15
- package/src/timeline/timeline-api.respec.mts +3 -3
- package/src/witness/space/reconciliation-space/reconciliation-space-base.mts +0 -46
- package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts +6 -5
- package/tsconfig.json +6 -1
- package/src/keystone/keystone-policy.schema.json +0 -51
- package/src/witness/space/reconciliation-space/reconciliation-space-base.mts.OLD.md +0 -884
- 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
|
|
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
|
-
|
|
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
|
+
}
|