2026-03-11 14:42:50 -07:00
|
|
|
/**
|
|
|
|
|
* @license
|
2026-03-13 14:11:51 -07:00
|
|
|
* Copyright 2026 Google LLC
|
2026-03-11 14:42:50 -07:00
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*/
|
|
|
|
|
|
2026-03-16 21:34:48 +00:00
|
|
|
import os from 'node:os';
|
2026-03-11 14:42:50 -07:00
|
|
|
import {
|
|
|
|
|
sanitizeEnvironment,
|
2026-03-16 21:34:48 +00:00
|
|
|
getSecureSanitizationConfig,
|
2026-03-11 14:42:50 -07:00
|
|
|
type EnvironmentSanitizationConfig,
|
|
|
|
|
} from './environmentSanitization.js';
|
2026-03-16 21:34:48 +00:00
|
|
|
import { LinuxSandboxManager } from '../sandbox/linux/LinuxSandboxManager.js';
|
2026-03-18 16:07:54 -04:00
|
|
|
import { MacOsSandboxManager } from '../sandbox/macos/MacOsSandboxManager.js';
|
2026-03-11 14:42:50 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Request for preparing a command to run in a sandbox.
|
|
|
|
|
*/
|
|
|
|
|
export interface SandboxRequest {
|
|
|
|
|
/** The program to execute. */
|
|
|
|
|
command: string;
|
|
|
|
|
/** Arguments for the program. */
|
|
|
|
|
args: string[];
|
|
|
|
|
/** The working directory. */
|
|
|
|
|
cwd: string;
|
|
|
|
|
/** Environment variables to be passed to the program. */
|
|
|
|
|
env: NodeJS.ProcessEnv;
|
|
|
|
|
/** Optional sandbox-specific configuration. */
|
|
|
|
|
config?: {
|
|
|
|
|
sanitizationConfig?: Partial<EnvironmentSanitizationConfig>;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A command that has been prepared for sandboxed execution.
|
|
|
|
|
*/
|
|
|
|
|
export interface SandboxedCommand {
|
|
|
|
|
/** The program or wrapper to execute. */
|
|
|
|
|
program: string;
|
|
|
|
|
/** Final arguments for the program. */
|
|
|
|
|
args: string[];
|
|
|
|
|
/** Sanitized environment variables. */
|
|
|
|
|
env: NodeJS.ProcessEnv;
|
2026-03-13 14:11:51 -07:00
|
|
|
/** The working directory. */
|
|
|
|
|
cwd?: string;
|
2026-03-11 14:42:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Interface for a service that prepares commands for sandboxed execution.
|
|
|
|
|
*/
|
|
|
|
|
export interface SandboxManager {
|
|
|
|
|
/**
|
|
|
|
|
* Prepares a command to run in a sandbox, including environment sanitization.
|
|
|
|
|
*/
|
|
|
|
|
prepareCommand(req: SandboxRequest): Promise<SandboxedCommand>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A no-op implementation of SandboxManager that silently passes commands
|
|
|
|
|
* through while applying environment sanitization.
|
|
|
|
|
*/
|
|
|
|
|
export class NoopSandboxManager implements SandboxManager {
|
|
|
|
|
/**
|
|
|
|
|
* Prepares a command by sanitizing the environment and passing through
|
|
|
|
|
* the original program and arguments.
|
|
|
|
|
*/
|
|
|
|
|
async prepareCommand(req: SandboxRequest): Promise<SandboxedCommand> {
|
2026-03-16 21:34:48 +00:00
|
|
|
const sanitizationConfig = getSecureSanitizationConfig(
|
|
|
|
|
req.config?.sanitizationConfig,
|
|
|
|
|
);
|
2026-03-11 14:42:50 -07:00
|
|
|
|
|
|
|
|
const sanitizedEnv = sanitizeEnvironment(req.env, sanitizationConfig);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
program: req.command,
|
|
|
|
|
args: req.args,
|
|
|
|
|
env: sanitizedEnv,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-13 14:11:51 -07:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* SandboxManager that implements actual sandboxing.
|
|
|
|
|
*/
|
|
|
|
|
export class LocalSandboxManager implements SandboxManager {
|
|
|
|
|
async prepareCommand(_req: SandboxRequest): Promise<SandboxedCommand> {
|
|
|
|
|
throw new Error('Tool sandboxing is not yet implemented.');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Creates a sandbox manager based on the provided settings.
|
|
|
|
|
*/
|
|
|
|
|
export function createSandboxManager(
|
|
|
|
|
sandboxingEnabled: boolean,
|
2026-03-16 21:34:48 +00:00
|
|
|
workspace: string,
|
2026-03-13 14:11:51 -07:00
|
|
|
): SandboxManager {
|
|
|
|
|
if (sandboxingEnabled) {
|
2026-03-16 21:34:48 +00:00
|
|
|
if (os.platform() === 'linux') {
|
|
|
|
|
return new LinuxSandboxManager({ workspace });
|
|
|
|
|
}
|
2026-03-18 16:07:54 -04:00
|
|
|
if (os.platform() === 'darwin') {
|
|
|
|
|
return new MacOsSandboxManager({ workspace });
|
|
|
|
|
}
|
2026-03-13 14:11:51 -07:00
|
|
|
return new LocalSandboxManager();
|
|
|
|
|
}
|
|
|
|
|
return new NoopSandboxManager();
|
|
|
|
|
}
|