feat(sandbox): dynamic macOS sandbox expansion and worktree support (#23301)

This commit is contained in:
Gal Zahavi
2026-03-23 21:48:13 -07:00
committed by GitHub
parent 7fdf708e1a
commit fe7baee18b
40 changed files with 2201 additions and 183 deletions
@@ -11,6 +11,18 @@ import {
getSecureSanitizationConfig,
type EnvironmentSanitizationConfig,
} from './environmentSanitization.js';
export interface SandboxPermissions {
/** Filesystem permissions. */
fileSystem?: {
/** Paths that should be readable by the command. */
read?: string[];
/** Paths that should be writable by the command. */
write?: string[];
};
/** Whether the command should have network access. */
network?: boolean;
}
/**
* Security boundaries and permissions applied to a specific sandboxed execution.
*/
@@ -23,6 +35,8 @@ export interface ExecutionPolicy {
networkAccess?: boolean;
/** Rules for scrubbing sensitive environment variables. */
sanitizationConfig?: Partial<EnvironmentSanitizationConfig>;
/** Additional granular permissions to grant to this command. */
additionalPermissions?: SandboxPermissions;
}
/**
@@ -14,6 +14,7 @@ import { LinuxSandboxManager } from '../sandbox/linux/LinuxSandboxManager.js';
import { MacOsSandboxManager } from '../sandbox/macos/MacOsSandboxManager.js';
import { WindowsSandboxManager } from './windowsSandboxManager.js';
import type { SandboxConfig } from '../config/config.js';
import { type SandboxPolicyManager } from '../policy/sandboxPolicyManager.js';
/**
* Creates a sandbox manager based on the provided settings.
@@ -21,7 +22,13 @@ import type { SandboxConfig } from '../config/config.js';
export function createSandboxManager(
sandbox: SandboxConfig | undefined,
workspace: string,
policyManager?: SandboxPolicyManager,
approvalMode?: string,
): SandboxManager {
if (approvalMode === 'yolo') {
return new NoopSandboxManager();
}
const isWindows = os.platform() === 'win32';
if (
@@ -36,7 +43,15 @@ export function createSandboxManager(
return new LinuxSandboxManager({ workspace });
}
if (os.platform() === 'darwin') {
return new MacOsSandboxManager({ workspace });
const modeConfig =
policyManager && approvalMode
? policyManager.getModeConfig(approvalMode)
: undefined;
return new MacOsSandboxManager({
workspace,
modeConfig,
policyManager,
});
}
return new LocalSandboxManager();
}
@@ -31,7 +31,11 @@ import {
sanitizeEnvironment,
type EnvironmentSanitizationConfig,
} from './environmentSanitization.js';
import { NoopSandboxManager, type SandboxManager } from './sandboxManager.js';
import {
NoopSandboxManager,
type SandboxManager,
type SandboxPermissions,
} from './sandboxManager.js';
import type { SandboxConfig } from '../config/config.js';
import { killProcessGroup } from '../utils/process-utils.js';
import {
@@ -84,6 +88,7 @@ export type ShellExecutionResult = ExecutionResult;
export type ShellExecutionHandle = ExecutionHandle;
export interface ShellExecutionConfig {
additionalPermissions?: SandboxPermissions;
terminalWidth?: number;
terminalHeight?: number;
pager?: string;
@@ -441,6 +446,7 @@ export class ShellExecutionService {
...shellExecutionConfig,
...(shellExecutionConfig.sandboxConfig || {}),
sanitizationConfig,
additionalPermissions: shellExecutionConfig.additionalPermissions,
},
});