@nekzus/liop 2.0.0-alpha.1 → 2.0.0-alpha.2
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/bin/agent.d.ts +0 -1
- package/dist/bin/agent.js +5 -306
- package/dist/bin/agent.js.map +1 -0
- package/dist/{bridge/stream.d.ts → bridge.d.ts} +44 -3
- package/dist/bridge.js +2 -0
- package/dist/bridge.js.map +1 -0
- package/dist/chunk-4ABAFG44.js +33 -0
- package/dist/chunk-4ABAFG44.js.map +1 -0
- package/dist/chunk-ANFXJGMP.js +2 -0
- package/dist/chunk-ANFXJGMP.js.map +1 -0
- package/dist/chunk-DBXGYHKY.js +2 -0
- package/dist/chunk-DBXGYHKY.js.map +1 -0
- package/dist/chunk-HM77MWB6.js +2 -0
- package/dist/chunk-HM77MWB6.js.map +1 -0
- package/dist/chunk-HNDVAKEK.js +24 -0
- package/dist/chunk-HNDVAKEK.js.map +1 -0
- package/dist/chunk-HQZHZM6U.js +2 -0
- package/dist/chunk-HQZHZM6U.js.map +1 -0
- package/dist/chunk-P52IE4L6.js +2 -0
- package/dist/chunk-P52IE4L6.js.map +1 -0
- package/dist/chunk-PIBCW4BD.js +13 -0
- package/dist/chunk-PIBCW4BD.js.map +1 -0
- package/dist/chunk-PPCOS2NU.js +2 -0
- package/dist/chunk-PPCOS2NU.js.map +1 -0
- package/dist/chunk-RWRRBYG4.js +2 -0
- package/dist/chunk-RWRRBYG4.js.map +1 -0
- package/dist/chunk-S6RJHZV2.js +2 -0
- package/dist/chunk-S6RJHZV2.js.map +1 -0
- package/dist/chunk-UVTEJYHN.js +2 -0
- package/dist/chunk-UVTEJYHN.js.map +1 -0
- package/dist/chunk-X6FJATUE.js +29 -0
- package/dist/chunk-X6FJATUE.js.map +1 -0
- package/dist/chunk-XLVRRGOX.js +3 -0
- package/dist/chunk-XLVRRGOX.js.map +1 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/{gateway/router.d.ts → gateway.d.ts} +30 -5
- package/dist/gateway.js +2 -0
- package/dist/gateway.js.map +1 -0
- package/dist/{client/index.d.ts → index-CyxNLlz7.d.ts} +24 -5
- package/dist/index.d.ts +313 -12
- package/dist/index.js +31 -12
- package/dist/index.js.map +1 -0
- package/dist/kyber-2WDOTUQX.js +2 -0
- package/dist/kyber-2WDOTUQX.js.map +1 -0
- package/dist/{mesh/node.d.ts → mesh.d.ts} +5 -3
- package/dist/mesh.js +2 -0
- package/dist/mesh.js.map +1 -0
- package/dist/{server/index.d.ts → server.d.ts} +125 -12
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +17 -14
- package/dist/types.js +2 -26
- package/dist/types.js.map +1 -0
- package/dist/{crypto/verifier.d.ts → verifier-DTCD9imJ.d.ts} +3 -1
- package/dist/verifier-RQRYXA4C.js +2 -0
- package/dist/verifier-RQRYXA4C.js.map +1 -0
- package/dist/workers/logic-execution.d.ts +4 -2
- package/dist/workers/logic-execution.js +2 -123
- package/dist/workers/logic-execution.js.map +1 -0
- package/dist/workers/zk-verifier.d.ts +4 -2
- package/dist/workers/zk-verifier.js +2 -98
- package/dist/workers/zk-verifier.js.map +1 -0
- package/package.json +31 -18
- package/dist/bridge/index.d.ts +0 -37
- package/dist/bridge/index.js +0 -249
- package/dist/bridge/stream.js +0 -210
- package/dist/client/index.js +0 -275
- package/dist/crypto/logic-image-id.d.ts +0 -3
- package/dist/crypto/logic-image-id.js +0 -27
- package/dist/crypto/verifier.js +0 -97
- package/dist/economy/estimator.d.ts +0 -53
- package/dist/economy/estimator.js +0 -69
- package/dist/economy/index.d.ts +0 -5
- package/dist/economy/index.js +0 -3
- package/dist/economy/otel.d.ts +0 -38
- package/dist/economy/otel.js +0 -100
- package/dist/economy/telemetry.d.ts +0 -77
- package/dist/economy/telemetry.js +0 -224
- package/dist/errors.d.ts +0 -14
- package/dist/errors.js +0 -19
- package/dist/gateway/hybrid.d.ts +0 -23
- package/dist/gateway/hybrid.js +0 -199
- package/dist/gateway/router.js +0 -1054
- package/dist/mesh/index.d.ts +0 -1
- package/dist/mesh/index.js +0 -1
- package/dist/mesh/node.js +0 -853
- package/dist/prompts/adapters.d.ts +0 -16
- package/dist/prompts/adapters.js +0 -55
- package/dist/rpc/client.d.ts +0 -22
- package/dist/rpc/client.js +0 -40
- package/dist/rpc/codec/lpm.d.ts +0 -20
- package/dist/rpc/codec/lpm.js +0 -36
- package/dist/rpc/crypto/aes.d.ts +0 -22
- package/dist/rpc/crypto/aes.js +0 -47
- package/dist/rpc/crypto/kyber.d.ts +0 -27
- package/dist/rpc/crypto/kyber.js +0 -70
- package/dist/rpc/proto.d.ts +0 -2
- package/dist/rpc/proto.js +0 -33
- package/dist/rpc/server.d.ts +0 -13
- package/dist/rpc/server.js +0 -50
- package/dist/rpc/tls.d.ts +0 -26
- package/dist/rpc/tls.js +0 -54
- package/dist/rpc/types.d.ts +0 -28
- package/dist/rpc/types.js +0 -5
- package/dist/sandbox/guardian.d.ts +0 -18
- package/dist/sandbox/guardian.js +0 -58
- package/dist/sandbox/wasi.d.ts +0 -36
- package/dist/sandbox/wasi.js +0 -233
- package/dist/security/guardian.d.ts +0 -22
- package/dist/security/guardian.js +0 -52
- package/dist/security/zk.d.ts +0 -37
- package/dist/security/zk.js +0 -76
- package/dist/server/index.js +0 -1047
- package/dist/server/ner-scanner.d.ts +0 -29
- package/dist/server/ner-scanner.js +0 -141
- package/dist/server/pii.d.ts +0 -66
- package/dist/server/pii.js +0 -428
- package/dist/utils/logger.d.ts +0 -21
- package/dist/utils/logger.js +0 -70
- package/dist/utils/mcpCompact.d.ts +0 -11
- package/dist/utils/mcpCompact.js +0 -29
package/dist/sandbox/wasi.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export interface SandboxConfig {
|
|
2
|
-
allowEnv?: boolean;
|
|
3
|
-
allowedDirectories?: Record<string, string>;
|
|
4
|
-
memoryLimitMb?: number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* LIOP WasiSandbox (Industrial Grade)
|
|
8
|
-
*
|
|
9
|
-
* Provides a production-grade isolated environment for executing untrusted logic.
|
|
10
|
-
* Primarily uses WebAssembly (WASI) for byte-code isolation, with a hardened
|
|
11
|
-
* V8 Isolate fallback for dynamic JS-to-WASM logic injection.
|
|
12
|
-
*/
|
|
13
|
-
export declare class WasiSandbox {
|
|
14
|
-
private wasi;
|
|
15
|
-
private sandboxId;
|
|
16
|
-
private workingDir;
|
|
17
|
-
private config;
|
|
18
|
-
private stdoutHandle;
|
|
19
|
-
private stderrHandle;
|
|
20
|
-
constructor(config?: SandboxConfig);
|
|
21
|
-
/**
|
|
22
|
-
* Initializes the physical sandbox environment with strict directory lockdown.
|
|
23
|
-
*/
|
|
24
|
-
init(): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Executes logic (WASM or JS-Wrapped) with hard resource limits.
|
|
27
|
-
*/
|
|
28
|
-
execute(compiledLogic: Buffer | string, records?: Record<string, unknown>[], inputs?: Record<string, unknown>): Promise<{
|
|
29
|
-
output: unknown;
|
|
30
|
-
fuelConsumed: number;
|
|
31
|
-
}>;
|
|
32
|
-
/**
|
|
33
|
-
* Physically cleans up the sandbox and releases resources.
|
|
34
|
-
*/
|
|
35
|
-
teardown(): Promise<void>;
|
|
36
|
-
}
|
package/dist/sandbox/wasi.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import * as fs from "node:fs/promises";
|
|
3
|
-
import * as os from "node:os";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
import vm from "node:vm";
|
|
6
|
-
import { WASI } from "node:wasi";
|
|
7
|
-
import { ASTGuardian } from "./guardian.js";
|
|
8
|
-
// Silence Node.js ExperimentalWarning for WASI (Industrial console parity)
|
|
9
|
-
const originalEmit = process.emit;
|
|
10
|
-
// @ts-expect-error
|
|
11
|
-
process.emit = (name, data, ...args) => {
|
|
12
|
-
if ((name === "warning" &&
|
|
13
|
-
typeof data === "object" &&
|
|
14
|
-
data.name === "ExperimentalWarning" &&
|
|
15
|
-
String(data.message).includes("WASI")) ||
|
|
16
|
-
String(data.message).includes("importing WASI")) {
|
|
17
|
-
return false;
|
|
18
|
-
}
|
|
19
|
-
return originalEmit.call(process, name, data, ...args);
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* LIOP WasiSandbox (Industrial Grade)
|
|
23
|
-
*
|
|
24
|
-
* Provides a production-grade isolated environment for executing untrusted logic.
|
|
25
|
-
* Primarily uses WebAssembly (WASI) for byte-code isolation, with a hardened
|
|
26
|
-
* V8 Isolate fallback for dynamic JS-to-WASM logic injection.
|
|
27
|
-
*/
|
|
28
|
-
export class WasiSandbox {
|
|
29
|
-
wasi;
|
|
30
|
-
sandboxId;
|
|
31
|
-
workingDir;
|
|
32
|
-
config;
|
|
33
|
-
stdoutHandle = null;
|
|
34
|
-
stderrHandle = null;
|
|
35
|
-
constructor(config = {}) {
|
|
36
|
-
this.sandboxId = crypto.randomUUID();
|
|
37
|
-
// Use a dedicated LIOP directory in the OS temp folder
|
|
38
|
-
this.workingDir = path.join(os.tmpdir(), "liop-mesh", "sandboxes", this.sandboxId);
|
|
39
|
-
this.config = config;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Initializes the physical sandbox environment with strict directory lockdown.
|
|
43
|
-
*/
|
|
44
|
-
async init() {
|
|
45
|
-
try {
|
|
46
|
-
await fs.mkdir(this.workingDir, { recursive: true });
|
|
47
|
-
// Initialize WASI with explicit limits
|
|
48
|
-
this.stdoutHandle = await fs.open(path.join(this.workingDir, "stdout.log"), "w+");
|
|
49
|
-
this.stderrHandle = await fs.open(path.join(this.workingDir, "stderr.log"), "w+");
|
|
50
|
-
this.wasi = new WASI({
|
|
51
|
-
version: "preview1",
|
|
52
|
-
args: ["liop_runtime"],
|
|
53
|
-
env: this.config.allowEnv
|
|
54
|
-
? process.env
|
|
55
|
-
: {
|
|
56
|
-
NODE_ENV: "production",
|
|
57
|
-
LIOP_NODE: "true",
|
|
58
|
-
RUNTIME_ID: this.sandboxId,
|
|
59
|
-
},
|
|
60
|
-
preopens: {
|
|
61
|
-
"/sandbox": this.workingDir,
|
|
62
|
-
...this.config.allowedDirectories,
|
|
63
|
-
},
|
|
64
|
-
stdout: this.stdoutHandle.fd,
|
|
65
|
-
stderr: this.stderrHandle.fd,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
throw new Error(`Sandbox Initialization Failed: ${error instanceof Error ? error.message : "FS Error"}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Executes logic (WASM or JS-Wrapped) with hard resource limits.
|
|
74
|
-
*/
|
|
75
|
-
async execute(compiledLogic, records = [], inputs = {}) {
|
|
76
|
-
const startTime = performance.now();
|
|
77
|
-
if (compiledLogic instanceof Buffer) {
|
|
78
|
-
// Path A: Native WebAssembly Isolation
|
|
79
|
-
try {
|
|
80
|
-
const module = await WebAssembly.compile(new Uint8Array(compiledLogic));
|
|
81
|
-
// Tier-0 Guardian: Static analysis to prevent sandbox escapes
|
|
82
|
-
ASTGuardian.analyze(module);
|
|
83
|
-
const instance = await WebAssembly.instantiate(module, this.wasi.getImportObject());
|
|
84
|
-
// Standard entry point
|
|
85
|
-
this.wasi.start(instance);
|
|
86
|
-
// Capture output from the sandbox
|
|
87
|
-
const stdoutPath = path.join(this.workingDir, "stdout.log");
|
|
88
|
-
const stderrPath = path.join(this.workingDir, "stderr.log");
|
|
89
|
-
const stdout = await fs.readFile(stdoutPath, "utf-8");
|
|
90
|
-
const stderr = await fs.readFile(stderrPath, "utf-8");
|
|
91
|
-
const duration = performance.now() - startTime;
|
|
92
|
-
return {
|
|
93
|
-
output: stdout || (stderr ? `Error: ${stderr}` : "WASM_EXECUTION_SUCCESS"),
|
|
94
|
-
fuelConsumed: Math.floor(duration * 1000),
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
throw new Error(`WASM Runtime Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
// Path B: Hardened V8 Isolate Fallback
|
|
103
|
-
// Uses node:vm with zero-prototype objects to prevent prototype pollution escapes.
|
|
104
|
-
// biome-ignore lint/suspicious/noExplicitAny: Required for Sandbox global poisoning
|
|
105
|
-
const sandboxEnv = Object.create(null); // Isolated global object
|
|
106
|
-
const env = { records, ...inputs };
|
|
107
|
-
// Explicitly poison Node.js escape vectors in the context
|
|
108
|
-
sandboxEnv.require = undefined;
|
|
109
|
-
sandboxEnv.process = undefined;
|
|
110
|
-
sandboxEnv.global = undefined;
|
|
111
|
-
sandboxEnv.globalThis = undefined;
|
|
112
|
-
sandboxEnv.Buffer = undefined;
|
|
113
|
-
sandboxEnv.setTimeout = undefined;
|
|
114
|
-
sandboxEnv.setInterval = undefined;
|
|
115
|
-
sandboxEnv.setImmediate = undefined;
|
|
116
|
-
sandboxEnv.queueMicrotask = undefined;
|
|
117
|
-
sandboxEnv.eval = undefined;
|
|
118
|
-
sandboxEnv.Function = undefined;
|
|
119
|
-
sandboxEnv.SharedArrayBuffer = undefined;
|
|
120
|
-
sandboxEnv.Date = undefined;
|
|
121
|
-
// [DoS Defense] Block off-heap memory allocation vectors.
|
|
122
|
-
// Logic-on-Origin operates on JSON data (env.records) — binary buffers
|
|
123
|
-
// serve no legitimate purpose and enable memory exhaustion DoS.
|
|
124
|
-
// (Uint8Array(2GB) bypassed Piscina's maxOldGenerationSizeMb limit)
|
|
125
|
-
sandboxEnv.ArrayBuffer = undefined;
|
|
126
|
-
sandboxEnv.Uint8Array = undefined;
|
|
127
|
-
sandboxEnv.Int8Array = undefined;
|
|
128
|
-
sandboxEnv.Uint16Array = undefined;
|
|
129
|
-
sandboxEnv.Int16Array = undefined;
|
|
130
|
-
sandboxEnv.Uint32Array = undefined;
|
|
131
|
-
sandboxEnv.Int32Array = undefined;
|
|
132
|
-
sandboxEnv.Float32Array = undefined;
|
|
133
|
-
sandboxEnv.Float64Array = undefined;
|
|
134
|
-
sandboxEnv.BigInt64Array = undefined;
|
|
135
|
-
sandboxEnv.BigUint64Array = undefined;
|
|
136
|
-
sandboxEnv.DataView = undefined;
|
|
137
|
-
// Inject strictly monitored globals
|
|
138
|
-
sandboxEnv.records = JSON.parse(JSON.stringify(records)); // Deep copy safety
|
|
139
|
-
sandboxEnv.env = JSON.parse(JSON.stringify(env));
|
|
140
|
-
for (const [key, value] of Object.entries(inputs)) {
|
|
141
|
-
sandboxEnv[key] = JSON.parse(JSON.stringify(value));
|
|
142
|
-
}
|
|
143
|
-
// Freeze the sandbox context to prevent mutation (SEC-GAP-1)
|
|
144
|
-
// biome-ignore lint/suspicious/noExplicitAny: Required for recursive deep freeze of unknown data
|
|
145
|
-
const deepFreeze = (obj) => {
|
|
146
|
-
if (obj && typeof obj === "object" && !Object.isFrozen(obj)) {
|
|
147
|
-
Object.freeze(obj);
|
|
148
|
-
for (const key of Object.keys(obj)) {
|
|
149
|
-
deepFreeze(obj[key]);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return obj;
|
|
153
|
-
};
|
|
154
|
-
deepFreeze(sandboxEnv.records);
|
|
155
|
-
deepFreeze(sandboxEnv.env);
|
|
156
|
-
// Prevent property addition/modification on global scope
|
|
157
|
-
for (const key of Object.keys(sandboxEnv)) {
|
|
158
|
-
Object.defineProperty(sandboxEnv, key, {
|
|
159
|
-
writable: false,
|
|
160
|
-
configurable: false,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
// LIOP Execution Wrapper
|
|
164
|
-
// Host-side logic transformation to avoid 'new Function' in sandbox
|
|
165
|
-
let processedLogic = String(compiledLogic);
|
|
166
|
-
if (/^\s*return\s/m.test(processedLogic) ||
|
|
167
|
-
!processedLogic.includes("function liop_main")) {
|
|
168
|
-
if (!processedLogic.includes("function liop_main")) {
|
|
169
|
-
processedLogic = `function liop_main(env) {\n${processedLogic}\n}`;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const scriptCode = `
|
|
173
|
-
(function() {
|
|
174
|
-
try {
|
|
175
|
-
Object.freeze(Object.prototype);
|
|
176
|
-
Object.freeze(Array.prototype);
|
|
177
|
-
Object.freeze(String.prototype);
|
|
178
|
-
Object.freeze(Number.prototype);
|
|
179
|
-
Object.freeze(Boolean.prototype);
|
|
180
|
-
Object.freeze(Object.getPrototypeOf(function(){}));
|
|
181
|
-
|
|
182
|
-
${processedLogic}
|
|
183
|
-
if (typeof liop_main === 'function') {
|
|
184
|
-
return liop_main(env);
|
|
185
|
-
}
|
|
186
|
-
return "ERR_NO_ENTRY_POINT";
|
|
187
|
-
} catch(e) {
|
|
188
|
-
return "LogicError: " + e.message;
|
|
189
|
-
}
|
|
190
|
-
})();
|
|
191
|
-
`;
|
|
192
|
-
try {
|
|
193
|
-
const script = new vm.Script(scriptCode, {
|
|
194
|
-
filename: `liop-sandbox-${this.sandboxId.slice(0, 8)}.js`,
|
|
195
|
-
});
|
|
196
|
-
const context = vm.createContext(sandboxEnv, {
|
|
197
|
-
name: "LIOP Isolate",
|
|
198
|
-
origin: "liop://sandbox",
|
|
199
|
-
});
|
|
200
|
-
// Execution with hard CPU and Memory limits (Fuel)
|
|
201
|
-
const output = script.runInContext(context, {
|
|
202
|
-
timeout: 5000,
|
|
203
|
-
breakOnSigint: true,
|
|
204
|
-
displayErrors: true,
|
|
205
|
-
});
|
|
206
|
-
const duration = performance.now() - startTime;
|
|
207
|
-
const fuelUsed = Math.floor(duration * 1500 + 100);
|
|
208
|
-
if (fuelUsed > 1000000) {
|
|
209
|
-
throw new Error("LIOP_RESOURCE_EXHAUSTED: Execution fuel limit exceeded.");
|
|
210
|
-
}
|
|
211
|
-
return { output, fuelConsumed: fuelUsed };
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
throw new Error(`V8 Isolate Fault: ${error instanceof Error ? error.message : "Execution Timeout"}`);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Physically cleans up the sandbox and releases resources.
|
|
220
|
-
*/
|
|
221
|
-
async teardown() {
|
|
222
|
-
try {
|
|
223
|
-
if (this.stdoutHandle)
|
|
224
|
-
await this.stdoutHandle.close();
|
|
225
|
-
if (this.stderrHandle)
|
|
226
|
-
await this.stderrHandle.close();
|
|
227
|
-
await fs.rm(this.workingDir, { recursive: true, force: true });
|
|
228
|
-
}
|
|
229
|
-
catch (_e) {
|
|
230
|
-
// Silent fail on teardown to prevent process crashes
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents a violation of the LIOP Zero-Trust Sandbox policy.
|
|
3
|
-
*/
|
|
4
|
-
export declare class GuardianViolationError extends Error {
|
|
5
|
-
constructor(message: string);
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* LIOP Guardian-TS (TypeScript Validator)
|
|
9
|
-
* Emulates the zero-time AST inspection done by `wasmparser` in Rust.
|
|
10
|
-
* Scans the WebAssembly module imports before instantiation to prevent
|
|
11
|
-
* sandbox escapes and limits execution strictly to WASI and LIOP APIs.
|
|
12
|
-
*/
|
|
13
|
-
export declare const GuardianTS: {
|
|
14
|
-
/**
|
|
15
|
-
* Scans raw WASM bytes to ensure 100% compliance with LIOP Logic-on-Origin boundaries.
|
|
16
|
-
*
|
|
17
|
-
* @param wasmBytes The raw compiled `.wasm` buffer to inspect
|
|
18
|
-
* @returns A parsed WebAssembly.Module proven safe for sandboxed execution
|
|
19
|
-
* @throws {GuardianViolationError} If forbidden host imports are detected
|
|
20
|
-
*/
|
|
21
|
-
analyzeAst(wasmBytes: Uint8Array | Buffer): Promise<WebAssembly.Module>;
|
|
22
|
-
};
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { log } from "../utils/logger.js";
|
|
2
|
-
/**
|
|
3
|
-
* Represents a violation of the LIOP Zero-Trust Sandbox policy.
|
|
4
|
-
*/
|
|
5
|
-
export class GuardianViolationError extends Error {
|
|
6
|
-
constructor(message) {
|
|
7
|
-
super(`[AST Security Violation]: ${message}`);
|
|
8
|
-
this.name = "GuardianViolationError";
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* LIOP Guardian-TS (TypeScript Validator)
|
|
13
|
-
* Emulates the zero-time AST inspection done by `wasmparser` in Rust.
|
|
14
|
-
* Scans the WebAssembly module imports before instantiation to prevent
|
|
15
|
-
* sandbox escapes and limits execution strictly to WASI and LIOP APIs.
|
|
16
|
-
*/
|
|
17
|
-
export const GuardianTS = {
|
|
18
|
-
/**
|
|
19
|
-
* Scans raw WASM bytes to ensure 100% compliance with LIOP Logic-on-Origin boundaries.
|
|
20
|
-
*
|
|
21
|
-
* @param wasmBytes The raw compiled `.wasm` buffer to inspect
|
|
22
|
-
* @returns A parsed WebAssembly.Module proven safe for sandboxed execution
|
|
23
|
-
* @throws {GuardianViolationError} If forbidden host imports are detected
|
|
24
|
-
*/
|
|
25
|
-
async analyzeAst(wasmBytes) {
|
|
26
|
-
log.info("[Guardian-TS] Starting Zero-Time AST heuristic inspection...");
|
|
27
|
-
// This throws if the WASM is structurally invalid or a decompression bomb
|
|
28
|
-
let module;
|
|
29
|
-
try {
|
|
30
|
-
// Convert Node Buffer to a raw Uint8Array pure BufferSource
|
|
31
|
-
const bufferSource = new Uint8Array(wasmBytes);
|
|
32
|
-
module = await WebAssembly.compile(bufferSource);
|
|
33
|
-
}
|
|
34
|
-
catch (e) {
|
|
35
|
-
throw new GuardianViolationError(`Payload structurally invalid or potential bomb: ${e.message}`);
|
|
36
|
-
}
|
|
37
|
-
// Heuristic Import Scanning
|
|
38
|
-
// Extract all imported functions/memories from the AST
|
|
39
|
-
const imports = WebAssembly.Module.imports(module);
|
|
40
|
-
let importCount = 0;
|
|
41
|
-
for (const imp of imports) {
|
|
42
|
-
// Strict Sandbox Validation: Only allow WASI preview 1 and native LIOP functions.
|
|
43
|
-
// Reject any custom or unexpected host imports (e.g. `env.shell_exec`, `fs.open`).
|
|
44
|
-
if (imp.module !== "wasi_snapshot_preview1" && imp.module !== "LIOP") {
|
|
45
|
-
throw new GuardianViolationError(`Banned Host Import Detected: ${imp.module}/${imp.name}`);
|
|
46
|
-
}
|
|
47
|
-
importCount++;
|
|
48
|
-
}
|
|
49
|
-
log.info(`[Guardian-TS] OK: AST clean. Validated ${importCount} WASI/LIOP imports.`);
|
|
50
|
-
return module;
|
|
51
|
-
},
|
|
52
|
-
};
|
package/dist/security/zk.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export interface ZkReceipt {
|
|
2
|
-
/** Cryptographic proof generated by a zero-knowledge VM (e.g., RISC Zero, SP1) */
|
|
3
|
-
proof: Buffer;
|
|
4
|
-
/** The public inputs/outputs of the execution (the "Journal" in RISC Zero terminology) */
|
|
5
|
-
journal: Buffer;
|
|
6
|
-
/** The expected image ID / verification key of the WASM binary that was executed */
|
|
7
|
-
imageId: Buffer;
|
|
8
|
-
}
|
|
9
|
-
export declare class ZkVerificationError extends Error {
|
|
10
|
-
constructor(message: string);
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* ZK-Proofs Verifier for Logic-Injection-on-Origin Protocol (LIOP)
|
|
14
|
-
*
|
|
15
|
-
* Validates that an executed Logic (WASM) actually produced the reported output,
|
|
16
|
-
* verifying the Zero-Knowledge receipt generated by the remote host's Trusted Execution
|
|
17
|
-
* Environment (TEE) or zkVM (Zero-Knowledge Virtual Machine).
|
|
18
|
-
*/
|
|
19
|
-
export declare const ZkVerifier: {
|
|
20
|
-
/**
|
|
21
|
-
* Validates a ZK receipt using structural Binary Receipt verification.
|
|
22
|
-
* Parses the HMAC-SHA256 commitment format (v1) and verifies journal integrity.
|
|
23
|
-
*
|
|
24
|
-
* @param receipt - Complete ZkReceipt to verify
|
|
25
|
-
* @param expectedImageId - Hash or ImageID of the WASM file dispatched to the host
|
|
26
|
-
* @throws ZkVerificationError if the proof is invalid or image IDs mismatch
|
|
27
|
-
* @returns true if the proof mathematically verifies the execution
|
|
28
|
-
*/
|
|
29
|
-
verify(receipt: ZkReceipt, expectedImageId: Buffer, sessionSecret?: Buffer): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Derives a predictable ImageID (usually a Hash) from a raw WASM binary.
|
|
32
|
-
*
|
|
33
|
-
* @param wasmBytes - The raw bytes of the WASM logic file
|
|
34
|
-
* @returns The SHA-256 ImageID of the logic
|
|
35
|
-
*/
|
|
36
|
-
deriveImageId(wasmBytes: Buffer): Buffer;
|
|
37
|
-
};
|
package/dist/security/zk.js
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
export class ZkVerificationError extends Error {
|
|
3
|
-
constructor(message) {
|
|
4
|
-
super(`ZK Verification Failed: ${message}`);
|
|
5
|
-
this.name = "ZkVerificationError";
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* ZK-Proofs Verifier for Logic-Injection-on-Origin Protocol (LIOP)
|
|
10
|
-
*
|
|
11
|
-
* Validates that an executed Logic (WASM) actually produced the reported output,
|
|
12
|
-
* verifying the Zero-Knowledge receipt generated by the remote host's Trusted Execution
|
|
13
|
-
* Environment (TEE) or zkVM (Zero-Knowledge Virtual Machine).
|
|
14
|
-
*/
|
|
15
|
-
export const ZkVerifier = {
|
|
16
|
-
/**
|
|
17
|
-
* Validates a ZK receipt using structural Binary Receipt verification.
|
|
18
|
-
* Parses the HMAC-SHA256 commitment format (v1) and verifies journal integrity.
|
|
19
|
-
*
|
|
20
|
-
* @param receipt - Complete ZkReceipt to verify
|
|
21
|
-
* @param expectedImageId - Hash or ImageID of the WASM file dispatched to the host
|
|
22
|
-
* @throws ZkVerificationError if the proof is invalid or image IDs mismatch
|
|
23
|
-
* @returns true if the proof mathematically verifies the execution
|
|
24
|
-
*/
|
|
25
|
-
verify(receipt, expectedImageId, sessionSecret) {
|
|
26
|
-
// 1. Verify Image ID (Ensures the host executed the exact logic we sent, not a malicious one)
|
|
27
|
-
if (!receipt.imageId.equals(expectedImageId)) {
|
|
28
|
-
throw new ZkVerificationError("ImageID mismatch. The remote origin executed a different WASM payload.");
|
|
29
|
-
}
|
|
30
|
-
// 2. Validate Proof Structure
|
|
31
|
-
if (receipt.proof.length === 0) {
|
|
32
|
-
throw new ZkVerificationError("Empty or malformed zero-knowledge proof array.");
|
|
33
|
-
}
|
|
34
|
-
// 3. Cryptographic Validation (Binary Receipt)
|
|
35
|
-
const proofBuf = Buffer.from(receipt.proof);
|
|
36
|
-
if (proofBuf.length < 35 || proofBuf[0] !== 0x01) {
|
|
37
|
-
throw new ZkVerificationError("Malformed receipt: invalid header or length.");
|
|
38
|
-
}
|
|
39
|
-
const journalLen = proofBuf.readUInt16BE(1);
|
|
40
|
-
const journal = proofBuf.subarray(3, 3 + journalLen);
|
|
41
|
-
const seal = proofBuf.subarray(3 + journalLen);
|
|
42
|
-
if (seal.length !== 32) {
|
|
43
|
-
throw new ZkVerificationError("Invalid seal: expected 32-byte HMAC-SHA256.");
|
|
44
|
-
}
|
|
45
|
-
// Verify journal contains matching imageId
|
|
46
|
-
try {
|
|
47
|
-
const journalData = JSON.parse(journal.toString());
|
|
48
|
-
if (journalData.image_id !== receipt.imageId.toString("hex")) {
|
|
49
|
-
throw new ZkVerificationError("Journal imageId does not match receipt header.");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch (_e) {
|
|
53
|
-
throw new ZkVerificationError("Failed to parse journal data.");
|
|
54
|
-
}
|
|
55
|
-
// 4. Mathematical Verification (HMAC-SHA256)
|
|
56
|
-
if (sessionSecret && sessionSecret.length > 0) {
|
|
57
|
-
const expectedSeal = crypto
|
|
58
|
-
.createHmac("sha256", sessionSecret)
|
|
59
|
-
.update(journal)
|
|
60
|
-
.digest();
|
|
61
|
-
if (!crypto.timingSafeEqual(seal, expectedSeal)) {
|
|
62
|
-
throw new ZkVerificationError("Invalid seal: HMAC verification failed.");
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return true;
|
|
66
|
-
},
|
|
67
|
-
/**
|
|
68
|
-
* Derives a predictable ImageID (usually a Hash) from a raw WASM binary.
|
|
69
|
-
*
|
|
70
|
-
* @param wasmBytes - The raw bytes of the WASM logic file
|
|
71
|
-
* @returns The SHA-256 ImageID of the logic
|
|
72
|
-
*/
|
|
73
|
-
deriveImageId(wasmBytes) {
|
|
74
|
-
return crypto.createHash("sha256").update(wasmBytes).digest();
|
|
75
|
-
},
|
|
76
|
-
};
|