@nekzus/liop 2.5.0-beta.2 → 2.5.0-beta.3
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/README.md +87 -40
- package/dist/bin/agent.js +27 -894
- package/dist/bridge.d.ts +4 -3
- package/dist/bridge.js +1 -4
- package/dist/chunk-2XHSALII.js +3 -0
- package/dist/chunk-2ZYX736J.js +2 -0
- package/dist/chunk-3WRKTVOF.js +2 -0
- package/dist/chunk-6KFKO6ZX.js +2 -0
- package/dist/chunk-6VK2XALI.js +2 -0
- package/dist/chunk-AYDF3IFZ.js +2 -0
- package/dist/chunk-CTTTLCGL.js +31 -0
- package/dist/chunk-ECRS6N33.js +4 -0
- package/dist/chunk-FDJMH4CB.js +2 -0
- package/dist/chunk-FTF6AMF6.js +0 -1
- package/dist/chunk-GWVSCZUS.js +2 -0
- package/dist/chunk-LEXMMIQI.js +15 -0
- package/dist/chunk-LM26HOJ6.js +31 -0
- package/dist/chunk-MQ5SU26J.js +2 -0
- package/dist/chunk-N35BC62H.js +2 -0
- package/dist/chunk-P6IJ3VBD.js +3 -0
- package/dist/chunk-TKLRW52V.js +2 -0
- package/dist/chunk-V35CXJQN.js +2 -0
- package/dist/chunk-WP5ER7RH.js +3 -0
- package/dist/chunk-XLVEDKM6.js +2 -0
- package/dist/chunk-Y675R34Z.js +2 -0
- package/dist/chunk-YD2AF2M6.js +46 -0
- package/dist/chunk-YLCNV764.js +3 -0
- package/dist/chunk-ZZMSFCJP.js +3 -0
- package/dist/client.d.ts +5 -4
- package/dist/client.js +1 -11
- package/dist/gateway.d.ts +6 -5
- package/dist/gateway.js +1 -11
- package/dist/{hybrid-DWe1bMoV.d.ts → hybrid-BZpCiUaV.d.ts} +4 -4
- package/dist/{index-BuEQtBHD.d.ts → index-BYDtRGue.d.ts} +8 -4
- package/dist/{index-CdW8j8Bn.d.ts → index-ByzjpRCk.d.ts} +30 -2
- package/dist/index.d.ts +57 -10
- package/dist/index.js +4 -317
- package/dist/kyber-PULV7PQX.js +2 -0
- package/dist/mesh.d.ts +1 -1
- package/dist/mesh.js +1 -5
- package/dist/{node-B0b2vUFS.d.ts → node-Djzm6UYd.d.ts} +8 -0
- package/dist/protocol/liop_core.proto +22 -6
- package/dist/server.d.ts +4 -3
- package/dist/server.js +1 -8
- package/dist/{types-CzRSOlOo.d.ts → types-29zv9X1V.d.ts} +3 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -2
- package/dist/verifier-DqZ9MQ9l.d.ts +82 -0
- package/dist/verifier-J4NQYZX5.js +2 -0
- package/dist/workers/logic-execution.d.ts +7 -0
- package/dist/workers/logic-execution.js +1 -271
- package/dist/workers/zk-verifier.d.ts +9 -0
- package/dist/workers/zk-verifier.js +1 -173
- package/dist/zk-DzYNWBgo.d.ts +104 -0
- package/package.json +7 -2
- package/dist/bin/agent.js.map +0 -1
- package/dist/bridge.js.map +0 -1
- package/dist/chunk-2KSO3W4A.js +0 -77
- package/dist/chunk-2KSO3W4A.js.map +0 -1
- package/dist/chunk-2STZHJ24.js +0 -114
- package/dist/chunk-2STZHJ24.js.map +0 -1
- package/dist/chunk-3QH44NKZ.js +0 -115
- package/dist/chunk-3QH44NKZ.js.map +0 -1
- package/dist/chunk-5SWHE62F.js +0 -3683
- package/dist/chunk-5SWHE62F.js.map +0 -1
- package/dist/chunk-7BSCUYUE.js +0 -421
- package/dist/chunk-7BSCUYUE.js.map +0 -1
- package/dist/chunk-7PITYWOV.js +0 -68
- package/dist/chunk-7PITYWOV.js.map +0 -1
- package/dist/chunk-EJ426URA.js +0 -818
- package/dist/chunk-EJ426URA.js.map +0 -1
- package/dist/chunk-FCFTYOAS.js +0 -793
- package/dist/chunk-FCFTYOAS.js.map +0 -1
- package/dist/chunk-FTF6AMF6.js.map +0 -1
- package/dist/chunk-IK7CGWAZ.js +0 -24
- package/dist/chunk-IK7CGWAZ.js.map +0 -1
- package/dist/chunk-K3DGJLUY.js +0 -106
- package/dist/chunk-K3DGJLUY.js.map +0 -1
- package/dist/chunk-PAICJCKJ.js +0 -332
- package/dist/chunk-PAICJCKJ.js.map +0 -1
- package/dist/chunk-PUDETPL4.js +0 -279
- package/dist/chunk-PUDETPL4.js.map +0 -1
- package/dist/chunk-UJFWPRDM.js +0 -206884
- package/dist/chunk-UJFWPRDM.js.map +0 -1
- package/dist/chunk-VRB5HUYU.js +0 -1492
- package/dist/chunk-VRB5HUYU.js.map +0 -1
- package/dist/chunk-VRDZ5IKE.js +0 -558
- package/dist/chunk-VRDZ5IKE.js.map +0 -1
- package/dist/chunk-WPTOJYN5.js +0 -181
- package/dist/chunk-WPTOJYN5.js.map +0 -1
- package/dist/chunk-XRDN232O.js +0 -877
- package/dist/chunk-XRDN232O.js.map +0 -1
- package/dist/chunk-Y62GORQF.js +0 -51
- package/dist/chunk-Y62GORQF.js.map +0 -1
- package/dist/chunk-ZP3VVXOI.js +0 -66
- package/dist/chunk-ZP3VVXOI.js.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/gateway.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/kyber-CGOA7Q6A.js +0 -3
- package/dist/kyber-CGOA7Q6A.js.map +0 -1
- package/dist/mesh.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/verifier-COnid_dg.d.ts +0 -31
- package/dist/verifier-XFU7ZB2W.js +0 -6
- package/dist/verifier-XFU7ZB2W.js.map +0 -1
- package/dist/workers/logic-execution.js.map +0 -1
- package/dist/workers/zk-verifier.js.map +0 -1
package/dist/chunk-WPTOJYN5.js
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { ml_dsa65 } from '@noble/post-quantum/ml-dsa.js';
|
|
2
|
-
|
|
3
|
-
// src/rpc/crypto/dilithium.ts
|
|
4
|
-
var DILITHIUM65_CONSTANTS = {
|
|
5
|
-
PUBLIC_KEY_BYTES: 1952,
|
|
6
|
-
SECRET_KEY_BYTES: 4032,
|
|
7
|
-
SIGNATURE_BYTES: 3309,
|
|
8
|
-
DEFAULT_CONTEXT: new TextEncoder().encode("LIOP-FIPS204-ML-DSA-65")
|
|
9
|
-
};
|
|
10
|
-
function normalizeMessage(message) {
|
|
11
|
-
if (typeof message === "string") {
|
|
12
|
-
return new TextEncoder().encode(message);
|
|
13
|
-
}
|
|
14
|
-
return message;
|
|
15
|
-
}
|
|
16
|
-
function canonicalizeJson(obj) {
|
|
17
|
-
if (obj === null || typeof obj !== "object") {
|
|
18
|
-
return JSON.stringify(obj);
|
|
19
|
-
}
|
|
20
|
-
if (Array.isArray(obj)) {
|
|
21
|
-
return `[${obj.map(canonicalizeJson).join(",")}]`;
|
|
22
|
-
}
|
|
23
|
-
const record = obj;
|
|
24
|
-
const sortedKeys = Object.keys(record).filter((key) => record[key] !== void 0).sort();
|
|
25
|
-
const entries = sortedKeys.map(
|
|
26
|
-
(key) => `${JSON.stringify(key)}:${canonicalizeJson(record[key])}`
|
|
27
|
-
);
|
|
28
|
-
return `{${entries.join(",")}}`;
|
|
29
|
-
}
|
|
30
|
-
var Dilithium65Wrapper = {
|
|
31
|
-
/** Constants */
|
|
32
|
-
PUBLIC_KEY_BYTES: DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES,
|
|
33
|
-
SECRET_KEY_BYTES: DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES,
|
|
34
|
-
SIGNATURE_BYTES: DILITHIUM65_CONSTANTS.SIGNATURE_BYTES,
|
|
35
|
-
/**
|
|
36
|
-
* Generates a new ML-DSA-65 (FIPS 204) key pair.
|
|
37
|
-
* Optionally accepts a 32-byte seed for deterministic key generation.
|
|
38
|
-
*/
|
|
39
|
-
generateKeyPair(seed) {
|
|
40
|
-
if (seed && seed.length !== 32) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
`ML-DSA-65 seed must be exactly 32 bytes (Received: ${seed.length})`
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
const keys = ml_dsa65.keygen(seed);
|
|
46
|
-
return {
|
|
47
|
-
publicKey: keys.publicKey,
|
|
48
|
-
secretKey: keys.secretKey
|
|
49
|
-
};
|
|
50
|
-
},
|
|
51
|
-
/**
|
|
52
|
-
* Validates and imports a raw ML-DSA-65 public key.
|
|
53
|
-
*/
|
|
54
|
-
importPublicKey(buffer) {
|
|
55
|
-
if (buffer.length !== DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
`ML-DSA-65 Public Key must be exactly ${DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES} bytes (Received: ${buffer.length})`
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
return buffer;
|
|
61
|
-
},
|
|
62
|
-
/**
|
|
63
|
-
* Signs a message using the post-quantum secret key.
|
|
64
|
-
* Supports optional domain separation context (up to 255 bytes).
|
|
65
|
-
*/
|
|
66
|
-
sign(message, secretKey, context) {
|
|
67
|
-
if (secretKey.length !== DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES) {
|
|
68
|
-
throw new Error(
|
|
69
|
-
`ML-DSA-65 Secret Key must be exactly ${DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES} bytes (Received: ${secretKey.length})`
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
const msgBytes = normalizeMessage(message);
|
|
73
|
-
const ctx = context ?? DILITHIUM65_CONSTANTS.DEFAULT_CONTEXT;
|
|
74
|
-
return ml_dsa65.sign(msgBytes, secretKey, { context: ctx });
|
|
75
|
-
},
|
|
76
|
-
/**
|
|
77
|
-
* Verifies an ML-DSA-65 post-quantum digital signature.
|
|
78
|
-
*/
|
|
79
|
-
verify(signature, message, publicKey, context) {
|
|
80
|
-
if (signature.length !== DILITHIUM65_CONSTANTS.SIGNATURE_BYTES) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
if (publicKey.length !== DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
const msgBytes = normalizeMessage(message);
|
|
88
|
-
const ctx = context ?? DILITHIUM65_CONSTANTS.DEFAULT_CONTEXT;
|
|
89
|
-
return ml_dsa65.verify(signature, msgBytes, publicKey, { context: ctx });
|
|
90
|
-
} catch {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
/**
|
|
95
|
-
* Signs a structured manifest (LiopManifest) using canonical JSON serialization.
|
|
96
|
-
* Returns base64-encoded signature and public key for transport over gRPC/MCP.
|
|
97
|
-
*/
|
|
98
|
-
signManifest(manifest, secretKey, publicKey) {
|
|
99
|
-
const { pqcSignature: _sig, pqcPublicKey: _pub, ...unsigned } = manifest;
|
|
100
|
-
const canonicalStr = canonicalizeJson(unsigned);
|
|
101
|
-
const sig = this.sign(canonicalStr, secretKey);
|
|
102
|
-
return {
|
|
103
|
-
signature: Buffer.from(sig).toString("base64"),
|
|
104
|
-
publicKey: Buffer.from(publicKey).toString("base64")
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
/**
|
|
108
|
-
* Verifies the post-quantum signature of a structured manifest.
|
|
109
|
-
*/
|
|
110
|
-
verifyManifest(manifest, signatureBase64, publicKeyBase64) {
|
|
111
|
-
try {
|
|
112
|
-
const sig = Buffer.from(signatureBase64, "base64");
|
|
113
|
-
const pub = Buffer.from(publicKeyBase64, "base64");
|
|
114
|
-
const { pqcSignature: _sig, pqcPublicKey: _pub, ...unsigned } = manifest;
|
|
115
|
-
const canonicalStr = canonicalizeJson(unsigned);
|
|
116
|
-
return this.verify(sig, canonicalStr, pub);
|
|
117
|
-
} catch {
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// src/security/rbac.ts
|
|
124
|
-
var SCOPE_MAP = {
|
|
125
|
-
// Protocol lifecycle — unauthenticated (MCP spec compliance)
|
|
126
|
-
initialize: [],
|
|
127
|
-
"notifications/initialized": [],
|
|
128
|
-
"notifications/cancelled": [],
|
|
129
|
-
ping: [],
|
|
130
|
-
"server/discover": [],
|
|
131
|
-
"subscriptions/listen": [],
|
|
132
|
-
// Tool operations — require explicit authorization
|
|
133
|
-
"tools/list": ["liop:tools:list"],
|
|
134
|
-
"tools/call": ["liop:tools:call"],
|
|
135
|
-
// Resource operations — read-level access
|
|
136
|
-
"resources/list": ["liop:resources:read"],
|
|
137
|
-
"resources/read": ["liop:resources:read"],
|
|
138
|
-
"resources/templates/list": ["liop:resources:read"],
|
|
139
|
-
// Prompt/schema operations — schema-level access
|
|
140
|
-
"prompts/list": ["liop:schema:read"],
|
|
141
|
-
"prompts/get": ["liop:schema:read"]
|
|
142
|
-
};
|
|
143
|
-
function authorizeRequest(method, auth, additionalScopes) {
|
|
144
|
-
const methodScopes = SCOPE_MAP[method];
|
|
145
|
-
if (methodScopes !== void 0 && methodScopes.length === 0) {
|
|
146
|
-
return { allowed: true };
|
|
147
|
-
}
|
|
148
|
-
if (!auth) {
|
|
149
|
-
return {
|
|
150
|
-
allowed: false,
|
|
151
|
-
reason: `Authentication required for method: ${method}`
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
const needed = [...methodScopes ?? [], ...additionalScopes ?? []];
|
|
155
|
-
if (needed.length === 0) {
|
|
156
|
-
return {
|
|
157
|
-
allowed: false,
|
|
158
|
-
reason: `Unknown method: ${method}. Access denied (fail-closed).`
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
const clientScopes = new Set(auth.scopes);
|
|
162
|
-
const missing = needed.filter((s) => !clientScopes.has(s));
|
|
163
|
-
if (missing.length > 0) {
|
|
164
|
-
return {
|
|
165
|
-
allowed: false,
|
|
166
|
-
reason: `Insufficient scopes for ${method}. Missing: ${missing.join(", ")}`
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
return { allowed: true };
|
|
170
|
-
}
|
|
171
|
-
var LIOP_SCOPES = [
|
|
172
|
-
"liop:tools:list",
|
|
173
|
-
"liop:tools:call",
|
|
174
|
-
"liop:resources:read",
|
|
175
|
-
"liop:schema:read",
|
|
176
|
-
"liop:mesh:query"
|
|
177
|
-
];
|
|
178
|
-
|
|
179
|
-
export { DILITHIUM65_CONSTANTS, Dilithium65Wrapper, LIOP_SCOPES, authorizeRequest };
|
|
180
|
-
//# sourceMappingURL=chunk-WPTOJYN5.js.map
|
|
181
|
-
//# sourceMappingURL=chunk-WPTOJYN5.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rpc/crypto/dilithium.ts","../src/security/rbac.ts"],"names":[],"mappings":"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","file":"chunk-WPTOJYN5.js","sourcesContent":["// Copyright 2026 Nekzus Solutions and contributors\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LIOP Post-Quantum Digital Signature Wrapper\n * Implements ML-DSA-65 (CRYSTALS-Dilithium, NIST FIPS 204) for quantum-resistant\n * manifest attestation, node revocation receipts, and cryptographic integrity.\n *\n * Characteristics:\n * - Security Category: NIST Level 3 (~AES-192 equivalent quantum resistance)\n * - Public Key Length: 1952 bytes\n * - Secret Key Length: 4032 bytes\n * - Signature Length: 3309 bytes\n * - Implementation: Pure TypeScript/JS via @noble/post-quantum\n */\n\nimport { ml_dsa65 } from \"@noble/post-quantum/ml-dsa.js\";\n\nexport const DILITHIUM65_CONSTANTS = {\n\tPUBLIC_KEY_BYTES: 1952,\n\tSECRET_KEY_BYTES: 4032,\n\tSIGNATURE_BYTES: 3309,\n\tDEFAULT_CONTEXT: new TextEncoder().encode(\"LIOP-FIPS204-ML-DSA-65\"),\n} as const;\n\n/**\n * Deterministically normalizes a message into a Uint8Array.\n */\nfunction normalizeMessage(message: Uint8Array | string): Uint8Array {\n\tif (typeof message === \"string\") {\n\t\treturn new TextEncoder().encode(message);\n\t}\n\treturn message;\n}\n\n/**\n * Deterministic canonical JSON serializer to ensure stable cryptographic hashing\n * regardless of key ordering in JavaScript objects (per RFC 8785 JCS).\n * Keys with undefined values are strictly excluded per RFC 8785 section 3.2.2.\n */\nfunction canonicalizeJson(obj: unknown): string {\n\tif (obj === null || typeof obj !== \"object\") {\n\t\treturn JSON.stringify(obj);\n\t}\n\tif (Array.isArray(obj)) {\n\t\treturn `[${obj.map(canonicalizeJson).join(\",\")}]`;\n\t}\n\tconst record = obj as Record<string, unknown>;\n\tconst sortedKeys = Object.keys(record)\n\t\t.filter((key) => record[key] !== undefined)\n\t\t.sort();\n\tconst entries = sortedKeys.map(\n\t\t(key) => `${JSON.stringify(key)}:${canonicalizeJson(record[key])}`,\n\t);\n\treturn `{${entries.join(\",\")}}`;\n}\n\nexport const Dilithium65Wrapper = {\n\t/** Constants */\n\tPUBLIC_KEY_BYTES: DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES,\n\tSECRET_KEY_BYTES: DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES,\n\tSIGNATURE_BYTES: DILITHIUM65_CONSTANTS.SIGNATURE_BYTES,\n\n\t/**\n\t * Generates a new ML-DSA-65 (FIPS 204) key pair.\n\t * Optionally accepts a 32-byte seed for deterministic key generation.\n\t */\n\tgenerateKeyPair(seed?: Uint8Array): {\n\t\tpublicKey: Uint8Array;\n\t\tsecretKey: Uint8Array;\n\t} {\n\t\tif (seed && seed.length !== 32) {\n\t\t\tthrow new Error(\n\t\t\t\t`ML-DSA-65 seed must be exactly 32 bytes (Received: ${seed.length})`,\n\t\t\t);\n\t\t}\n\t\tconst keys = ml_dsa65.keygen(seed);\n\t\treturn {\n\t\t\tpublicKey: keys.publicKey,\n\t\t\tsecretKey: keys.secretKey,\n\t\t};\n\t},\n\n\t/**\n\t * Validates and imports a raw ML-DSA-65 public key.\n\t */\n\timportPublicKey(buffer: Uint8Array): Uint8Array {\n\t\tif (buffer.length !== DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES) {\n\t\t\tthrow new Error(\n\t\t\t\t`ML-DSA-65 Public Key must be exactly ${DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES} bytes (Received: ${buffer.length})`,\n\t\t\t);\n\t\t}\n\t\treturn buffer;\n\t},\n\n\t/**\n\t * Signs a message using the post-quantum secret key.\n\t * Supports optional domain separation context (up to 255 bytes).\n\t */\n\tsign(\n\t\tmessage: Uint8Array | string,\n\t\tsecretKey: Uint8Array,\n\t\tcontext?: Uint8Array,\n\t): Uint8Array {\n\t\tif (secretKey.length !== DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES) {\n\t\t\tthrow new Error(\n\t\t\t\t`ML-DSA-65 Secret Key must be exactly ${DILITHIUM65_CONSTANTS.SECRET_KEY_BYTES} bytes (Received: ${secretKey.length})`,\n\t\t\t);\n\t\t}\n\t\tconst msgBytes = normalizeMessage(message);\n\t\tconst ctx = context ?? DILITHIUM65_CONSTANTS.DEFAULT_CONTEXT;\n\t\treturn ml_dsa65.sign(msgBytes, secretKey, { context: ctx });\n\t},\n\n\t/**\n\t * Verifies an ML-DSA-65 post-quantum digital signature.\n\t */\n\tverify(\n\t\tsignature: Uint8Array,\n\t\tmessage: Uint8Array | string,\n\t\tpublicKey: Uint8Array,\n\t\tcontext?: Uint8Array,\n\t): boolean {\n\t\tif (signature.length !== DILITHIUM65_CONSTANTS.SIGNATURE_BYTES) {\n\t\t\treturn false;\n\t\t}\n\t\tif (publicKey.length !== DILITHIUM65_CONSTANTS.PUBLIC_KEY_BYTES) {\n\t\t\treturn false;\n\t\t}\n\t\ttry {\n\t\t\tconst msgBytes = normalizeMessage(message);\n\t\t\tconst ctx = context ?? DILITHIUM65_CONSTANTS.DEFAULT_CONTEXT;\n\t\t\treturn ml_dsa65.verify(signature, msgBytes, publicKey, { context: ctx });\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t},\n\n\t/**\n\t * Signs a structured manifest (LiopManifest) using canonical JSON serialization.\n\t * Returns base64-encoded signature and public key for transport over gRPC/MCP.\n\t */\n\tsignManifest(\n\t\tmanifest: Record<string, unknown>,\n\t\tsecretKey: Uint8Array,\n\t\tpublicKey: Uint8Array,\n\t): { signature: string; publicKey: string } {\n\t\tconst { pqcSignature: _sig, pqcPublicKey: _pub, ...unsigned } = manifest;\n\t\tconst canonicalStr = canonicalizeJson(unsigned);\n\t\tconst sig = this.sign(canonicalStr, secretKey);\n\t\treturn {\n\t\t\tsignature: Buffer.from(sig).toString(\"base64\"),\n\t\t\tpublicKey: Buffer.from(publicKey).toString(\"base64\"),\n\t\t};\n\t},\n\n\t/**\n\t * Verifies the post-quantum signature of a structured manifest.\n\t */\n\tverifyManifest(\n\t\tmanifest: Record<string, unknown>,\n\t\tsignatureBase64: string,\n\t\tpublicKeyBase64: string,\n\t): boolean {\n\t\ttry {\n\t\t\tconst sig = Buffer.from(signatureBase64, \"base64\");\n\t\t\tconst pub = Buffer.from(publicKeyBase64, \"base64\");\n\t\t\tconst { pqcSignature: _sig, pqcPublicKey: _pub, ...unsigned } = manifest;\n\t\t\tconst canonicalStr = canonicalizeJson(unsigned);\n\t\t\treturn this.verify(sig, canonicalStr, pub);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t},\n};\n","// Copyright 2026 Nekzus Solutions and contributors\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * LIOP RBAC Engine — Scope-Based Authorization\n *\n * Maps MCP JSON-RPC methods to required LIOP OAuth scopes.\n * Enforces least-privilege access at the router level before\n * any tool execution or resource read occurs.\n *\n * Standards: NIST SP 800-207 §4.3 (least privilege), OWASP LLM06 (Excessive Agency),\n * OWASP API-A01 (Broken Access Control)\n */\n\nimport type { AuthInfo } from \"./jwt-validator.js\";\n\n/**\n * Maps MCP JSON-RPC methods to the LIOP scopes required to invoke them.\n * Empty array = no authentication required (public endpoints).\n */\nconst SCOPE_MAP: Readonly<Record<string, readonly string[]>> = {\n\t// Protocol lifecycle — unauthenticated (MCP spec compliance)\n\tinitialize: [],\n\t\"notifications/initialized\": [],\n\t\"notifications/cancelled\": [],\n\tping: [],\n\t\"server/discover\": [],\n\t\"subscriptions/listen\": [],\n\n\t// Tool operations — require explicit authorization\n\t\"tools/list\": [\"liop:tools:list\"],\n\t\"tools/call\": [\"liop:tools:call\"],\n\n\t// Resource operations — read-level access\n\t\"resources/list\": [\"liop:resources:read\"],\n\t\"resources/read\": [\"liop:resources:read\"],\n\t\"resources/templates/list\": [\"liop:resources:read\"],\n\n\t// Prompt/schema operations — schema-level access\n\t\"prompts/list\": [\"liop:schema:read\"],\n\t\"prompts/get\": [\"liop:schema:read\"],\n};\n\n/**\n * Authorization result with optional denial reason for audit logging.\n */\nexport interface AuthorizationResult {\n\tallowed: boolean;\n\treason?: string;\n}\n\n/**\n * Evaluates whether a request is authorized based on JWT scopes.\n *\n * Decision logic:\n * 1. Methods with no required scopes (initialize, ping) → always allowed.\n * 2. Methods with required scopes but no auth → denied.\n * 3. Methods with required scopes → all scopes must be present in the JWT.\n * 4. Unknown methods with no auth → denied (fail-closed per NIST SP 800-207).\n *\n * @param method - MCP JSON-RPC method name (e.g., \"tools/call\")\n * @param auth - Validated JWT context, or null if unauthenticated\n * @param additionalScopes - Extra scopes required by specific node configuration\n */\nexport function authorizeRequest(\n\tmethod: string,\n\tauth: AuthInfo | null,\n\tadditionalScopes?: readonly string[],\n): AuthorizationResult {\n\tconst methodScopes = SCOPE_MAP[method];\n\n\t// Methods explicitly marked as public (empty scope array) pass freely\n\tif (methodScopes !== undefined && methodScopes.length === 0) {\n\t\treturn { allowed: true };\n\t}\n\n\t// If no auth context and method requires scopes → deny\n\tif (!auth) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Authentication required for method: ${method}`,\n\t\t};\n\t}\n\n\t// Merge method-level scopes with node-level additional scopes\n\tconst needed = [...(methodScopes ?? []), ...(additionalScopes ?? [])];\n\n\t// If no scopes needed (unknown method, no additional) → fail-closed\n\tif (needed.length === 0) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Unknown method: ${method}. Access denied (fail-closed).`,\n\t\t};\n\t}\n\n\t// Verify all required scopes are present in the JWT\n\tconst clientScopes = new Set(auth.scopes);\n\tconst missing = needed.filter((s) => !clientScopes.has(s));\n\n\tif (missing.length > 0) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Insufficient scopes for ${method}. Missing: ${missing.join(\", \")}`,\n\t\t};\n\t}\n\n\treturn { allowed: true };\n}\n\n/**\n * All LIOP OAuth scopes supported by the protocol.\n * Used for PRM metadata and client registration.\n */\nexport const LIOP_SCOPES = [\n\t\"liop:tools:list\",\n\t\"liop:tools:call\",\n\t\"liop:resources:read\",\n\t\"liop:schema:read\",\n\t\"liop:mesh:query\",\n] as const;\n\nexport type LiopScope = (typeof LIOP_SCOPES)[number];\n"]}
|