yakmesh 2.8.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +637 -0
- package/CONTRIBUTING.md +42 -0
- package/Caddyfile +77 -0
- package/README.md +119 -29
- package/adapters/adapter-mlv-bible/README.md +124 -0
- package/adapters/adapter-mlv-bible/index.js +400 -0
- package/adapters/chat-mod-adapter.js +532 -0
- package/adapters/content-adapter.js +273 -0
- package/content/api.js +50 -41
- package/content/index.js +2 -2
- package/content/store.js +355 -173
- package/dashboard/index.html +19 -3
- package/database/replication.js +117 -37
- package/docs/CRYPTO-AGILITY.md +204 -0
- package/docs/MTLS-RESEARCH.md +367 -0
- package/docs/NAMCHE-SPEC.md +681 -0
- package/docs/PEERQUANTA-YAKMESH-INTEGRATION.md +407 -0
- package/docs/PRECISION-DISCLOSURE.md +96 -0
- package/docs/README.md +76 -0
- package/docs/ROADMAP-2.4.0.md +447 -0
- package/docs/ROADMAP-2.5.0.md +244 -0
- package/docs/SECURITY-AUDIT-REPORT.md +306 -0
- package/docs/SST-INTEGRATION.md +712 -0
- package/docs/STEADYWATCH-IMPLEMENTATION.md +303 -0
- package/docs/TERNARY-AUDIT-REPORT.md +247 -0
- package/docs/TME-FAQ.md +221 -0
- package/docs/WHITEPAPER.md +623 -0
- package/docs/adapters.html +1001 -0
- package/docs/advanced-systems.html +1045 -0
- package/docs/annex.html +1046 -0
- package/docs/api.html +970 -0
- package/docs/business/response-templates.md +160 -0
- package/docs/c2c.html +1225 -0
- package/docs/cli.html +1332 -0
- package/docs/configuration.html +1248 -0
- package/docs/darshan.html +1085 -0
- package/docs/dharma.html +966 -0
- package/docs/docs-bundle.html +1075 -0
- package/docs/docs.css +3120 -0
- package/docs/docs.js +556 -0
- package/docs/doko.html +969 -0
- package/docs/geo-proof.html +858 -0
- package/docs/getting-started.html +840 -0
- package/docs/gumba-tutorial.html +1144 -0
- package/docs/gumba.html +1098 -0
- package/docs/index.html +914 -0
- package/docs/jhilke.html +1312 -0
- package/docs/karma.html +1100 -0
- package/docs/katha.html +1037 -0
- package/docs/lama.html +978 -0
- package/docs/mandala.html +1067 -0
- package/docs/mani.html +964 -0
- package/docs/mantra.html +967 -0
- package/docs/mesh.html +1409 -0
- package/docs/nakpak.html +869 -0
- package/docs/namche.html +928 -0
- package/docs/nav-order.json +53 -0
- package/docs/prahari.html +1043 -0
- package/docs/prism-bash.min.js +1 -0
- package/docs/prism-javascript.min.js +1 -0
- package/docs/prism-json.min.js +1 -0
- package/docs/prism-tomorrow.min.css +1 -0
- package/docs/prism.min.js +1 -0
- package/docs/privacy.html +699 -0
- package/docs/quick-reference.html +1181 -0
- package/docs/sakshi.html +1402 -0
- package/docs/sandboxing.md +386 -0
- package/docs/seva.html +911 -0
- package/docs/sherpa.html +871 -0
- package/docs/studio.html +860 -0
- package/docs/stupa.html +995 -0
- package/docs/tailwind.min.css +2 -0
- package/docs/tattva.html +1332 -0
- package/docs/terms.html +686 -0
- package/docs/time-server-deployment.md +166 -0
- package/docs/time-sources.html +1392 -0
- package/docs/tivra.html +1127 -0
- package/docs/trademark-policy.html +686 -0
- package/docs/tribhuj.html +1183 -0
- package/docs/trust-security.html +1029 -0
- package/docs/tutorials/backup-recovery.html +654 -0
- package/docs/tutorials/dashboard.html +604 -0
- package/docs/tutorials/domain-setup.html +605 -0
- package/docs/tutorials/host-website.html +456 -0
- package/docs/tutorials/mesh-network.html +505 -0
- package/docs/tutorials/mobile-access.html +445 -0
- package/docs/tutorials/privacy.html +467 -0
- package/docs/tutorials/raspberry-pi.html +600 -0
- package/docs/tutorials/security-basics.html +539 -0
- package/docs/tutorials/share-files.html +431 -0
- package/docs/tutorials/troubleshooting.html +637 -0
- package/docs/tutorials/trust-karma.html +419 -0
- package/docs/tutorials/yak-protocol.html +456 -0
- package/docs/tutorials.html +1034 -0
- package/docs/vani.html +1270 -0
- package/docs/webserver.html +809 -0
- package/docs/yak-protocol.html +940 -0
- package/docs/yak-timeserver-design.md +475 -0
- package/docs/yakapp.html +1015 -0
- package/docs/ypc27.html +1069 -0
- package/docs/yurt.html +1344 -0
- package/embedded-docs/bundle.js +334 -74
- package/gossip/protocol.js +247 -27
- package/identity/key-resolver.js +262 -0
- package/identity/machine-seed.js +632 -0
- package/identity/node-key.js +669 -368
- package/identity/tribhuj-ratchet.js +506 -0
- package/knowledge-base.js +37 -8
- package/launcher/yakmesh.bat +62 -0
- package/launcher/yakmesh.sh +70 -0
- package/mesh/annex.js +462 -108
- package/mesh/beacon-broadcast.js +113 -1
- package/mesh/darshan.js +1718 -0
- package/mesh/gumba.js +1567 -0
- package/mesh/jhilke.js +651 -0
- package/mesh/katha.js +1012 -0
- package/mesh/nakpak-routing.js +8 -5
- package/mesh/network.js +724 -34
- package/mesh/pulse-sync.js +4 -1
- package/mesh/rate-limiter.js +127 -15
- package/mesh/seva.js +526 -0
- package/mesh/sherpa-discovery.js +89 -8
- package/mesh/sybil-defense.js +19 -5
- package/mesh/temporal-encoder.js +4 -3
- package/mesh/vani.js +1364 -0
- package/mesh/yurt.js +1340 -0
- package/models/entropy-sentinel.onnx +0 -0
- package/models/karma-trust.onnx +0 -0
- package/models/manifest.json +43 -0
- package/models/sakshi-anomaly.onnx +0 -0
- package/oracle/code-proof-protocol.js +7 -6
- package/oracle/codebase-lock.js +257 -28
- package/oracle/index.js +74 -15
- package/oracle/ma902-snmp.js +678 -0
- package/oracle/module-sealer.js +5 -3
- package/oracle/network-identity.js +16 -0
- package/oracle/packet-checksum.js +201 -0
- package/oracle/sst.js +579 -0
- package/oracle/ternary-144t.js +714 -0
- package/oracle/ternary-ml.js +481 -0
- package/oracle/time-api.js +239 -0
- package/oracle/time-source.js +137 -47
- package/oracle/validation-oracle-hardened.js +1111 -1071
- package/oracle/validation-oracle.js +4 -2
- package/oracle/ypc27.js +211 -0
- package/package.json +20 -3
- package/protocol/yak-handler.js +35 -9
- package/protocol/yak-protocol.js +28 -13
- package/reference/cpp/yakmesh_mceliece_shard.cpp +168 -0
- package/reference/cpp/yakmesh_ypc27.cpp +179 -0
- package/sbom.json +87 -0
- package/scripts/security-audit.mjs +264 -0
- package/scripts/update-docs-nav.js +194 -0
- package/scripts/update-docs-sidebar.cjs +164 -0
- package/security/crypto-config.js +4 -3
- package/security/dharma-moderation.js +517 -0
- package/security/doko-identity.js +193 -143
- package/security/domain-consensus.js +86 -85
- package/security/fs-hardening.js +620 -0
- package/security/hardware-attestation.js +5 -3
- package/security/hybrid-trust.js +227 -87
- package/security/karma-rate-limiter.js +692 -0
- package/security/khata-protocol.js +22 -21
- package/security/khata-trust-integration.js +277 -150
- package/security/memory-safety.js +635 -0
- package/security/mesh-auth.js +11 -10
- package/security/mesh-revocation.js +373 -5
- package/security/namche-gateway.js +298 -69
- package/security/sakshi.js +460 -3
- package/security/sangha.js +770 -0
- package/security/secure-config.js +473 -0
- package/security/silicon-parity.js +13 -10
- package/security/steadywatch.js +1142 -0
- package/security/strike-system.js +32 -3
- package/security/temporal-signing.js +488 -0
- package/security/trit-commitment.js +464 -0
- package/server/crypto/annex.js +247 -0
- package/server/darshan-api.js +343 -0
- package/server/index.js +3259 -362
- package/server/komm-api.js +668 -0
- package/utils/accel.js +2273 -0
- package/utils/ternary-id.js +79 -0
- package/utils/verify-worker.js +57 -0
- package/webserver/index.js +95 -5
- package/assets/yakmesh-logo.png +0 -0
- package/assets/yakmesh-logo.svg +0 -80
- package/assets/yakmesh-logo2.png +0 -0
- package/assets/yakmesh-logo2sm.png +0 -0
- package/assets/ymsm.png +0 -0
- package/website/assets/silhouettes/adapters.svg +0 -107
- package/website/assets/silhouettes/api-endpoints.svg +0 -115
- package/website/assets/silhouettes/atomic-clock.svg +0 -83
- package/website/assets/silhouettes/base-camp.svg +0 -81
- package/website/assets/silhouettes/bridge.svg +0 -69
- package/website/assets/silhouettes/docs-bundle.svg +0 -113
- package/website/assets/silhouettes/doko-basket.svg +0 -70
- package/website/assets/silhouettes/fortress.svg +0 -93
- package/website/assets/silhouettes/gateway.svg +0 -54
- package/website/assets/silhouettes/gears.svg +0 -93
- package/website/assets/silhouettes/globe-satellite.svg +0 -67
- package/website/assets/silhouettes/karma-wheel.svg +0 -137
- package/website/assets/silhouettes/lama-council.svg +0 -141
- package/website/assets/silhouettes/mandala-network.svg +0 -169
- package/website/assets/silhouettes/mani-stones.svg +0 -149
- package/website/assets/silhouettes/mantra-wheel.svg +0 -116
- package/website/assets/silhouettes/mesh-nodes.svg +0 -113
- package/website/assets/silhouettes/nakpak.svg +0 -56
- package/website/assets/silhouettes/peak-lightning.svg +0 -73
- package/website/assets/silhouettes/sherpa.svg +0 -69
- package/website/assets/silhouettes/stupa-tower.svg +0 -119
- package/website/assets/silhouettes/tattva-eye.svg +0 -78
- package/website/assets/silhouettes/terminal.svg +0 -74
- package/website/assets/silhouettes/webserver.svg +0 -145
- package/website/assets/silhouettes/yak.svg +0 -78
- package/website/assets/yakmesh-logo.png +0 -0
- package/website/assets/yakmesh-logo.webp +0 -0
- package/website/assets/yakmesh-logo128x140.webp +0 -0
- package/website/assets/yakmesh-logo2.png +0 -0
- package/website/assets/yakmesh-logo2.svg +0 -51
- package/website/assets/yakmesh-logo40x44.webp +0 -0
- package/website/assets/yakmesh.gif +0 -0
- package/website/assets/yakmesh.ico +0 -0
- package/website/assets/yakmesh.jpg +0 -0
- package/website/assets/yakmesh.pdf +0 -0
- package/website/assets/yakmesh.png +0 -0
- package/website/assets/yakmesh.svg +0 -70
- package/website/assets/yakmesh128.webp +0 -0
- package/website/assets/yakmesh32.png +0 -0
- package/website/assets/yakmesh32.svg +0 -65
- package/website/assets/yakmesh32o.ico +0 -2
- package/website/assets/yakmesh32o.svg +0 -65
- package/website/assets/yakmesh32o.svgz +0 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Yakmesh Secure Defaults + Oracle-Attested Configuration
|
|
3
|
+
*
|
|
4
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
* PHILOSOPHY: THE ORACLE ATTESTS YOUR CONFIG
|
|
6
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
|
+
*
|
|
8
|
+
* Traditional secure defaults: Ship with good defaults, hope no one changes them.
|
|
9
|
+
* Oracle-attested config: Runtime config is hashed and verified.
|
|
10
|
+
*
|
|
11
|
+
* The Oracle maintains a "secure profile" — a hash of known-good configuration.
|
|
12
|
+
* At startup and periodically, the actual config is compared against this profile.
|
|
13
|
+
*
|
|
14
|
+
* If someone relaxes security settings (larger request sizes, longer timeouts,
|
|
15
|
+
* disabled features), the config hash changes and the Oracle reports a violation.
|
|
16
|
+
*
|
|
17
|
+
* This creates cryptographic accountability for configuration changes.
|
|
18
|
+
*
|
|
19
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
20
|
+
* SECURE PROFILE LEVELS
|
|
21
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
22
|
+
*
|
|
23
|
+
* PARANOID: Maximum security, minimal attack surface, may break some features
|
|
24
|
+
* HARDENED: Production-ready security, all protections enabled
|
|
25
|
+
* STANDARD: Balanced security with reasonable defaults
|
|
26
|
+
* DEVELOPMENT: Relaxed for local development (warnings only, no enforcement)
|
|
27
|
+
*
|
|
28
|
+
* @module security/secure-config
|
|
29
|
+
* @version 1.0.0
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { createLogger } from '../utils/logger.js';
|
|
33
|
+
import { sha3_256 } from '../utils/accel.js';
|
|
34
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
35
|
+
import { EventEmitter } from 'events';
|
|
36
|
+
|
|
37
|
+
const log = createLogger('security:secure-config');
|
|
38
|
+
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// CONSTANTS
|
|
41
|
+
// =============================================================================
|
|
42
|
+
|
|
43
|
+
/** Security profile levels */
|
|
44
|
+
export const PROFILE_LEVEL = {
|
|
45
|
+
PARANOID: 'PARANOID',
|
|
46
|
+
HARDENED: 'HARDENED',
|
|
47
|
+
STANDARD: 'STANDARD',
|
|
48
|
+
DEVELOPMENT: 'DEVELOPMENT',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Default secure configuration values */
|
|
52
|
+
export const SECURE_DEFAULTS = {
|
|
53
|
+
// -------------------------------------------------------------------------
|
|
54
|
+
// NETWORK
|
|
55
|
+
// -------------------------------------------------------------------------
|
|
56
|
+
network: {
|
|
57
|
+
maxConnections: 100, // Max simultaneous peer connections
|
|
58
|
+
connectionTimeout: 30000, // Connection timeout (ms)
|
|
59
|
+
handshakeTimeout: 10000, // Handshake timeout (ms)
|
|
60
|
+
maxMessageSize: 65536, // Max message size (64 KB)
|
|
61
|
+
heartbeatInterval: 30000, // Heartbeat interval (ms)
|
|
62
|
+
heartbeatTimeout: 90000, // Heartbeat timeout (ms)
|
|
63
|
+
minReconnectDelay: 1000, // Min reconnect delay (ms)
|
|
64
|
+
maxReconnectDelay: 60000, // Max reconnect delay (ms)
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
// -------------------------------------------------------------------------
|
|
68
|
+
// RATE LIMITING (per KARMA tier)
|
|
69
|
+
// -------------------------------------------------------------------------
|
|
70
|
+
rateLimiting: {
|
|
71
|
+
unknown: 10, // Requests/min for unknown peers
|
|
72
|
+
hostile: 2, // Requests/min for hostile peers
|
|
73
|
+
low: 25, // Requests/min for low-KARMA peers
|
|
74
|
+
medium: 50, // Requests/min for medium-KARMA peers
|
|
75
|
+
high: 100, // Requests/min for high-KARMA peers
|
|
76
|
+
excellent: 200, // Requests/min for excellent-KARMA peers
|
|
77
|
+
burstMultiplier: 2, // Burst allowance multiplier
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// -------------------------------------------------------------------------
|
|
81
|
+
// CRYPTO
|
|
82
|
+
// -------------------------------------------------------------------------
|
|
83
|
+
crypto: {
|
|
84
|
+
algorithm: 'ML-DSA-65', // Primary signing algorithm
|
|
85
|
+
kemAlgorithm: 'ML-KEM-768', // Key encapsulation mechanism
|
|
86
|
+
hashAlgorithm: 'SHA3-256', // Hash algorithm
|
|
87
|
+
keyRotationInterval: 300000, // TRIBHUJ rotation (5 min)
|
|
88
|
+
sessionTimeout: 3600000, // Session timeout (1 hour)
|
|
89
|
+
nonceCacheSize: 10000, // Replay nonce cache size
|
|
90
|
+
nonceCacheTTL: 600000, // Nonce TTL (10 min)
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// -------------------------------------------------------------------------
|
|
94
|
+
// IDENTITY
|
|
95
|
+
// -------------------------------------------------------------------------
|
|
96
|
+
identity: {
|
|
97
|
+
dokoRequireSignature: true, // Require DOKO signature verification
|
|
98
|
+
dokoMaxAge: 86400000, // Max DOKO age (24 hours)
|
|
99
|
+
trustNewPeers: false, // Don't trust new peers by default
|
|
100
|
+
requireAttestation: true, // Require attestation for sensitive ops
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// -------------------------------------------------------------------------
|
|
104
|
+
// CONTENT
|
|
105
|
+
// -------------------------------------------------------------------------
|
|
106
|
+
content: {
|
|
107
|
+
maxUploadSize: 16777216, // Max upload size (16 MB)
|
|
108
|
+
maxDownloadSize: 67108864, // Max download size (64 MB)
|
|
109
|
+
requireDARSHAN: true, // Require DARSHAN for streaming
|
|
110
|
+
allowUnverified: false, // Don't serve unverified content
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// -------------------------------------------------------------------------
|
|
114
|
+
// GOSSIP
|
|
115
|
+
// -------------------------------------------------------------------------
|
|
116
|
+
gossip: {
|
|
117
|
+
maxPayloadSize: 4096, // Max gossip payload (4 KB)
|
|
118
|
+
ttlMax: 10, // Max TTL hops
|
|
119
|
+
duplicateWindow: 60000, // Duplicate detection window (1 min)
|
|
120
|
+
propagationDelay: 100, // Propagation delay (ms)
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// -------------------------------------------------------------------------
|
|
124
|
+
// ORACLE
|
|
125
|
+
// -------------------------------------------------------------------------
|
|
126
|
+
oracle: {
|
|
127
|
+
hashAlgorithm: 'SHA3-256', // Oracle hash algorithm
|
|
128
|
+
verifyOnStart: true, // Verify codebase on startup
|
|
129
|
+
watchForTampering: true, // Monitor for runtime tampering
|
|
130
|
+
lockCodebase: true, // Lock codebase files
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// -------------------------------------------------------------------------
|
|
134
|
+
// SANGHA
|
|
135
|
+
// -------------------------------------------------------------------------
|
|
136
|
+
sangha: {
|
|
137
|
+
circulationInterval: 5000, // Attestation circulation (5 sec)
|
|
138
|
+
staleThreshold: 10000, // Stale attestation threshold (10 sec)
|
|
139
|
+
quorumPercentage: 0.67, // Required quorum for consensus
|
|
140
|
+
anomalyThreshold: 0.5, // Anomaly detection threshold
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
// -------------------------------------------------------------------------
|
|
144
|
+
// FS HARDENING
|
|
145
|
+
// -------------------------------------------------------------------------
|
|
146
|
+
fsHardening: {
|
|
147
|
+
protectIdentityFiles: true, // Lock identity files
|
|
148
|
+
protectDatabase: true, // Monitor database file
|
|
149
|
+
verificationInterval: 30000, // Verification interval (30 sec)
|
|
150
|
+
gracePeriod: 5000, // Startup grace period (5 sec)
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
// -------------------------------------------------------------------------
|
|
154
|
+
// MEMORY SAFETY
|
|
155
|
+
// -------------------------------------------------------------------------
|
|
156
|
+
memorySafety: {
|
|
157
|
+
enableCanaries: true, // Enable memory canaries
|
|
158
|
+
heapCanaries: 3, // Number of heap canaries
|
|
159
|
+
closureCanaries: 2, // Number of closure canaries
|
|
160
|
+
nativeCanaries: 2, // Number of native canaries
|
|
161
|
+
monitorInterval: 5000, // Monitor interval (5 sec)
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// PROFILE MODIFICATIONS
|
|
167
|
+
// =============================================================================
|
|
168
|
+
|
|
169
|
+
/** Profile-specific overrides */
|
|
170
|
+
const PROFILE_OVERRIDES = {
|
|
171
|
+
[PROFILE_LEVEL.PARANOID]: {
|
|
172
|
+
network: { maxConnections: 50, maxMessageSize: 32768 },
|
|
173
|
+
rateLimiting: { unknown: 5, hostile: 1 },
|
|
174
|
+
identity: { dokoMaxAge: 43200000 }, // 12 hours
|
|
175
|
+
content: { allowUnverified: false, maxUploadSize: 8388608 }, // 8 MB
|
|
176
|
+
gossip: { ttlMax: 5 },
|
|
177
|
+
},
|
|
178
|
+
[PROFILE_LEVEL.HARDENED]: {
|
|
179
|
+
// Uses all secure defaults
|
|
180
|
+
},
|
|
181
|
+
[PROFILE_LEVEL.STANDARD]: {
|
|
182
|
+
network: { maxConnections: 200 },
|
|
183
|
+
rateLimiting: { unknown: 20 },
|
|
184
|
+
identity: { trustNewPeers: false },
|
|
185
|
+
},
|
|
186
|
+
[PROFILE_LEVEL.DEVELOPMENT]: {
|
|
187
|
+
network: { maxConnections: 500, maxMessageSize: 1048576 },
|
|
188
|
+
rateLimiting: { unknown: 100, hostile: 10 },
|
|
189
|
+
identity: { trustNewPeers: true, requireAttestation: false },
|
|
190
|
+
content: { allowUnverified: true },
|
|
191
|
+
oracle: { lockCodebase: false, watchForTampering: false },
|
|
192
|
+
fsHardening: { protectIdentityFiles: false },
|
|
193
|
+
memorySafety: { enableCanaries: false },
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// =============================================================================
|
|
198
|
+
// SECURE CONFIG MANAGER
|
|
199
|
+
// =============================================================================
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* SecureConfigManager — Oracle-attested configuration management
|
|
203
|
+
*/
|
|
204
|
+
export class SecureConfigManager extends EventEmitter {
|
|
205
|
+
#config;
|
|
206
|
+
#profileLevel;
|
|
207
|
+
#profileHash;
|
|
208
|
+
#actualHash;
|
|
209
|
+
#sangha;
|
|
210
|
+
#deviations;
|
|
211
|
+
#lastVerification;
|
|
212
|
+
|
|
213
|
+
constructor(profileLevel = PROFILE_LEVEL.HARDENED) {
|
|
214
|
+
super();
|
|
215
|
+
this.#profileLevel = profileLevel;
|
|
216
|
+
this.#config = this.#buildConfig(profileLevel);
|
|
217
|
+
this.#profileHash = this.#computeHash(this.#config);
|
|
218
|
+
this.#actualHash = this.#profileHash;
|
|
219
|
+
this.#sangha = null;
|
|
220
|
+
this.#deviations = [];
|
|
221
|
+
this.#lastVerification = Date.now();
|
|
222
|
+
|
|
223
|
+
log.info('Secure config manager initialized', {
|
|
224
|
+
profile: profileLevel,
|
|
225
|
+
hash: this.#profileHash.slice(0, 16) + '...',
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
Object.seal(this);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Build configuration for a profile level
|
|
233
|
+
*/
|
|
234
|
+
#buildConfig(level) {
|
|
235
|
+
// Start with secure defaults
|
|
236
|
+
const config = JSON.parse(JSON.stringify(SECURE_DEFAULTS));
|
|
237
|
+
|
|
238
|
+
// Apply profile overrides
|
|
239
|
+
const overrides = PROFILE_OVERRIDES[level] || {};
|
|
240
|
+
for (const [section, values] of Object.entries(overrides)) {
|
|
241
|
+
if (config[section]) {
|
|
242
|
+
Object.assign(config[section], values);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return config;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Compute SHA3-256 hash of configuration
|
|
251
|
+
*/
|
|
252
|
+
#computeHash(config) {
|
|
253
|
+
const json = JSON.stringify(config, Object.keys(config).sort());
|
|
254
|
+
const hash = sha3_256(new TextEncoder().encode(json));
|
|
255
|
+
return bytesToHex(hash);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get a configuration value
|
|
260
|
+
* @param {string} path - Dot-separated path (e.g., 'network.maxConnections')
|
|
261
|
+
* @returns {any}
|
|
262
|
+
*/
|
|
263
|
+
get(path) {
|
|
264
|
+
const parts = path.split('.');
|
|
265
|
+
let value = this.#config;
|
|
266
|
+
|
|
267
|
+
for (const part of parts) {
|
|
268
|
+
if (value === undefined || value === null) return undefined;
|
|
269
|
+
value = value[part];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return value;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Set a configuration value (tracks deviations)
|
|
277
|
+
* @param {string} path - Dot-separated path
|
|
278
|
+
* @param {any} value - New value
|
|
279
|
+
*/
|
|
280
|
+
set(path, value) {
|
|
281
|
+
const parts = path.split('.');
|
|
282
|
+
const key = parts.pop();
|
|
283
|
+
let target = this.#config;
|
|
284
|
+
|
|
285
|
+
for (const part of parts) {
|
|
286
|
+
if (target[part] === undefined) {
|
|
287
|
+
target[part] = {};
|
|
288
|
+
}
|
|
289
|
+
target = target[part];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const oldValue = target[key];
|
|
293
|
+
target[key] = value;
|
|
294
|
+
|
|
295
|
+
// Track deviation
|
|
296
|
+
if (oldValue !== value) {
|
|
297
|
+
this.#deviations.push({
|
|
298
|
+
path,
|
|
299
|
+
oldValue,
|
|
300
|
+
newValue: value,
|
|
301
|
+
timestamp: Date.now(),
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
log.warn('Configuration deviation', { path, oldValue, newValue: value });
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Recompute actual hash
|
|
308
|
+
this.#actualHash = this.#computeHash(this.#config);
|
|
309
|
+
|
|
310
|
+
// Check if we've deviated from profile
|
|
311
|
+
if (this.#actualHash !== this.#profileHash) {
|
|
312
|
+
this.emit('deviation', {
|
|
313
|
+
profileLevel: this.#profileLevel,
|
|
314
|
+
deviations: this.#deviations,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Verify configuration matches expected profile
|
|
321
|
+
* @returns {{ valid: boolean, deviations: object[], hash: string }}
|
|
322
|
+
*/
|
|
323
|
+
verify() {
|
|
324
|
+
this.#lastVerification = Date.now();
|
|
325
|
+
this.#actualHash = this.#computeHash(this.#config);
|
|
326
|
+
|
|
327
|
+
const valid = this.#actualHash === this.#profileHash;
|
|
328
|
+
|
|
329
|
+
if (!valid) {
|
|
330
|
+
log.warn('Configuration verification failed', {
|
|
331
|
+
expected: this.#profileHash.slice(0, 16) + '...',
|
|
332
|
+
actual: this.#actualHash.slice(0, 16) + '...',
|
|
333
|
+
deviations: this.#deviations.length,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return {
|
|
338
|
+
valid,
|
|
339
|
+
profileLevel: this.#profileLevel,
|
|
340
|
+
expectedHash: this.#profileHash,
|
|
341
|
+
actualHash: this.#actualHash,
|
|
342
|
+
deviations: [...this.#deviations],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Reset to profile defaults
|
|
348
|
+
*/
|
|
349
|
+
reset() {
|
|
350
|
+
this.#config = this.#buildConfig(this.#profileLevel);
|
|
351
|
+
this.#actualHash = this.#profileHash;
|
|
352
|
+
this.#deviations = [];
|
|
353
|
+
|
|
354
|
+
log.info('Configuration reset to profile defaults', {
|
|
355
|
+
profile: this.#profileLevel,
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
this.emit('reset', { profileLevel: this.#profileLevel });
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Get the full configuration object (read-only copy)
|
|
363
|
+
*/
|
|
364
|
+
getAll() {
|
|
365
|
+
return JSON.parse(JSON.stringify(this.#config));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Get a section of the configuration
|
|
370
|
+
*/
|
|
371
|
+
getSection(section) {
|
|
372
|
+
return this.#config[section]
|
|
373
|
+
? JSON.parse(JSON.stringify(this.#config[section]))
|
|
374
|
+
: undefined;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Bind SANGHA for collective verification
|
|
379
|
+
*/
|
|
380
|
+
bindSangha(sangha) {
|
|
381
|
+
this.#sangha = sangha;
|
|
382
|
+
log.info('Secure config bound to SANGHA collective');
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Get state for SANGHA attestation
|
|
387
|
+
*/
|
|
388
|
+
getState() {
|
|
389
|
+
return {
|
|
390
|
+
component: 'config',
|
|
391
|
+
profileLevel: this.#profileLevel,
|
|
392
|
+
profileHash: this.#profileHash,
|
|
393
|
+
actualHash: this.#actualHash,
|
|
394
|
+
isValid: this.#actualHash === this.#profileHash,
|
|
395
|
+
deviations: this.#deviations.length,
|
|
396
|
+
lastVerification: this.#lastVerification,
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Get status for API
|
|
402
|
+
*/
|
|
403
|
+
getStatus() {
|
|
404
|
+
return {
|
|
405
|
+
profileLevel: this.#profileLevel,
|
|
406
|
+
profileHash: this.#profileHash,
|
|
407
|
+
actualHash: this.#actualHash,
|
|
408
|
+
isValid: this.#actualHash === this.#profileHash,
|
|
409
|
+
deviations: this.#deviations.length,
|
|
410
|
+
lastVerification: this.#lastVerification,
|
|
411
|
+
sanghaBound: !!this.#sangha,
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Get profile level
|
|
417
|
+
*/
|
|
418
|
+
getProfileLevel() {
|
|
419
|
+
return this.#profileLevel;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Check if running in development mode
|
|
424
|
+
*/
|
|
425
|
+
isDevelopment() {
|
|
426
|
+
return this.#profileLevel === PROFILE_LEVEL.DEVELOPMENT;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Check if a feature is enabled by the config
|
|
431
|
+
*/
|
|
432
|
+
isEnabled(feature) {
|
|
433
|
+
switch (feature) {
|
|
434
|
+
case 'codebaseLock':
|
|
435
|
+
return this.get('oracle.lockCodebase');
|
|
436
|
+
case 'tamperWatch':
|
|
437
|
+
return this.get('oracle.watchForTampering');
|
|
438
|
+
case 'canaries':
|
|
439
|
+
return this.get('memorySafety.enableCanaries');
|
|
440
|
+
case 'fsHardening':
|
|
441
|
+
return this.get('fsHardening.protectIdentityFiles');
|
|
442
|
+
case 'attestation':
|
|
443
|
+
return this.get('identity.requireAttestation');
|
|
444
|
+
case 'darshan':
|
|
445
|
+
return this.get('content.requireDARSHAN');
|
|
446
|
+
default:
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// =============================================================================
|
|
453
|
+
// SINGLETON & EXPORTS
|
|
454
|
+
// =============================================================================
|
|
455
|
+
|
|
456
|
+
let _instance = null;
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Get the SecureConfigManager singleton
|
|
460
|
+
* @param {string} profileLevel - Profile level (only used on first call)
|
|
461
|
+
* @returns {SecureConfigManager}
|
|
462
|
+
*/
|
|
463
|
+
export function getSecureConfig(profileLevel) {
|
|
464
|
+
if (!_instance) {
|
|
465
|
+
// Detect profile from environment
|
|
466
|
+
const envProfile = process.env.YAKMESH_SECURITY_PROFILE;
|
|
467
|
+
const level = profileLevel || envProfile || PROFILE_LEVEL.HARDENED;
|
|
468
|
+
_instance = new SecureConfigManager(level);
|
|
469
|
+
}
|
|
470
|
+
return _instance;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
export default SecureConfigManager;
|
|
@@ -213,13 +213,14 @@ export async function getPlatformUUID() {
|
|
|
213
213
|
* Get Windows machine GUID
|
|
214
214
|
*/
|
|
215
215
|
async function getWindowsUUID() {
|
|
216
|
-
const {
|
|
216
|
+
const { execFile } = await import('child_process');
|
|
217
217
|
const { promisify } = await import('util');
|
|
218
|
-
const
|
|
218
|
+
const execFileAsync = promisify(execFile);
|
|
219
219
|
|
|
220
220
|
try {
|
|
221
|
-
const { stdout } = await
|
|
222
|
-
'reg
|
|
221
|
+
const { stdout } = await execFileAsync(
|
|
222
|
+
'reg',
|
|
223
|
+
['query', 'HKLM\\SOFTWARE\\Microsoft\\Cryptography', '/v', 'MachineGuid'],
|
|
223
224
|
{ timeout: 5000 }
|
|
224
225
|
);
|
|
225
226
|
const match = stdout.match(/MachineGuid\s+REG_SZ\s+(\S+)/);
|
|
@@ -227,8 +228,9 @@ async function getWindowsUUID() {
|
|
|
227
228
|
} catch (err) {
|
|
228
229
|
// Try WMI as fallback
|
|
229
230
|
try {
|
|
230
|
-
const { stdout } = await
|
|
231
|
-
'wmic
|
|
231
|
+
const { stdout } = await execFileAsync(
|
|
232
|
+
'wmic',
|
|
233
|
+
['csproduct', 'get', 'uuid'],
|
|
232
234
|
{ timeout: 5000 }
|
|
233
235
|
);
|
|
234
236
|
const lines = stdout.trim().split('\n');
|
|
@@ -273,12 +275,13 @@ async function getLinuxUUID() {
|
|
|
273
275
|
* Get macOS IOPlatformUUID
|
|
274
276
|
*/
|
|
275
277
|
async function getMacOSUUID() {
|
|
276
|
-
const {
|
|
278
|
+
const { execFile } = await import('child_process');
|
|
277
279
|
const { promisify } = await import('util');
|
|
278
|
-
const
|
|
280
|
+
const execFileAsync = promisify(execFile);
|
|
279
281
|
|
|
280
|
-
const { stdout } = await
|
|
281
|
-
'ioreg
|
|
282
|
+
const { stdout } = await execFileAsync(
|
|
283
|
+
'/usr/sbin/ioreg',
|
|
284
|
+
['-rd1', '-c', 'IOPlatformExpertDevice'],
|
|
282
285
|
{ timeout: 5000 }
|
|
283
286
|
);
|
|
284
287
|
|