@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/src/index.ts CHANGED
@@ -22,11 +22,6 @@ export * from './utils/logger';
22
22
  export * from './utils/silent-monitor';
23
23
  export * from './utils/timeout';
24
24
 
25
- // Security
26
- export * from './security/security';
27
- export { verifyTool, shouldExecuteTool, VERIFICATION_POLICIES } from './security/sign';
28
- export type { VerificationPolicy as SecurityVerificationPolicy } from './security/sign';
29
- export * from './security/verification-enforcer';
30
25
 
31
26
  // Services
32
27
  export * from './services/McpCoreService';
@@ -20,7 +20,6 @@ export class EnactDirect {
20
20
  apiUrl?: string;
21
21
  supabaseUrl?: string;
22
22
  authToken?: string;
23
- verificationPolicy?: "permissive" | "enterprise" | "paranoid";
24
23
  defaultTimeout?: string;
25
24
  } = {},
26
25
  ) {
@@ -33,7 +32,6 @@ export class EnactDirect {
33
32
  "https://xjnhhxwxovjifdxdwzih.supabase.co",
34
33
  executionProvider: "direct",
35
34
  authToken: options.authToken || process.env.ENACT_AUTH_TOKEN,
36
- verificationPolicy: options.verificationPolicy || "permissive",
37
35
  defaultTimeout: options.defaultTimeout || "30s",
38
36
  });
39
37
  }
@@ -75,24 +73,6 @@ export class EnactDirect {
75
73
  return this.core.getToolInfo(name, version);
76
74
  }
77
75
 
78
- /**
79
- * Verify a tool's cryptographic signatures
80
- *
81
- * @param name - Tool name
82
- * @param policy - Verification policy
83
- * @returns Verification result
84
- */
85
- async verifyTool(
86
- name: string,
87
- policy?: "permissive" | "enterprise" | "paranoid",
88
- ): Promise<{
89
- verified: boolean;
90
- signatures: any[];
91
- policy: string;
92
- errors?: string[];
93
- }> {
94
- return this.core.verifyTool(name, policy);
95
- }
96
76
 
97
77
  /**
98
78
  * Execute a tool from raw YAML definition
@@ -173,7 +153,6 @@ export class EnactDirect {
173
153
  async getStatus(): Promise<{
174
154
  executionProvider: string;
175
155
  apiUrl: string;
176
- verificationPolicy: string;
177
156
  defaultTimeout: string;
178
157
  authenticated: boolean;
179
158
  }> {
@@ -62,16 +62,12 @@ export class McpCoreService {
62
62
  inputs: Record<string, any> = {},
63
63
  options?: {
64
64
  timeout?: string;
65
- verifyPolicy?: "permissive" | "enterprise" | "paranoid";
66
- skipVerification?: boolean;
67
65
  force?: boolean;
68
66
  dryRun?: boolean;
69
67
  },
70
68
  ): Promise<ExecutionResult> {
71
69
  const executeOptions: ToolExecuteOptions = {
72
70
  timeout: options?.timeout,
73
- verifyPolicy: options?.verifyPolicy,
74
- skipVerification: options?.skipVerification,
75
71
  force: options?.force,
76
72
  dryRun: options?.dryRun,
77
73
  };
@@ -87,14 +83,12 @@ export class McpCoreService {
87
83
  inputs: Record<string, any> = {},
88
84
  options?: {
89
85
  timeout?: string;
90
- skipVerification?: boolean;
91
86
  force?: boolean;
92
87
  dryRun?: boolean;
93
88
  },
94
89
  ): Promise<ExecutionResult> {
95
90
  const executeOptions: ToolExecuteOptions = {
96
91
  timeout: options?.timeout,
97
- skipVerification: options?.skipVerification,
98
92
  force: options?.force,
99
93
  dryRun: options?.dryRun,
100
94
  };
@@ -102,20 +96,6 @@ export class McpCoreService {
102
96
  return await this.core.executeRawTool(toolYaml, inputs, executeOptions);
103
97
  }
104
98
 
105
- /**
106
- * Verify a tool's signature
107
- */
108
- async verifyTool(
109
- name: string,
110
- policy?: string,
111
- ): Promise<{
112
- verified: boolean;
113
- signatures: any[];
114
- policy: string;
115
- errors?: string[];
116
- }> {
117
- return await this.core.verifyTool(name, policy);
118
- }
119
99
 
120
100
  /**
121
101
  * Check if a tool exists
package/src/types.ts CHANGED
@@ -6,6 +6,7 @@ export interface EnactTool {
6
6
  command: string; // Shell command to execute with version pins
7
7
 
8
8
  // RECOMMENDED FIELDS
9
+ from?: string; // Container image to run the command on (optional, defaults to system shell)
9
10
  timeout?: string; // Go duration format: "30s", "5m", "1h" (default: "30s")
10
11
  tags?: string[]; // Tags for search and categorization
11
12
  license?: string; // SPDX License identifier (e.g., "MIT", "Apache-2.0")
@@ -70,18 +71,15 @@ export interface EnactTool {
70
71
  role?: string; // Optional description of the signer
71
72
  };
72
73
 
73
- // Multi-signature support (new format)
74
- signatures?: Record<
75
- string,
76
- {
77
- algorithm: string; // Hash algorithm: "sha256"
78
- type: string; // Signature type: "ecdsa-p256"
79
- signer: string; // Signer identifier
80
- created: string; // ISO timestamp
81
- value: string; // Base64 encoded signature
82
- role?: string; // Optional description of the signer (e.g., "author", "maintainer")
83
- }
84
- >;
74
+ // Multi-signature support (array format)
75
+ signatures?: {
76
+ signer: string; // Signer identifier (UUID or human-readable name)
77
+ algorithm: string; // Hash algorithm: "sha256"
78
+ type: string; // Signature type: "ecdsa-p256"
79
+ value: string; // Base64 encoded signature
80
+ created: string; // ISO timestamp
81
+ role?: string; // Optional description of the signer (e.g., "author", "reviewer", "approver")
82
+ }[];
85
83
 
86
84
  // Extensions pattern (x-prefixed fields)
87
85
  [key: string]: any; // Allow x- prefixed extension fields
@@ -23,7 +23,7 @@ export async function ensureConfig(): Promise<void> {
23
23
  }
24
24
 
25
25
  if (!existsSync(CONFIG_FILE)) {
26
- await writeConfig({ history: [] });
26
+ await writeFile(CONFIG_FILE, JSON.stringify({ history: [] }, null, 2));
27
27
  }
28
28
  }
29
29
 
@@ -1,12 +1,33 @@
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
  /**
5
8
  * Displays the CLI version with nice formatting
6
9
  */
7
10
  export function showVersion(): void {
8
- // Bun automatically sets npm_package_version when running scripts via package.json
9
- const version = process.env.npm_package_version || "0.0.1-dev";
11
+ let version = "0.0.1-dev";
12
+
13
+ try {
14
+ // Try to get version from environment first (for npm scripts)
15
+ if (process.env.npm_package_version) {
16
+ version = process.env.npm_package_version;
17
+ } else {
18
+ // When running as installed binary, read from package.json
19
+ // Go up from shared/dist/utils/version.js to find package.json
20
+ const currentFile = typeof __filename !== 'undefined' ? __filename : fileURLToPath(import.meta.url);
21
+ const sharedDir = dirname(dirname(dirname(currentFile)));
22
+ const packageJsonPath = join(sharedDir, 'package.json');
23
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
24
+ version = packageJson.version;
25
+ }
26
+ } catch (error) {
27
+ // Fall back to default version if anything fails
28
+ version = "1.0.14";
29
+ }
30
+
10
31
  const versionText = `v${version}`;
11
32
 
12
33
  console.error(`
@@ -1,3 +0,0 @@
1
- export * from './security';
2
- export * from './sign';
3
- export * from './verification-enforcer';
@@ -1,188 +0,0 @@
1
- // src/security/security.ts - Simplified security module for CLI core
2
- import logger from "../exec/logger";
3
- import type { EnactTool } from "../types";
4
-
5
- /**
6
- * Verify the signature of an Enact tool before execution
7
- * @param tool The tool to verify
8
- * @returns Boolean indicating validity
9
- */
10
-
11
- /**
12
- * Verify that a command is safe to execute
13
- * @param command The command to verify
14
- * @param tool The tool containing the command
15
- * @returns Object with safety status and warnings
16
- */
17
- export function verifyCommandSafety(
18
- command: string,
19
- tool: EnactTool,
20
- ): {
21
- isSafe: boolean;
22
- warnings: string[];
23
- blocked?: string[];
24
- } {
25
- const warnings: string[] = [];
26
- const blocked: string[] = [];
27
-
28
- // Dangerous command patterns that should be blocked
29
- const dangerousPatterns = [
30
- /rm\s+-rf\s+\//, // rm -rf /
31
- /rm\s+-rf\s+\*/, // rm -rf *
32
- />\s*\/dev\/sd[a-z]/, // Writing to disk devices
33
- /dd\s+if=.*of=\/dev/, // Direct disk writing
34
- /mkfs/, // Format filesystem
35
- /fdisk/, // Disk partitioning
36
- /passwd/, // Password changes
37
- /sudo\s+passwd/, // Password changes with sudo
38
- /chmod\s+777/, // Overly permissive permissions
39
- /curl.*\|\s*sh/, // Piping curl to shell
40
- /wget.*\|\s*sh/, // Piping wget to shell
41
- /exec\s+sh/, // Executing shell
42
- /\/etc\/passwd/, // Accessing password file
43
- /\/etc\/shadow/, // Accessing shadow file
44
- ];
45
-
46
- // Check for dangerous patterns
47
- for (const pattern of dangerousPatterns) {
48
- if (pattern.test(command)) {
49
- blocked.push(
50
- `Potentially dangerous command pattern detected: ${pattern.source}`,
51
- );
52
- }
53
- }
54
-
55
- // Warning patterns that are suspicious but not necessarily blocked
56
- const warningPatterns = [
57
- /sudo\s+/, // Sudo usage
58
- /su\s+/, // User switching
59
- /systemctl/, // System service control
60
- /service\s+/, // Service control
61
- /mount/, // Mounting filesystems
62
- /umount/, // Unmounting filesystems
63
- /iptables/, // Firewall rules
64
- /crontab/, // Cron job management
65
- ];
66
-
67
- // Check for warning patterns
68
- for (const pattern of warningPatterns) {
69
- if (pattern.test(command)) {
70
- warnings.push(
71
- `Potentially privileged operation detected: ${pattern.source}`,
72
- );
73
- }
74
- }
75
-
76
- // Check for version pinning (security best practice)
77
- if (command.includes("npx ") && !command.match(/npx\s+[^@#\s]+[@#]/)) {
78
- if (!command.includes("github:")) {
79
- warnings.push(
80
- "NPX package not version-pinned - consider using @version or github:org/repo#commit",
81
- );
82
- }
83
- }
84
-
85
- if (
86
- command.includes("uvx ") &&
87
- !command.includes("git+") &&
88
- !command.includes("@")
89
- ) {
90
- warnings.push(
91
- "UVX package not version-pinned - consider using @version or git+ URL",
92
- );
93
- }
94
-
95
- if (
96
- command.includes("docker run") &&
97
- !command.match(/:[^@\s]+(@sha256:|:\w)/)
98
- ) {
99
- warnings.push(
100
- "Docker image not version-pinned - consider using specific tags or digests",
101
- );
102
- }
103
-
104
- // Check for network access patterns
105
- if (tool.annotations?.openWorldHint !== true) {
106
- const networkPatterns = [
107
- /curl\s+/, // HTTP requests
108
- /wget\s+/, // HTTP requests
109
- /http[s]?:\/\//, // HTTP URLs
110
- /ftp:\/\//, // FTP URLs
111
- /ssh\s+/, // SSH connections
112
- /scp\s+/, // SCP transfers
113
- /rsync.*::/, // Rsync over network
114
- ];
115
-
116
- for (const pattern of networkPatterns) {
117
- if (pattern.test(command)) {
118
- warnings.push(
119
- "Network access detected but openWorldHint not set to true",
120
- );
121
- break;
122
- }
123
- }
124
- }
125
-
126
- // Check for destructive operations
127
- if (tool.annotations?.destructiveHint !== true) {
128
- const destructivePatterns = [
129
- /rm\s+/, // File removal
130
- /rmdir\s+/, // Directory removal
131
- /mv\s+.*\s+\/dev\//, // Moving to device files
132
- />\s*[^&]/, // File redirection (overwriting)
133
- /tee\s+/, // Writing to files
134
- ];
135
-
136
- for (const pattern of destructivePatterns) {
137
- if (pattern.test(command)) {
138
- warnings.push(
139
- "Potentially destructive operation detected but destructiveHint not set to true",
140
- );
141
- break;
142
- }
143
- }
144
- }
145
-
146
- return {
147
- isSafe: blocked.length === 0,
148
- warnings,
149
- ...(blocked.length > 0 && { blocked }),
150
- };
151
- }
152
-
153
- /**
154
- * Sanitize environment variables to prevent injection attacks
155
- * @param envVars Environment variables to sanitize
156
- * @returns Sanitized environment variables
157
- */
158
- export function sanitizeEnvironmentVariables(
159
- envVars: Record<string, any>,
160
- ): Record<string, string> {
161
- const sanitized: Record<string, string> = {};
162
-
163
- for (const [key, value] of Object.entries(envVars)) {
164
- // Validate environment variable name
165
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
166
- logger.warn(`Invalid environment variable name: ${key}`);
167
- continue;
168
- }
169
-
170
- // Convert value to string and sanitize
171
- const strValue = String(value);
172
-
173
- // Check for potentially dangerous characters
174
- if (strValue.includes("\n") || strValue.includes("\r")) {
175
- logger.warn(`Environment variable ${key} contains newline characters`);
176
- }
177
-
178
- if (strValue.includes("$(") || strValue.includes("`")) {
179
- logger.warn(
180
- `Environment variable ${key} contains command substitution patterns`,
181
- );
182
- }
183
-
184
- sanitized[key] = strValue;
185
- }
186
-
187
- return sanitized;
188
- }