@enactprotocol/shared 1.2.8 → 1.2.9
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/api/enact-api.d.ts +2 -1
- package/dist/api/enact-api.js +7 -0
- package/dist/api/types.d.ts +12 -0
- package/dist/core/EnactCore.d.ts +2 -0
- package/dist/core/EnactCore.js +53 -21
- package/package.json +1 -1
- package/src/api/enact-api.ts +15 -0
- package/src/api/types.ts +13 -0
- package/src/core/EnactCore.ts +64 -30
package/dist/api/enact-api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EnactToolDefinition, ToolUsage, ToolSearchQuery, CLITokenCreate, OAuthTokenExchange } from "./types";
|
|
1
|
+
import { EnactToolDefinition, ToolSignaturePayload, ToolUsage, ToolSearchQuery, CLITokenCreate, OAuthTokenExchange } from "./types";
|
|
2
2
|
export declare class EnactApiClient {
|
|
3
3
|
baseUrl: string;
|
|
4
4
|
supabaseUrl: string;
|
|
@@ -100,6 +100,7 @@ export declare class EnactApiClient {
|
|
|
100
100
|
* Get a user's public key
|
|
101
101
|
*/
|
|
102
102
|
getUserPublicKey(userId: string): Promise<any>;
|
|
103
|
+
signTool(toolId: string, payload: ToolSignaturePayload, token: string, tokenType?: "jwt" | "cli"): Promise<any>;
|
|
103
104
|
/**
|
|
104
105
|
* Generate OAuth authorization URL
|
|
105
106
|
*/
|
package/dist/api/enact-api.js
CHANGED
|
@@ -343,6 +343,13 @@ export class EnactApiClient {
|
|
|
343
343
|
throw new EnactApiError("Unknown error occurred", 0);
|
|
344
344
|
}
|
|
345
345
|
}
|
|
346
|
+
async signTool(toolId, payload, token, tokenType = "cli") {
|
|
347
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(toolId)}/signatures`;
|
|
348
|
+
return this.makeRequest(endpoint, {
|
|
349
|
+
method: "POST",
|
|
350
|
+
body: JSON.stringify(payload),
|
|
351
|
+
}, token, tokenType);
|
|
352
|
+
}
|
|
346
353
|
// ===================
|
|
347
354
|
// OAUTH FLOW HELPERS
|
|
348
355
|
// ===================
|
package/dist/api/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface EnactToolDefinition {
|
|
2
2
|
name: string;
|
|
3
3
|
description: string;
|
|
4
|
+
verified?: boolean;
|
|
4
5
|
command: string;
|
|
5
6
|
from?: string;
|
|
6
7
|
version?: string;
|
|
@@ -89,3 +90,14 @@ export interface EnactExecOptions {
|
|
|
89
90
|
dangerouslySkipVerification?: boolean;
|
|
90
91
|
mount?: string;
|
|
91
92
|
}
|
|
93
|
+
export interface ToolSignaturePayload {
|
|
94
|
+
algorithm: "sha256";
|
|
95
|
+
created: string;
|
|
96
|
+
key_id: string;
|
|
97
|
+
public_key: string;
|
|
98
|
+
role: "author";
|
|
99
|
+
signer: string;
|
|
100
|
+
timestamp: number;
|
|
101
|
+
type: "ecdsa-p256";
|
|
102
|
+
value: string;
|
|
103
|
+
}
|
package/dist/core/EnactCore.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EnactTool, ExecutionResult } from "../types.js";
|
|
2
|
+
import { EnactToolDefinition } from "../api/types.js";
|
|
2
3
|
export interface EnactCoreOptions {
|
|
3
4
|
apiUrl?: string;
|
|
4
5
|
supabaseUrl?: string;
|
|
@@ -67,6 +68,7 @@ export declare class EnactCore {
|
|
|
67
68
|
* Execute a tool by name
|
|
68
69
|
*/
|
|
69
70
|
executeToolByName(name: string, inputs?: Record<string, any>, options?: ToolExecuteOptions): Promise<ExecutionResult>;
|
|
71
|
+
static checkToolVerificationStatus(tool: EnactToolDefinition): Promise<boolean>;
|
|
70
72
|
private verifyTool;
|
|
71
73
|
/**
|
|
72
74
|
* Execute a tool directly
|
package/dist/core/EnactCore.js
CHANGED
|
@@ -5,7 +5,7 @@ import { DaggerExecutionProvider } from "./DaggerExecutionProvider.js";
|
|
|
5
5
|
import { resolveToolEnvironmentVariables } from "../utils/env-loader.js";
|
|
6
6
|
import logger from "../exec/logger.js";
|
|
7
7
|
import yaml from "yaml";
|
|
8
|
-
import {
|
|
8
|
+
import { SecurityConfigManager, SigningService } from "@enactprotocol/security";
|
|
9
9
|
import { getFrontendUrl, getApiUrl } from "../utils/config";
|
|
10
10
|
export class EnactCore {
|
|
11
11
|
constructor(options = {}) {
|
|
@@ -278,6 +278,33 @@ export class EnactCore {
|
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
+
static async checkToolVerificationStatus(tool) {
|
|
282
|
+
const documentForVerification = {
|
|
283
|
+
command: tool.command,
|
|
284
|
+
description: tool.description,
|
|
285
|
+
from: tool.from,
|
|
286
|
+
name: tool.name,
|
|
287
|
+
signatures: tool.signatures?.map(sig => ({
|
|
288
|
+
signature: sig.value,
|
|
289
|
+
publicKey: "", // TODO: Look up the correct public key
|
|
290
|
+
algorithm: sig.algorithm,
|
|
291
|
+
timestamp: new Date(sig.created).getTime(),
|
|
292
|
+
})),
|
|
293
|
+
};
|
|
294
|
+
let isValid = false;
|
|
295
|
+
if (tool.signatures && tool.signatures.length > 0) {
|
|
296
|
+
isValid = tool.signatures.some(sig => {
|
|
297
|
+
const referenceSignature = {
|
|
298
|
+
signature: sig.value,
|
|
299
|
+
publicKey: "", // TODO: Lookup correct public key based on signature UUID
|
|
300
|
+
algorithm: sig.algorithm,
|
|
301
|
+
timestamp: new Date(sig.created).getTime()
|
|
302
|
+
};
|
|
303
|
+
return SigningService.verifyDocument(documentForVerification, referenceSignature, { includeFields: ['command', 'description', 'from', 'name'] });
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return isValid;
|
|
307
|
+
}
|
|
281
308
|
async verifyTool(tool, dangerouslySkipVerification = false) {
|
|
282
309
|
if (dangerouslySkipVerification) {
|
|
283
310
|
logger.warn(`Skipping signature verification for tool: ${tool.name}`);
|
|
@@ -287,28 +314,33 @@ export class EnactCore {
|
|
|
287
314
|
if (!tool.signatures || tool.signatures.length === 0) {
|
|
288
315
|
throw new Error(`Tool ${tool.name} does not have any signatures`);
|
|
289
316
|
}
|
|
290
|
-
const documentForVerification = {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
};
|
|
296
|
-
const referenceSignature = {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
};
|
|
302
|
-
// Check what canonical document looks like
|
|
303
|
-
const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification,
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
//
|
|
307
|
-
|
|
317
|
+
// const documentForVerification = {
|
|
318
|
+
// command: tool.command,
|
|
319
|
+
// description: tool.description,
|
|
320
|
+
// from: tool.from,
|
|
321
|
+
// name: tool.name,
|
|
322
|
+
// };
|
|
323
|
+
// const referenceSignature = {
|
|
324
|
+
// signature: tool.signatures[0].value,
|
|
325
|
+
// publicKey: "", // Correct public key for UUID 71e02e2c-148c-4534-9900-bd9646e99333
|
|
326
|
+
// algorithm: tool.signatures[0].algorithm,
|
|
327
|
+
// timestamp: new Date(tool.signatures[0].created).getTime()
|
|
328
|
+
// };
|
|
329
|
+
// // Check what canonical document looks like
|
|
330
|
+
// const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command', 'description', 'from', 'name'] }
|
|
331
|
+
// );
|
|
332
|
+
// const docString = JSON.stringify(canonicalDoc);
|
|
333
|
+
// const messageHash = CryptoUtils.hash(docString);
|
|
334
|
+
// // Test direct crypto verification
|
|
335
|
+
// const directVerify = CryptoUtils.verify(
|
|
336
|
+
// referenceSignature.publicKey,
|
|
337
|
+
// messageHash,
|
|
338
|
+
// referenceSignature.signature
|
|
339
|
+
// );
|
|
308
340
|
// Check trusted keys
|
|
309
341
|
// const trustedKeys = KeyManager.getAllTrustedPublicKeys();
|
|
310
|
-
const isValid =
|
|
311
|
-
|
|
342
|
+
const isValid = await EnactCore.checkToolVerificationStatus(tool);
|
|
343
|
+
console.log("Final verification result:", isValid);
|
|
312
344
|
if (!isValid) {
|
|
313
345
|
throw new Error(`Tool ${tool.name} has invalid signatures`);
|
|
314
346
|
}
|
package/package.json
CHANGED
package/src/api/enact-api.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EnactToolDefinition,
|
|
3
|
+
ToolSignaturePayload,
|
|
3
4
|
ToolUsage,
|
|
4
5
|
ToolSearchQuery,
|
|
5
6
|
CLITokenCreate,
|
|
@@ -480,6 +481,20 @@ export class EnactApiClient {
|
|
|
480
481
|
throw new EnactApiError("Unknown error occurred", 0);
|
|
481
482
|
}
|
|
482
483
|
}
|
|
484
|
+
|
|
485
|
+
async signTool(
|
|
486
|
+
toolId: string,
|
|
487
|
+
payload: ToolSignaturePayload,
|
|
488
|
+
token: string,
|
|
489
|
+
tokenType: "jwt" | "cli" = "cli"
|
|
490
|
+
): Promise<any> {
|
|
491
|
+
const endpoint = `/functions/v1/tools/${encodeURIComponent(toolId)}/signatures`;
|
|
492
|
+
|
|
493
|
+
return this.makeRequest(endpoint, {
|
|
494
|
+
method: "POST",
|
|
495
|
+
body: JSON.stringify(payload),
|
|
496
|
+
}, token, tokenType);
|
|
497
|
+
}
|
|
483
498
|
|
|
484
499
|
// ===================
|
|
485
500
|
// OAUTH FLOW HELPERS
|
package/src/api/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface EnactToolDefinition {
|
|
2
2
|
name: string;
|
|
3
3
|
description: string;
|
|
4
|
+
verified?: boolean; // Indicates if the tool has been verified
|
|
4
5
|
command: string;
|
|
5
6
|
from?: string;
|
|
6
7
|
version?: string;
|
|
@@ -99,3 +100,15 @@ export interface EnactExecOptions {
|
|
|
99
100
|
dangerouslySkipVerification?: boolean; // Skip all signature verification (DANGEROUS)
|
|
100
101
|
mount?: string; // Mount local directory to container (format: "local:container")
|
|
101
102
|
}
|
|
103
|
+
|
|
104
|
+
export interface ToolSignaturePayload {
|
|
105
|
+
algorithm: "sha256";
|
|
106
|
+
created: string; // Time of signing
|
|
107
|
+
key_id: string; // ID of the private key
|
|
108
|
+
public_key: string; // The corresponding public key
|
|
109
|
+
role: "author";
|
|
110
|
+
signer: string; // The userID of the signer
|
|
111
|
+
timestamp: number;
|
|
112
|
+
type: "ecdsa-p256";
|
|
113
|
+
value: string; // Signature
|
|
114
|
+
}
|
package/src/core/EnactCore.ts
CHANGED
|
@@ -19,6 +19,7 @@ import fs from "fs";
|
|
|
19
19
|
import path from "path";
|
|
20
20
|
import { CryptoUtils, KeyManager, SecurityConfigManager, SigningService } from "@enactprotocol/security";
|
|
21
21
|
import { getFrontendUrl, getApiUrl } from "../utils/config";
|
|
22
|
+
import { EnactToolDefinition } from "../api/types.js";
|
|
22
23
|
|
|
23
24
|
export interface EnactCoreOptions {
|
|
24
25
|
apiUrl?: string;
|
|
@@ -408,6 +409,43 @@ export class EnactCore {
|
|
|
408
409
|
}
|
|
409
410
|
}
|
|
410
411
|
|
|
412
|
+
public static async checkToolVerificationStatus(tool: EnactToolDefinition): Promise<boolean> {
|
|
413
|
+
const documentForVerification = {
|
|
414
|
+
command: tool.command,
|
|
415
|
+
description: tool.description,
|
|
416
|
+
from: tool.from,
|
|
417
|
+
name: tool.name,
|
|
418
|
+
signatures: tool.signatures?.map(sig => ({
|
|
419
|
+
signature: sig.value,
|
|
420
|
+
publicKey: "", // TODO: Look up the correct public key
|
|
421
|
+
algorithm: sig.algorithm,
|
|
422
|
+
timestamp: new Date(sig.created).getTime(),
|
|
423
|
+
})),
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
let isValid = false;
|
|
427
|
+
|
|
428
|
+
if (tool.signatures && tool.signatures.length > 0) {
|
|
429
|
+
isValid = tool.signatures.some(sig => {
|
|
430
|
+
const referenceSignature = {
|
|
431
|
+
signature: sig.value,
|
|
432
|
+
publicKey: "", // TODO: Lookup correct public key based on signature UUID
|
|
433
|
+
algorithm: sig.algorithm,
|
|
434
|
+
timestamp: new Date(sig.created).getTime()
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
return SigningService.verifyDocument(
|
|
438
|
+
documentForVerification,
|
|
439
|
+
referenceSignature,
|
|
440
|
+
{ includeFields: ['command', 'description', 'from', 'name'] }
|
|
441
|
+
);
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return isValid;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
|
|
411
449
|
private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean = false): Promise<void> {
|
|
412
450
|
if (dangerouslySkipVerification) {
|
|
413
451
|
logger.warn(`Skipping signature verification for tool: ${tool.name}`);
|
|
@@ -419,46 +457,42 @@ private async verifyTool(tool: EnactTool, dangerouslySkipVerification: boolean =
|
|
|
419
457
|
throw new Error(`Tool ${tool.name} does not have any signatures`);
|
|
420
458
|
}
|
|
421
459
|
|
|
422
|
-
const documentForVerification = {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
const referenceSignature = {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
460
|
+
// const documentForVerification = {
|
|
461
|
+
// command: tool.command,
|
|
462
|
+
// description: tool.description,
|
|
463
|
+
// from: tool.from,
|
|
464
|
+
// name: tool.name,
|
|
465
|
+
// };
|
|
466
|
+
|
|
467
|
+
// const referenceSignature = {
|
|
468
|
+
// signature: tool.signatures[0].value,
|
|
469
|
+
// publicKey: "", // Correct public key for UUID 71e02e2c-148c-4534-9900-bd9646e99333
|
|
470
|
+
// algorithm: tool.signatures[0].algorithm,
|
|
471
|
+
// timestamp: new Date(tool.signatures[0].created).getTime()
|
|
472
|
+
// };
|
|
435
473
|
|
|
436
474
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
);
|
|
475
|
+
// // Check what canonical document looks like
|
|
476
|
+
// const canonicalDoc = SigningService.getCanonicalDocument(documentForVerification, { includeFields: ['command', 'description', 'from', 'name'] }
|
|
477
|
+
// );
|
|
440
478
|
|
|
441
|
-
|
|
442
|
-
|
|
479
|
+
// const docString = JSON.stringify(canonicalDoc);
|
|
480
|
+
// const messageHash = CryptoUtils.hash(docString);
|
|
443
481
|
|
|
444
482
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
483
|
+
// // Test direct crypto verification
|
|
484
|
+
// const directVerify = CryptoUtils.verify(
|
|
485
|
+
// referenceSignature.publicKey,
|
|
486
|
+
// messageHash,
|
|
487
|
+
// referenceSignature.signature
|
|
488
|
+
// );
|
|
451
489
|
|
|
452
490
|
// Check trusted keys
|
|
453
491
|
// const trustedKeys = KeyManager.getAllTrustedPublicKeys();
|
|
454
492
|
|
|
455
|
-
const isValid =
|
|
456
|
-
documentForVerification,
|
|
457
|
-
referenceSignature,
|
|
458
|
-
{ includeFields: ['command', 'description', 'from', 'name'] }
|
|
459
|
-
);
|
|
493
|
+
const isValid = await EnactCore.checkToolVerificationStatus(tool);
|
|
460
494
|
|
|
461
|
-
|
|
495
|
+
console.log("Final verification result:", isValid);
|
|
462
496
|
|
|
463
497
|
if (!isValid) {
|
|
464
498
|
throw new Error(`Tool ${tool.name} has invalid signatures`);
|