@enactprotocol/shared 1.0.13 ā 1.2.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/dist/api/enact-api.js +2 -2
- package/dist/api/types.d.ts +10 -3
- package/dist/core/DaggerExecutionProvider.d.ts +1 -1
- package/dist/core/DaggerExecutionProvider.js +23 -19
- package/dist/core/EnactCore.d.ts +36 -19
- package/dist/core/EnactCore.js +157 -219
- package/dist/core/NativeExecutionProvider.d.ts +9 -0
- package/dist/core/NativeExecutionProvider.js +16 -0
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/lib/enact-direct.d.ts +0 -15
- package/dist/lib/enact-direct.js +0 -11
- package/dist/security/sign.d.ts +5 -5
- package/dist/security/sign.js +247 -113
- package/dist/security/verification-enforcer.d.ts +12 -0
- package/dist/security/verification-enforcer.js +26 -3
- package/dist/services/McpCoreService.d.ts +0 -12
- package/dist/services/McpCoreService.js +0 -9
- package/dist/types.d.ts +5 -4
- package/dist/utils/config.js +1 -1
- package/dist/utils/version.js +23 -2
- package/package.json +3 -6
- package/src/api/enact-api.ts +2 -2
- package/src/api/types.ts +11 -4
- package/src/core/DaggerExecutionProvider.ts +26 -13
- package/src/core/EnactCore.ts +226 -270
- package/src/index.ts +0 -5
- package/src/lib/enact-direct.ts +0 -21
- package/src/services/McpCoreService.ts +0 -20
- package/src/types.ts +10 -12
- package/src/utils/config.ts +1 -1
- package/src/utils/version.ts +23 -2
- package/src/security/index.ts +0 -3
- package/src/security/security.ts +0 -188
- package/src/security/sign.ts +0 -797
- package/src/security/verification-enforcer.ts +0 -268
|
@@ -5,10 +5,33 @@ import logger from "../exec/logger";
|
|
|
5
5
|
* Enforce mandatory signature verification for tool execution
|
|
6
6
|
* This is the central function that should be called before ANY tool execution
|
|
7
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Get security policy based on execution context
|
|
10
|
+
*/
|
|
11
|
+
export function getSecurityPolicy(options) {
|
|
12
|
+
// Local files have different security policies
|
|
13
|
+
if (options.isLocalFile) {
|
|
14
|
+
return {
|
|
15
|
+
allowSkipVerification: true,
|
|
16
|
+
allowUnsigned: true,
|
|
17
|
+
requireInteractiveConfirmation: false,
|
|
18
|
+
defaultVerificationPolicy: "permissive",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// Production/registry tools have strict policies
|
|
22
|
+
return {
|
|
23
|
+
allowSkipVerification: false,
|
|
24
|
+
allowUnsigned: false,
|
|
25
|
+
requireInteractiveConfirmation: !!options.interactive,
|
|
26
|
+
defaultVerificationPolicy: options.verifyPolicy || "permissive",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
8
29
|
export async function enforceSignatureVerification(tool, options = {}) {
|
|
9
30
|
const toolName = tool.name || "unknown";
|
|
31
|
+
// Apply centralized security policy based on context
|
|
32
|
+
const securityPolicy = getSecurityPolicy(options);
|
|
10
33
|
// Check if verification is explicitly skipped
|
|
11
|
-
if (options.skipVerification) {
|
|
34
|
+
if (options.skipVerification && securityPolicy.allowSkipVerification) {
|
|
12
35
|
logger.warn(`šØ SECURITY WARNING: Signature verification skipped for tool: ${toolName}`);
|
|
13
36
|
logger.warn(` This bypasses security measures and is NOT recommended for production use!`);
|
|
14
37
|
return {
|
|
@@ -29,8 +52,8 @@ export async function enforceSignatureVerification(tool, options = {}) {
|
|
|
29
52
|
!!tool.signature;
|
|
30
53
|
if (!hasSignatures) {
|
|
31
54
|
logger.warn(`ā ļø Tool has no signatures: ${toolName}`);
|
|
32
|
-
// Only allow unsigned tools if
|
|
33
|
-
if (options.allowUnsigned) {
|
|
55
|
+
// Only allow unsigned tools if policy permits (for development/testing)
|
|
56
|
+
if (options.allowUnsigned || securityPolicy.allowUnsigned) {
|
|
34
57
|
logger.warn(` Allowing unsigned tool execution due to allowUnsigned flag (DEV/TEST ONLY)`);
|
|
35
58
|
return {
|
|
36
59
|
allowed: true,
|
|
@@ -27,8 +27,6 @@ export declare class McpCoreService {
|
|
|
27
27
|
*/
|
|
28
28
|
executeToolByName(name: string, inputs?: Record<string, any>, options?: {
|
|
29
29
|
timeout?: string;
|
|
30
|
-
verifyPolicy?: "permissive" | "enterprise" | "paranoid";
|
|
31
|
-
skipVerification?: boolean;
|
|
32
30
|
force?: boolean;
|
|
33
31
|
dryRun?: boolean;
|
|
34
32
|
}): Promise<ExecutionResult>;
|
|
@@ -37,19 +35,9 @@ export declare class McpCoreService {
|
|
|
37
35
|
*/
|
|
38
36
|
executeRawTool(toolYaml: string, inputs?: Record<string, any>, options?: {
|
|
39
37
|
timeout?: string;
|
|
40
|
-
skipVerification?: boolean;
|
|
41
38
|
force?: boolean;
|
|
42
39
|
dryRun?: boolean;
|
|
43
40
|
}): Promise<ExecutionResult>;
|
|
44
|
-
/**
|
|
45
|
-
* Verify a tool's signature
|
|
46
|
-
*/
|
|
47
|
-
verifyTool(name: string, policy?: string): Promise<{
|
|
48
|
-
verified: boolean;
|
|
49
|
-
signatures: any[];
|
|
50
|
-
policy: string;
|
|
51
|
-
errors?: string[];
|
|
52
|
-
}>;
|
|
53
41
|
/**
|
|
54
42
|
* Check if a tool exists
|
|
55
43
|
*/
|
|
@@ -38,8 +38,6 @@ export class McpCoreService {
|
|
|
38
38
|
async executeToolByName(name, inputs = {}, options) {
|
|
39
39
|
const executeOptions = {
|
|
40
40
|
timeout: options?.timeout,
|
|
41
|
-
verifyPolicy: options?.verifyPolicy,
|
|
42
|
-
skipVerification: options?.skipVerification,
|
|
43
41
|
force: options?.force,
|
|
44
42
|
dryRun: options?.dryRun,
|
|
45
43
|
};
|
|
@@ -51,18 +49,11 @@ export class McpCoreService {
|
|
|
51
49
|
async executeRawTool(toolYaml, inputs = {}, options) {
|
|
52
50
|
const executeOptions = {
|
|
53
51
|
timeout: options?.timeout,
|
|
54
|
-
skipVerification: options?.skipVerification,
|
|
55
52
|
force: options?.force,
|
|
56
53
|
dryRun: options?.dryRun,
|
|
57
54
|
};
|
|
58
55
|
return await this.core.executeRawTool(toolYaml, inputs, executeOptions);
|
|
59
56
|
}
|
|
60
|
-
/**
|
|
61
|
-
* Verify a tool's signature
|
|
62
|
-
*/
|
|
63
|
-
async verifyTool(name, policy) {
|
|
64
|
-
return await this.core.verifyTool(name, policy);
|
|
65
|
-
}
|
|
66
57
|
/**
|
|
67
58
|
* Check if a tool exists
|
|
68
59
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export interface EnactTool {
|
|
|
2
2
|
name: string;
|
|
3
3
|
description: string;
|
|
4
4
|
command: string;
|
|
5
|
+
from?: string;
|
|
5
6
|
timeout?: string;
|
|
6
7
|
tags?: string[];
|
|
7
8
|
license?: string;
|
|
@@ -47,14 +48,14 @@ export interface EnactTool {
|
|
|
47
48
|
value: string;
|
|
48
49
|
role?: string;
|
|
49
50
|
};
|
|
50
|
-
signatures?:
|
|
51
|
+
signatures?: {
|
|
52
|
+
signer: string;
|
|
51
53
|
algorithm: string;
|
|
52
54
|
type: string;
|
|
53
|
-
signer: string;
|
|
54
|
-
created: string;
|
|
55
55
|
value: string;
|
|
56
|
+
created: string;
|
|
56
57
|
role?: string;
|
|
57
|
-
}
|
|
58
|
+
}[];
|
|
58
59
|
[key: string]: any;
|
|
59
60
|
}
|
|
60
61
|
export interface JSONSchemaDefinition {
|
package/dist/utils/config.js
CHANGED
package/dist/utils/version.js
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
// src/utils/version.ts
|
|
2
2
|
import pc from "picocolors";
|
|
3
|
+
import { readFileSync } from "fs";
|
|
4
|
+
import { join, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
3
6
|
/**
|
|
4
7
|
* Displays the CLI version with nice formatting
|
|
5
8
|
*/
|
|
6
9
|
export function showVersion() {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
let version = "0.0.1-dev";
|
|
11
|
+
try {
|
|
12
|
+
// Try to get version from environment first (for npm scripts)
|
|
13
|
+
if (process.env.npm_package_version) {
|
|
14
|
+
version = process.env.npm_package_version;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// When running as installed binary, read from package.json
|
|
18
|
+
// Go up from shared/dist/utils/version.js to find package.json
|
|
19
|
+
const currentFile = typeof __filename !== 'undefined' ? __filename : fileURLToPath(import.meta.url);
|
|
20
|
+
const sharedDir = dirname(dirname(dirname(currentFile)));
|
|
21
|
+
const packageJsonPath = join(sharedDir, 'package.json');
|
|
22
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
23
|
+
version = packageJson.version;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
// Fall back to default version if anything fails
|
|
28
|
+
version = "1.0.14";
|
|
29
|
+
}
|
|
9
30
|
const versionText = `v${version}`;
|
|
10
31
|
console.error(`
|
|
11
32
|
${pc.bold("Enact CLI")} ${pc.cyan(versionText)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enactprotocol/shared",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Shared utilities and core functionality for Enact Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,10 +22,6 @@
|
|
|
22
22
|
"import": "./dist/utils/index.js",
|
|
23
23
|
"types": "./dist/utils/index.d.ts"
|
|
24
24
|
},
|
|
25
|
-
"./security": {
|
|
26
|
-
"import": "./dist/security/index.js",
|
|
27
|
-
"types": "./dist/security/index.d.ts"
|
|
28
|
-
},
|
|
29
25
|
"./services": {
|
|
30
26
|
"import": "./dist/services/index.js",
|
|
31
27
|
"types": "./dist/services/index.d.ts"
|
|
@@ -65,6 +61,7 @@
|
|
|
65
61
|
"license": "MIT",
|
|
66
62
|
"dependencies": {
|
|
67
63
|
"@dagger.io/dagger": "^0.9.11",
|
|
64
|
+
"@enactprotocol/security": "^0.2.5",
|
|
68
65
|
"dotenv": "^16.5.0",
|
|
69
66
|
"pino": "^9.7.0",
|
|
70
67
|
"pino-pretty": "^13.0.0",
|
|
@@ -76,4 +73,4 @@
|
|
|
76
73
|
"@types/node": "^20.12.12",
|
|
77
74
|
"typescript": "^5.4.5"
|
|
78
75
|
}
|
|
79
|
-
}
|
|
76
|
+
}
|
package/src/api/enact-api.ts
CHANGED
|
@@ -62,7 +62,7 @@ export class EnactApiClient {
|
|
|
62
62
|
const responseData = await response.json();
|
|
63
63
|
|
|
64
64
|
// Debug logging to help identify response structure issues
|
|
65
|
-
if (process.env.NODE_ENV === "development" || process.env.DEBUG) {
|
|
65
|
+
if ((process.env.NODE_ENV === "development" || process.env.DEBUG) && !process.env.ENACT_SILENT) {
|
|
66
66
|
console.error(`API Response for ${endpoint}:`, responseData);
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -141,7 +141,7 @@ export class EnactApiClient {
|
|
|
141
141
|
|
|
142
142
|
try {
|
|
143
143
|
// Log the request for debugging
|
|
144
|
-
if (process.env.NODE_ENV === "development" || process.env.DEBUG) {
|
|
144
|
+
if ((process.env.NODE_ENV === "development" || process.env.DEBUG) && !process.env.ENACT_SILENT) {
|
|
145
145
|
console.error(
|
|
146
146
|
`Search request to ${endpoint}:`,
|
|
147
147
|
JSON.stringify(query, null, 2),
|
package/src/api/types.ts
CHANGED
|
@@ -2,6 +2,7 @@ export interface EnactToolDefinition {
|
|
|
2
2
|
name: string;
|
|
3
3
|
description: string;
|
|
4
4
|
command: string;
|
|
5
|
+
from?: string;
|
|
5
6
|
version?: string;
|
|
6
7
|
timeout?: string;
|
|
7
8
|
tags?: string[];
|
|
@@ -37,7 +38,14 @@ export interface EnactToolDefinition {
|
|
|
37
38
|
value: string;
|
|
38
39
|
role?: string;
|
|
39
40
|
};
|
|
40
|
-
signatures?:
|
|
41
|
+
signatures?: {
|
|
42
|
+
signer: string;
|
|
43
|
+
algorithm: string;
|
|
44
|
+
type: string;
|
|
45
|
+
value: string;
|
|
46
|
+
created: string;
|
|
47
|
+
role?: string;
|
|
48
|
+
}[];
|
|
41
49
|
raw_content?: string;
|
|
42
50
|
namespace?: string;
|
|
43
51
|
enact?: string;
|
|
@@ -87,7 +95,6 @@ export interface EnactExecOptions {
|
|
|
87
95
|
timeout?: string;
|
|
88
96
|
dry?: boolean;
|
|
89
97
|
verbose?: boolean;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
force?: boolean; // Force execution even if verification fails
|
|
98
|
+
force?: boolean; // Force execution even if verification fails (legacy)
|
|
99
|
+
dangerouslySkipVerification?: boolean; // Skip all signature verification (DANGEROUS)
|
|
93
100
|
}
|
|
@@ -409,6 +409,8 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
409
409
|
inputs,
|
|
410
410
|
environment,
|
|
411
411
|
tool.timeout,
|
|
412
|
+
undefined,
|
|
413
|
+
tool,
|
|
412
414
|
);
|
|
413
415
|
|
|
414
416
|
logger.debug(
|
|
@@ -527,6 +529,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
527
529
|
showSpinner?: boolean;
|
|
528
530
|
streamOutput?: boolean;
|
|
529
531
|
},
|
|
532
|
+
tool?: EnactTool,
|
|
530
533
|
): Promise<CommandResult> {
|
|
531
534
|
const verbose = options?.verbose ?? false;
|
|
532
535
|
const showSpinner = options?.showSpinner ?? false;
|
|
@@ -554,17 +557,20 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
554
557
|
);
|
|
555
558
|
|
|
556
559
|
if (verbose) {
|
|
560
|
+
// Determine which container image to use - prefer tool's 'from' field over default baseImage
|
|
561
|
+
const containerImage = tool?.from || this.options.baseImage!;
|
|
562
|
+
|
|
557
563
|
try {
|
|
558
564
|
const pc = require("picocolors");
|
|
559
565
|
console.error(
|
|
560
566
|
pc.cyan("\nš³ Executing Enact command in Dagger container:"),
|
|
561
567
|
);
|
|
562
568
|
console.error(pc.white(substitutedCommand));
|
|
563
|
-
console.error(pc.gray(`
|
|
569
|
+
console.error(pc.gray(`Container image: ${containerImage}${tool?.from ? ' (from tool.from)' : ' (default baseImage)'}`));
|
|
564
570
|
} catch (e) {
|
|
565
571
|
console.error("\nš³ Executing Enact command in Dagger container:");
|
|
566
572
|
console.error(substitutedCommand);
|
|
567
|
-
console.error(`
|
|
573
|
+
console.error(`Container image: ${containerImage}${tool?.from ? ' (from tool.from)' : ' (default baseImage)'}`);
|
|
568
574
|
}
|
|
569
575
|
}
|
|
570
576
|
|
|
@@ -577,7 +583,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
577
583
|
|
|
578
584
|
// Execute command with enhanced error handling and timeout management
|
|
579
585
|
const result = await Promise.race([
|
|
580
|
-
this.executeWithConnect(substitutedCommand, environment, inputs),
|
|
586
|
+
this.executeWithConnect(substitutedCommand, environment, inputs, tool),
|
|
581
587
|
this.createTimeoutPromise(effectiveTimeout),
|
|
582
588
|
]);
|
|
583
589
|
|
|
@@ -627,6 +633,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
627
633
|
command: string,
|
|
628
634
|
environment: ExecutionEnvironment,
|
|
629
635
|
inputs: Record<string, any>,
|
|
636
|
+
tool?: EnactTool,
|
|
630
637
|
): Promise<CommandResult> {
|
|
631
638
|
return new Promise<CommandResult>((resolve, reject) => {
|
|
632
639
|
// Setup abort handling
|
|
@@ -645,6 +652,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
645
652
|
client,
|
|
646
653
|
environment,
|
|
647
654
|
inputs,
|
|
655
|
+
tool,
|
|
648
656
|
);
|
|
649
657
|
logger.debug("š¦ Container setup complete");
|
|
650
658
|
const commandResult = await this.executeInContainer(
|
|
@@ -698,13 +706,17 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
698
706
|
client: Client,
|
|
699
707
|
environment: ExecutionEnvironment,
|
|
700
708
|
inputs: Record<string, any>,
|
|
709
|
+
tool?: EnactTool,
|
|
701
710
|
): Promise<Container> {
|
|
711
|
+
// Determine which container image to use - prefer tool's 'from' field over default baseImage
|
|
712
|
+
const containerImage = tool?.from || this.options.baseImage!;
|
|
713
|
+
|
|
702
714
|
logger.debug(
|
|
703
|
-
`š Setting up container with
|
|
715
|
+
`š Setting up container with image: ${containerImage}${tool?.from ? ' (from tool.from)' : ' (default baseImage)'}`,
|
|
704
716
|
);
|
|
705
717
|
|
|
706
718
|
// Start with base container
|
|
707
|
-
let container = client.container().from(
|
|
719
|
+
let container = client.container().from(containerImage);
|
|
708
720
|
logger.debug("š¦ Base container created");
|
|
709
721
|
|
|
710
722
|
// Set working directory
|
|
@@ -721,7 +733,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
721
733
|
|
|
722
734
|
// Install common tools needed for Enact commands
|
|
723
735
|
if (this.options.enableNetwork) {
|
|
724
|
-
container = await this.installCommonTools(container);
|
|
736
|
+
container = await this.installCommonTools(container, containerImage);
|
|
725
737
|
logger.debug("š§ Common tools installed");
|
|
726
738
|
} else {
|
|
727
739
|
logger.debug("š§ Skipping common tools installation (network disabled)");
|
|
@@ -745,14 +757,14 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
745
757
|
* Install common tools that Enact commands might need
|
|
746
758
|
* Enhanced with better error handling and timeout
|
|
747
759
|
*/
|
|
748
|
-
private async installCommonTools(container: Container): Promise<Container> {
|
|
760
|
+
private async installCommonTools(container: Container, containerImage: string): Promise<Container> {
|
|
749
761
|
logger.debug(
|
|
750
|
-
`š§ Installing common tools for
|
|
762
|
+
`š§ Installing common tools for container image: ${containerImage}`,
|
|
751
763
|
);
|
|
752
764
|
|
|
753
765
|
try {
|
|
754
766
|
// For node images, most tools are already available, so we can skip installation
|
|
755
|
-
if (
|
|
767
|
+
if (containerImage.includes("node:")) {
|
|
756
768
|
logger.debug(
|
|
757
769
|
"š¦ Node.js image detected, skipping tool installation (most tools already available)",
|
|
758
770
|
);
|
|
@@ -760,10 +772,10 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
760
772
|
}
|
|
761
773
|
|
|
762
774
|
// Determine package manager based on base image
|
|
763
|
-
const isAlpine =
|
|
775
|
+
const isAlpine = containerImage.includes("alpine");
|
|
764
776
|
const isDebian =
|
|
765
|
-
|
|
766
|
-
|
|
777
|
+
containerImage.includes("debian") ||
|
|
778
|
+
containerImage.includes("ubuntu");
|
|
767
779
|
|
|
768
780
|
if (isAlpine) {
|
|
769
781
|
logger.debug("š¦ Detected Alpine Linux, installing basic tools");
|
|
@@ -783,7 +795,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
783
795
|
]);
|
|
784
796
|
} else {
|
|
785
797
|
logger.warn(
|
|
786
|
-
`Unknown
|
|
798
|
+
`Unknown container image ${containerImage}, skipping tool installation`,
|
|
787
799
|
);
|
|
788
800
|
}
|
|
789
801
|
|
|
@@ -1161,6 +1173,7 @@ export class DaggerExecutionProvider extends ExecutionProvider {
|
|
|
1161
1173
|
showSpinner: true,
|
|
1162
1174
|
streamOutput: false,
|
|
1163
1175
|
},
|
|
1176
|
+
undefined, // no tool parameter for backwards compatibility
|
|
1164
1177
|
);
|
|
1165
1178
|
|
|
1166
1179
|
if (result.exitCode !== 0) {
|