@sanctuary-framework/mcp-server 0.5.12 → 0.5.13
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/dist/cli.cjs +53 -18
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +53 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +248 -168
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +248 -168
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var aes_js = require('@noble/ciphers/aes.js');
|
|
3
5
|
var sha256 = require('@noble/hashes/sha256');
|
|
4
6
|
var hmac = require('@noble/hashes/hmac');
|
|
7
|
+
var ed25519 = require('@noble/curves/ed25519');
|
|
5
8
|
var promises = require('fs/promises');
|
|
6
9
|
var path = require('path');
|
|
7
10
|
var os = require('os');
|
|
8
11
|
var module$1 = require('module');
|
|
9
|
-
var crypto = require('crypto');
|
|
10
|
-
var aes_js = require('@noble/ciphers/aes.js');
|
|
11
|
-
var ed25519 = require('@noble/curves/ed25519');
|
|
12
12
|
var hashWasm = require('hash-wasm');
|
|
13
13
|
var hkdf = require('@noble/hashes/hkdf');
|
|
14
14
|
var index_js = require('@modelcontextprotocol/sdk/server/index.js');
|
|
@@ -28,6 +28,26 @@ var __export = (target, all) => {
|
|
|
28
28
|
for (var name in all)
|
|
29
29
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
30
30
|
};
|
|
31
|
+
function randomBytes(length) {
|
|
32
|
+
if (length <= 0) {
|
|
33
|
+
throw new RangeError("Length must be positive");
|
|
34
|
+
}
|
|
35
|
+
const buf = crypto.randomBytes(length);
|
|
36
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
37
|
+
}
|
|
38
|
+
function generateIV() {
|
|
39
|
+
return randomBytes(12);
|
|
40
|
+
}
|
|
41
|
+
function generateSalt() {
|
|
42
|
+
return randomBytes(32);
|
|
43
|
+
}
|
|
44
|
+
function generateRandomKey() {
|
|
45
|
+
return randomBytes(32);
|
|
46
|
+
}
|
|
47
|
+
var init_random = __esm({
|
|
48
|
+
"src/core/random.ts"() {
|
|
49
|
+
}
|
|
50
|
+
});
|
|
31
51
|
|
|
32
52
|
// src/core/encoding.ts
|
|
33
53
|
var encoding_exports = {};
|
|
@@ -79,6 +99,42 @@ var init_encoding = __esm({
|
|
|
79
99
|
"src/core/encoding.ts"() {
|
|
80
100
|
}
|
|
81
101
|
});
|
|
102
|
+
function encrypt(plaintext, key, aad) {
|
|
103
|
+
if (key.length !== 32) {
|
|
104
|
+
throw new Error("Key must be exactly 32 bytes (256 bits)");
|
|
105
|
+
}
|
|
106
|
+
const iv = generateIV();
|
|
107
|
+
const cipher = aes_js.gcm(key, iv, aad);
|
|
108
|
+
const ciphertext = cipher.encrypt(plaintext);
|
|
109
|
+
return {
|
|
110
|
+
v: 1,
|
|
111
|
+
alg: "aes-256-gcm",
|
|
112
|
+
iv: toBase64url(iv),
|
|
113
|
+
ct: toBase64url(ciphertext),
|
|
114
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function decrypt(payload, key, aad) {
|
|
118
|
+
if (key.length !== 32) {
|
|
119
|
+
throw new Error("Key must be exactly 32 bytes (256 bits)");
|
|
120
|
+
}
|
|
121
|
+
if (payload.v !== 1) {
|
|
122
|
+
throw new Error(`Unsupported payload version: ${payload.v}`);
|
|
123
|
+
}
|
|
124
|
+
if (payload.alg !== "aes-256-gcm") {
|
|
125
|
+
throw new Error(`Unsupported algorithm: ${payload.alg}`);
|
|
126
|
+
}
|
|
127
|
+
const iv = fromBase64url(payload.iv);
|
|
128
|
+
const ciphertext = fromBase64url(payload.ct);
|
|
129
|
+
const cipher = aes_js.gcm(key, iv, aad);
|
|
130
|
+
return cipher.decrypt(ciphertext);
|
|
131
|
+
}
|
|
132
|
+
var init_encryption = __esm({
|
|
133
|
+
"src/core/encryption.ts"() {
|
|
134
|
+
init_random();
|
|
135
|
+
init_encoding();
|
|
136
|
+
}
|
|
137
|
+
});
|
|
82
138
|
|
|
83
139
|
// src/core/hashing.ts
|
|
84
140
|
var hashing_exports = {};
|
|
@@ -207,6 +263,123 @@ var init_hashing = __esm({
|
|
|
207
263
|
init_encoding();
|
|
208
264
|
}
|
|
209
265
|
});
|
|
266
|
+
|
|
267
|
+
// src/core/identity.ts
|
|
268
|
+
var identity_exports = {};
|
|
269
|
+
__export(identity_exports, {
|
|
270
|
+
createIdentity: () => createIdentity,
|
|
271
|
+
generateIdentityId: () => generateIdentityId,
|
|
272
|
+
generateKeypair: () => generateKeypair,
|
|
273
|
+
publicKeyToDid: () => publicKeyToDid,
|
|
274
|
+
rotateKeys: () => rotateKeys,
|
|
275
|
+
sign: () => sign,
|
|
276
|
+
verify: () => verify
|
|
277
|
+
});
|
|
278
|
+
function generateKeypair() {
|
|
279
|
+
const privateKey = randomBytes(32);
|
|
280
|
+
const publicKey = ed25519.ed25519.getPublicKey(privateKey);
|
|
281
|
+
return { publicKey, privateKey };
|
|
282
|
+
}
|
|
283
|
+
function publicKeyToDid(publicKey) {
|
|
284
|
+
const multicodec = new Uint8Array([237, 1, ...publicKey]);
|
|
285
|
+
return `did:key:z${toBase64url(multicodec)}`;
|
|
286
|
+
}
|
|
287
|
+
function generateIdentityId(publicKey) {
|
|
288
|
+
const keyHash = hash(publicKey);
|
|
289
|
+
return Array.from(keyHash.slice(0, 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
290
|
+
}
|
|
291
|
+
function createIdentity(label, encryptionKey, keyProtection) {
|
|
292
|
+
const { publicKey, privateKey } = generateKeypair();
|
|
293
|
+
const identityId = generateIdentityId(publicKey);
|
|
294
|
+
const did = publicKeyToDid(publicKey);
|
|
295
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
296
|
+
const encryptedPrivateKey = encrypt(privateKey, encryptionKey);
|
|
297
|
+
privateKey.fill(0);
|
|
298
|
+
const publicIdentity = {
|
|
299
|
+
identity_id: identityId,
|
|
300
|
+
label,
|
|
301
|
+
public_key: toBase64url(publicKey),
|
|
302
|
+
did,
|
|
303
|
+
created_at: now,
|
|
304
|
+
key_type: "ed25519",
|
|
305
|
+
key_protection: keyProtection
|
|
306
|
+
};
|
|
307
|
+
const storedIdentity = {
|
|
308
|
+
...publicIdentity,
|
|
309
|
+
encrypted_private_key: encryptedPrivateKey,
|
|
310
|
+
rotation_history: []
|
|
311
|
+
};
|
|
312
|
+
return { publicIdentity, storedIdentity };
|
|
313
|
+
}
|
|
314
|
+
function sign(payload, encryptedPrivateKey, encryptionKey) {
|
|
315
|
+
const privateKey = decrypt(encryptedPrivateKey, encryptionKey);
|
|
316
|
+
try {
|
|
317
|
+
return ed25519.ed25519.sign(payload, privateKey);
|
|
318
|
+
} finally {
|
|
319
|
+
privateKey.fill(0);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function verify(payload, signature, publicKey) {
|
|
323
|
+
try {
|
|
324
|
+
return ed25519.ed25519.verify(signature, payload, publicKey);
|
|
325
|
+
} catch {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function rotateKeys(storedIdentity, encryptionKey, reason) {
|
|
330
|
+
const { publicKey: newPublicKey, privateKey: newPrivateKey } = generateKeypair();
|
|
331
|
+
const newIdentityDid = publicKeyToDid(newPublicKey);
|
|
332
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
333
|
+
const eventData = JSON.stringify({
|
|
334
|
+
old_public_key: storedIdentity.public_key,
|
|
335
|
+
new_public_key: toBase64url(newPublicKey),
|
|
336
|
+
identity_id: storedIdentity.identity_id,
|
|
337
|
+
reason,
|
|
338
|
+
rotated_at: now
|
|
339
|
+
});
|
|
340
|
+
const eventBytes = new TextEncoder().encode(eventData);
|
|
341
|
+
const signature = sign(
|
|
342
|
+
eventBytes,
|
|
343
|
+
storedIdentity.encrypted_private_key,
|
|
344
|
+
encryptionKey
|
|
345
|
+
);
|
|
346
|
+
const rotationEvent = {
|
|
347
|
+
old_public_key: storedIdentity.public_key,
|
|
348
|
+
new_public_key: toBase64url(newPublicKey),
|
|
349
|
+
identity_id: storedIdentity.identity_id,
|
|
350
|
+
reason,
|
|
351
|
+
rotated_at: now,
|
|
352
|
+
signature: toBase64url(signature)
|
|
353
|
+
};
|
|
354
|
+
const encryptedNewPrivateKey = encrypt(newPrivateKey, encryptionKey);
|
|
355
|
+
newPrivateKey.fill(0);
|
|
356
|
+
const updatedIdentity = {
|
|
357
|
+
...storedIdentity,
|
|
358
|
+
public_key: toBase64url(newPublicKey),
|
|
359
|
+
did: newIdentityDid,
|
|
360
|
+
encrypted_private_key: encryptedNewPrivateKey,
|
|
361
|
+
rotation_history: [
|
|
362
|
+
...storedIdentity.rotation_history,
|
|
363
|
+
{
|
|
364
|
+
old_public_key: storedIdentity.public_key,
|
|
365
|
+
new_public_key: toBase64url(newPublicKey),
|
|
366
|
+
rotation_event: toBase64url(
|
|
367
|
+
new TextEncoder().encode(JSON.stringify(rotationEvent))
|
|
368
|
+
),
|
|
369
|
+
rotated_at: now
|
|
370
|
+
}
|
|
371
|
+
]
|
|
372
|
+
};
|
|
373
|
+
return { updatedIdentity, rotationEvent };
|
|
374
|
+
}
|
|
375
|
+
var init_identity = __esm({
|
|
376
|
+
"src/core/identity.ts"() {
|
|
377
|
+
init_encoding();
|
|
378
|
+
init_encryption();
|
|
379
|
+
init_hashing();
|
|
380
|
+
init_random();
|
|
381
|
+
}
|
|
382
|
+
});
|
|
210
383
|
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
211
384
|
var { version: PKG_VERSION } = require2("../package.json");
|
|
212
385
|
var SANCTUARY_VERSION = PKG_VERSION;
|
|
@@ -384,24 +557,9 @@ function deepMerge(base, override) {
|
|
|
384
557
|
}
|
|
385
558
|
return result;
|
|
386
559
|
}
|
|
387
|
-
function randomBytes(length) {
|
|
388
|
-
if (length <= 0) {
|
|
389
|
-
throw new RangeError("Length must be positive");
|
|
390
|
-
}
|
|
391
|
-
const buf = crypto.randomBytes(length);
|
|
392
|
-
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
393
|
-
}
|
|
394
|
-
function generateIV() {
|
|
395
|
-
return randomBytes(12);
|
|
396
|
-
}
|
|
397
|
-
function generateSalt() {
|
|
398
|
-
return randomBytes(32);
|
|
399
|
-
}
|
|
400
|
-
function generateRandomKey() {
|
|
401
|
-
return randomBytes(32);
|
|
402
|
-
}
|
|
403
560
|
|
|
404
561
|
// src/storage/filesystem.ts
|
|
562
|
+
init_random();
|
|
405
563
|
var FilesystemStorage = class {
|
|
406
564
|
basePath;
|
|
407
565
|
constructor(basePath) {
|
|
@@ -509,141 +667,14 @@ var FilesystemStorage = class {
|
|
|
509
667
|
return total;
|
|
510
668
|
}
|
|
511
669
|
};
|
|
512
|
-
init_encoding();
|
|
513
|
-
function encrypt(plaintext, key, aad) {
|
|
514
|
-
if (key.length !== 32) {
|
|
515
|
-
throw new Error("Key must be exactly 32 bytes (256 bits)");
|
|
516
|
-
}
|
|
517
|
-
const iv = generateIV();
|
|
518
|
-
const cipher = aes_js.gcm(key, iv, aad);
|
|
519
|
-
const ciphertext = cipher.encrypt(plaintext);
|
|
520
|
-
return {
|
|
521
|
-
v: 1,
|
|
522
|
-
alg: "aes-256-gcm",
|
|
523
|
-
iv: toBase64url(iv),
|
|
524
|
-
ct: toBase64url(ciphertext),
|
|
525
|
-
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
function decrypt(payload, key, aad) {
|
|
529
|
-
if (key.length !== 32) {
|
|
530
|
-
throw new Error("Key must be exactly 32 bytes (256 bits)");
|
|
531
|
-
}
|
|
532
|
-
if (payload.v !== 1) {
|
|
533
|
-
throw new Error(`Unsupported payload version: ${payload.v}`);
|
|
534
|
-
}
|
|
535
|
-
if (payload.alg !== "aes-256-gcm") {
|
|
536
|
-
throw new Error(`Unsupported algorithm: ${payload.alg}`);
|
|
537
|
-
}
|
|
538
|
-
const iv = fromBase64url(payload.iv);
|
|
539
|
-
const ciphertext = fromBase64url(payload.ct);
|
|
540
|
-
const cipher = aes_js.gcm(key, iv, aad);
|
|
541
|
-
return cipher.decrypt(ciphertext);
|
|
542
|
-
}
|
|
543
670
|
|
|
544
671
|
// src/l1-cognitive/state-store.ts
|
|
672
|
+
init_encryption();
|
|
545
673
|
init_hashing();
|
|
674
|
+
init_identity();
|
|
546
675
|
|
|
547
|
-
// src/core/
|
|
548
|
-
|
|
549
|
-
init_hashing();
|
|
550
|
-
function generateKeypair() {
|
|
551
|
-
const privateKey = randomBytes(32);
|
|
552
|
-
const publicKey = ed25519.ed25519.getPublicKey(privateKey);
|
|
553
|
-
return { publicKey, privateKey };
|
|
554
|
-
}
|
|
555
|
-
function publicKeyToDid(publicKey) {
|
|
556
|
-
const multicodec = new Uint8Array([237, 1, ...publicKey]);
|
|
557
|
-
return `did:key:z${toBase64url(multicodec)}`;
|
|
558
|
-
}
|
|
559
|
-
function generateIdentityId(publicKey) {
|
|
560
|
-
const keyHash = hash(publicKey);
|
|
561
|
-
return Array.from(keyHash.slice(0, 16)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
562
|
-
}
|
|
563
|
-
function createIdentity(label, encryptionKey, keyProtection) {
|
|
564
|
-
const { publicKey, privateKey } = generateKeypair();
|
|
565
|
-
const identityId = generateIdentityId(publicKey);
|
|
566
|
-
const did = publicKeyToDid(publicKey);
|
|
567
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
568
|
-
const encryptedPrivateKey = encrypt(privateKey, encryptionKey);
|
|
569
|
-
privateKey.fill(0);
|
|
570
|
-
const publicIdentity = {
|
|
571
|
-
identity_id: identityId,
|
|
572
|
-
label,
|
|
573
|
-
public_key: toBase64url(publicKey),
|
|
574
|
-
did,
|
|
575
|
-
created_at: now,
|
|
576
|
-
key_type: "ed25519",
|
|
577
|
-
key_protection: keyProtection
|
|
578
|
-
};
|
|
579
|
-
const storedIdentity = {
|
|
580
|
-
...publicIdentity,
|
|
581
|
-
encrypted_private_key: encryptedPrivateKey,
|
|
582
|
-
rotation_history: []
|
|
583
|
-
};
|
|
584
|
-
return { publicIdentity, storedIdentity };
|
|
585
|
-
}
|
|
586
|
-
function sign(payload, encryptedPrivateKey, encryptionKey) {
|
|
587
|
-
const privateKey = decrypt(encryptedPrivateKey, encryptionKey);
|
|
588
|
-
try {
|
|
589
|
-
return ed25519.ed25519.sign(payload, privateKey);
|
|
590
|
-
} finally {
|
|
591
|
-
privateKey.fill(0);
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
|
-
function verify(payload, signature, publicKey) {
|
|
595
|
-
try {
|
|
596
|
-
return ed25519.ed25519.verify(signature, payload, publicKey);
|
|
597
|
-
} catch {
|
|
598
|
-
return false;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
function rotateKeys(storedIdentity, encryptionKey, reason) {
|
|
602
|
-
const { publicKey: newPublicKey, privateKey: newPrivateKey } = generateKeypair();
|
|
603
|
-
const newIdentityDid = publicKeyToDid(newPublicKey);
|
|
604
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
605
|
-
const eventData = JSON.stringify({
|
|
606
|
-
old_public_key: storedIdentity.public_key,
|
|
607
|
-
new_public_key: toBase64url(newPublicKey),
|
|
608
|
-
identity_id: storedIdentity.identity_id,
|
|
609
|
-
reason,
|
|
610
|
-
rotated_at: now
|
|
611
|
-
});
|
|
612
|
-
const eventBytes = new TextEncoder().encode(eventData);
|
|
613
|
-
const signature = sign(
|
|
614
|
-
eventBytes,
|
|
615
|
-
storedIdentity.encrypted_private_key,
|
|
616
|
-
encryptionKey
|
|
617
|
-
);
|
|
618
|
-
const rotationEvent = {
|
|
619
|
-
old_public_key: storedIdentity.public_key,
|
|
620
|
-
new_public_key: toBase64url(newPublicKey),
|
|
621
|
-
identity_id: storedIdentity.identity_id,
|
|
622
|
-
reason,
|
|
623
|
-
rotated_at: now,
|
|
624
|
-
signature: toBase64url(signature)
|
|
625
|
-
};
|
|
626
|
-
const encryptedNewPrivateKey = encrypt(newPrivateKey, encryptionKey);
|
|
627
|
-
newPrivateKey.fill(0);
|
|
628
|
-
const updatedIdentity = {
|
|
629
|
-
...storedIdentity,
|
|
630
|
-
public_key: toBase64url(newPublicKey),
|
|
631
|
-
did: newIdentityDid,
|
|
632
|
-
encrypted_private_key: encryptedNewPrivateKey,
|
|
633
|
-
rotation_history: [
|
|
634
|
-
...storedIdentity.rotation_history,
|
|
635
|
-
{
|
|
636
|
-
old_public_key: storedIdentity.public_key,
|
|
637
|
-
new_public_key: toBase64url(newPublicKey),
|
|
638
|
-
rotation_event: toBase64url(
|
|
639
|
-
new TextEncoder().encode(JSON.stringify(rotationEvent))
|
|
640
|
-
),
|
|
641
|
-
rotated_at: now
|
|
642
|
-
}
|
|
643
|
-
]
|
|
644
|
-
};
|
|
645
|
-
return { updatedIdentity, rotationEvent };
|
|
646
|
-
}
|
|
676
|
+
// src/core/key-derivation.ts
|
|
677
|
+
init_random();
|
|
647
678
|
init_encoding();
|
|
648
679
|
var ARGON2_MEMORY_COST = 65536;
|
|
649
680
|
var ARGON2_TIME_COST = 3;
|
|
@@ -1241,7 +1272,9 @@ function toolResult(data) {
|
|
|
1241
1272
|
}
|
|
1242
1273
|
|
|
1243
1274
|
// src/l1-cognitive/tools.ts
|
|
1275
|
+
init_identity();
|
|
1244
1276
|
init_encoding();
|
|
1277
|
+
init_encryption();
|
|
1245
1278
|
init_encoding();
|
|
1246
1279
|
var RESERVED_NAMESPACE_PREFIXES2 = [
|
|
1247
1280
|
"_identities",
|
|
@@ -1748,6 +1781,7 @@ function createL1Tools(stateStore, storage, masterKey, keyProtection, auditLog)
|
|
|
1748
1781
|
}
|
|
1749
1782
|
|
|
1750
1783
|
// src/l2-operational/audit-log.ts
|
|
1784
|
+
init_encryption();
|
|
1751
1785
|
init_encoding();
|
|
1752
1786
|
var AuditLog = class {
|
|
1753
1787
|
storage;
|
|
@@ -1845,6 +1879,8 @@ var AuditLog = class {
|
|
|
1845
1879
|
// src/l3-disclosure/commitments.ts
|
|
1846
1880
|
init_hashing();
|
|
1847
1881
|
init_encoding();
|
|
1882
|
+
init_random();
|
|
1883
|
+
init_encryption();
|
|
1848
1884
|
init_encoding();
|
|
1849
1885
|
function createCommitment(value, blindingFactor) {
|
|
1850
1886
|
const blindingBytes = blindingFactor ? fromBase64url(blindingFactor) : randomBytes(32);
|
|
@@ -1925,7 +1961,9 @@ var CommitmentStore = class {
|
|
|
1925
1961
|
};
|
|
1926
1962
|
|
|
1927
1963
|
// src/l3-disclosure/policies.ts
|
|
1964
|
+
init_encryption();
|
|
1928
1965
|
init_encoding();
|
|
1966
|
+
init_random();
|
|
1929
1967
|
function evaluateDisclosure(policy, context, requestedFields) {
|
|
1930
1968
|
return requestedFields.map((field) => {
|
|
1931
1969
|
const exactRule = policy.rules.find((r) => r.context === context);
|
|
@@ -2056,6 +2094,9 @@ var PolicyStore = class {
|
|
|
2056
2094
|
);
|
|
2057
2095
|
}
|
|
2058
2096
|
};
|
|
2097
|
+
|
|
2098
|
+
// src/l3-disclosure/zk-proofs.ts
|
|
2099
|
+
init_random();
|
|
2059
2100
|
init_encoding();
|
|
2060
2101
|
var G = ed25519.RistrettoPoint.BASE;
|
|
2061
2102
|
var H_INPUT = concatBytes(
|
|
@@ -2733,7 +2774,10 @@ function createL3Tools(storage, masterKey, auditLog) {
|
|
|
2733
2774
|
}
|
|
2734
2775
|
|
|
2735
2776
|
// src/l4-reputation/reputation-store.ts
|
|
2777
|
+
init_encryption();
|
|
2736
2778
|
init_encoding();
|
|
2779
|
+
init_random();
|
|
2780
|
+
init_identity();
|
|
2737
2781
|
function computeMedian(values) {
|
|
2738
2782
|
if (values.length === 0) return 0;
|
|
2739
2783
|
const sorted = [...values].sort((a, b) => a - b);
|
|
@@ -3628,6 +3672,24 @@ function createL4Tools(storage, masterKey, identityManager, auditLog, handshakeR
|
|
|
3628
3672
|
}
|
|
3629
3673
|
const publishType = args.type;
|
|
3630
3674
|
const veracoreUrl = args.verascore_url || "https://verascore.ai";
|
|
3675
|
+
const ALLOWED_VERASCORE_HOSTS = ["verascore.ai", "www.verascore.ai", "api.verascore.ai"];
|
|
3676
|
+
try {
|
|
3677
|
+
const parsed = new URL(veracoreUrl);
|
|
3678
|
+
if (parsed.protocol !== "https:") {
|
|
3679
|
+
return toolResult({
|
|
3680
|
+
error: `verascore_url must use HTTPS. Got: ${parsed.protocol}`
|
|
3681
|
+
});
|
|
3682
|
+
}
|
|
3683
|
+
if (!ALLOWED_VERASCORE_HOSTS.includes(parsed.hostname)) {
|
|
3684
|
+
return toolResult({
|
|
3685
|
+
error: `verascore_url must point to a known Verascore domain (${ALLOWED_VERASCORE_HOSTS.join(", ")}). Got: ${parsed.hostname}`
|
|
3686
|
+
});
|
|
3687
|
+
}
|
|
3688
|
+
} catch {
|
|
3689
|
+
return toolResult({
|
|
3690
|
+
error: `verascore_url is not a valid URL: ${veracoreUrl}`
|
|
3691
|
+
});
|
|
3692
|
+
}
|
|
3631
3693
|
const agentId = args.verascore_agent_id || identity.did.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
3632
3694
|
let publishData;
|
|
3633
3695
|
if (args.data) {
|
|
@@ -3657,24 +3719,21 @@ function createL4Tools(storage, masterKey, identityManager, auditLog, handshakeR
|
|
|
3657
3719
|
return toolResult({ error: `Unknown publish type: ${publishType}` });
|
|
3658
3720
|
}
|
|
3659
3721
|
}
|
|
3660
|
-
const { sign:
|
|
3661
|
-
const payloadBytes =
|
|
3722
|
+
const { sign: identitySign } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
3723
|
+
const payloadBytes = new TextEncoder().encode(JSON.stringify(publishData));
|
|
3662
3724
|
let signatureB64;
|
|
3663
3725
|
try {
|
|
3664
|
-
const
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
]),
|
|
3671
|
-
format: "der",
|
|
3672
|
-
type: "pkcs8"
|
|
3673
|
-
});
|
|
3674
|
-
const sig = sign2(null, payloadBytes, privateKey);
|
|
3675
|
-
signatureB64 = sig.toString("base64url");
|
|
3726
|
+
const signingBytes = identitySign(
|
|
3727
|
+
payloadBytes,
|
|
3728
|
+
identity.encrypted_private_key,
|
|
3729
|
+
identityEncryptionKey
|
|
3730
|
+
);
|
|
3731
|
+
signatureB64 = toBase64url(signingBytes);
|
|
3676
3732
|
} catch (signError) {
|
|
3677
|
-
|
|
3733
|
+
return toolResult({
|
|
3734
|
+
error: "Failed to sign publish payload. Identity key may be corrupted.",
|
|
3735
|
+
details: signError instanceof Error ? signError.message : String(signError)
|
|
3736
|
+
});
|
|
3678
3737
|
}
|
|
3679
3738
|
const requestBody = {
|
|
3680
3739
|
agentId,
|
|
@@ -3753,7 +3812,9 @@ var DEFAULT_POLICY = {
|
|
|
3753
3812
|
"reputation_import",
|
|
3754
3813
|
"reputation_export",
|
|
3755
3814
|
"bootstrap_provide_guarantee",
|
|
3756
|
-
"decommission_certificate"
|
|
3815
|
+
"decommission_certificate",
|
|
3816
|
+
"reputation_publish"
|
|
3817
|
+
// SEC-039: Explicit Tier 1 — sends data to external API
|
|
3757
3818
|
],
|
|
3758
3819
|
tier2_anomaly: DEFAULT_TIER2,
|
|
3759
3820
|
tier3_always_allow: [
|
|
@@ -3805,7 +3866,9 @@ var DEFAULT_POLICY = {
|
|
|
3805
3866
|
"shr_gateway_export",
|
|
3806
3867
|
"bridge_commit",
|
|
3807
3868
|
"bridge_verify",
|
|
3808
|
-
"bridge_attest"
|
|
3869
|
+
"bridge_attest",
|
|
3870
|
+
"dashboard_open"
|
|
3871
|
+
// SEC-039: Explicit Tier 3 — only generates a URL
|
|
3809
3872
|
],
|
|
3810
3873
|
approval_channel: DEFAULT_CHANNEL
|
|
3811
3874
|
};
|
|
@@ -3913,6 +3976,7 @@ tier1_always_approve:
|
|
|
3913
3976
|
- reputation_import
|
|
3914
3977
|
- reputation_export
|
|
3915
3978
|
- bootstrap_provide_guarantee
|
|
3979
|
+
- reputation_publish
|
|
3916
3980
|
|
|
3917
3981
|
# \u2500\u2500\u2500 Tier 2: Behavioral Anomaly Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3918
3982
|
# Triggers approval when agent behavior deviates from its baseline.
|
|
@@ -3975,6 +4039,7 @@ tier3_always_allow:
|
|
|
3975
4039
|
- bridge_commit
|
|
3976
4040
|
- bridge_verify
|
|
3977
4041
|
- bridge_attest
|
|
4042
|
+
- dashboard_open
|
|
3978
4043
|
|
|
3979
4044
|
# \u2500\u2500\u2500 Approval Channel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3980
4045
|
# How Sanctuary reaches you when approval is needed.
|
|
@@ -4002,6 +4067,7 @@ async function loadPrincipalPolicy(storagePath) {
|
|
|
4002
4067
|
}
|
|
4003
4068
|
|
|
4004
4069
|
// src/principal-policy/baseline.ts
|
|
4070
|
+
init_encryption();
|
|
4005
4071
|
init_encoding();
|
|
4006
4072
|
var BASELINE_NAMESPACE = "_principal";
|
|
4007
4073
|
var BASELINE_KEY = "session-baseline";
|
|
@@ -4227,6 +4293,7 @@ function canonicalizeForSigning(body) {
|
|
|
4227
4293
|
}
|
|
4228
4294
|
|
|
4229
4295
|
// src/shr/generator.ts
|
|
4296
|
+
init_identity();
|
|
4230
4297
|
init_encoding();
|
|
4231
4298
|
var DEFAULT_VALIDITY_MS = 60 * 60 * 1e3;
|
|
4232
4299
|
function generateSHR(identityId, opts) {
|
|
@@ -5607,7 +5674,9 @@ function generateDashboardHTML(options) {
|
|
|
5607
5674
|
|
|
5608
5675
|
<script>
|
|
5609
5676
|
// Constants
|
|
5610
|
-
|
|
5677
|
+
// SEC-038: Do NOT embed the long-lived auth token in page source.
|
|
5678
|
+
// Use only the session token stored in sessionStorage by the login flow.
|
|
5679
|
+
const AUTH_TOKEN = sessionStorage.getItem('authToken') || '';
|
|
5611
5680
|
const TIMEOUT_SECONDS = ${options.timeoutSeconds};
|
|
5612
5681
|
const API_BASE = '';
|
|
5613
5682
|
|
|
@@ -8120,6 +8189,7 @@ function createPrincipalPolicyTools(policy, baseline, auditLog) {
|
|
|
8120
8189
|
}
|
|
8121
8190
|
|
|
8122
8191
|
// src/shr/verifier.ts
|
|
8192
|
+
init_identity();
|
|
8123
8193
|
init_encoding();
|
|
8124
8194
|
function verifySHR(shr, now) {
|
|
8125
8195
|
const errors = [];
|
|
@@ -8542,7 +8612,9 @@ function createSHRTools(config, identityManager, masterKey, auditLog) {
|
|
|
8542
8612
|
}
|
|
8543
8613
|
|
|
8544
8614
|
// src/handshake/protocol.ts
|
|
8615
|
+
init_identity();
|
|
8545
8616
|
init_encoding();
|
|
8617
|
+
init_random();
|
|
8546
8618
|
function generateNonce() {
|
|
8547
8619
|
return toBase64url(randomBytes(32));
|
|
8548
8620
|
}
|
|
@@ -8709,7 +8781,9 @@ function deriveTrustTier(level) {
|
|
|
8709
8781
|
}
|
|
8710
8782
|
|
|
8711
8783
|
// src/handshake/attestation.ts
|
|
8784
|
+
init_identity();
|
|
8712
8785
|
init_encoding();
|
|
8786
|
+
init_identity();
|
|
8713
8787
|
init_encoding();
|
|
8714
8788
|
var ATTESTATION_VERSION = "1.0";
|
|
8715
8789
|
function deriveTrustTier2(level) {
|
|
@@ -9502,10 +9576,13 @@ function createFederationTools(auditLog, handshakeResults) {
|
|
|
9502
9576
|
|
|
9503
9577
|
// src/bridge/tools.ts
|
|
9504
9578
|
init_encoding();
|
|
9579
|
+
init_encryption();
|
|
9505
9580
|
init_encoding();
|
|
9506
9581
|
|
|
9507
9582
|
// src/bridge/bridge.ts
|
|
9583
|
+
init_identity();
|
|
9508
9584
|
init_encoding();
|
|
9585
|
+
init_random();
|
|
9509
9586
|
init_hashing();
|
|
9510
9587
|
function canonicalize(outcome) {
|
|
9511
9588
|
return stringToBytes(stableStringify(outcome));
|
|
@@ -10656,7 +10733,9 @@ function createAuditTools(config) {
|
|
|
10656
10733
|
}
|
|
10657
10734
|
|
|
10658
10735
|
// src/l2-operational/context-gate.ts
|
|
10736
|
+
init_encryption();
|
|
10659
10737
|
init_encoding();
|
|
10738
|
+
init_random();
|
|
10660
10739
|
init_hashing();
|
|
10661
10740
|
var MAX_CONTEXT_FIELDS = 1e3;
|
|
10662
10741
|
var MAX_POLICY_RULES = 50;
|
|
@@ -12626,6 +12705,7 @@ function createL2HardeningTools(storagePath, auditLog) {
|
|
|
12626
12705
|
}
|
|
12627
12706
|
|
|
12628
12707
|
// src/index.ts
|
|
12708
|
+
init_random();
|
|
12629
12709
|
init_encoding();
|
|
12630
12710
|
|
|
12631
12711
|
// src/l2-operational/model-provenance.ts
|