| |
| |
| |
| |
| |
|
|
| import type { |
| FsReadRestrictionConfig, |
| FsWriteRestrictionConfig, |
| IgnoreViolationsConfig, |
| NetworkHostPattern, |
| NetworkRestrictionConfig, |
| SandboxAskCallback, |
| SandboxDependencyCheck, |
| SandboxRuntimeConfig, |
| SandboxViolationEvent, |
| } from '@anthropic-ai/sandbox-runtime' |
| import { |
| SandboxManager as BaseSandboxManager, |
| SandboxRuntimeConfigSchema, |
| SandboxViolationStore, |
| } from '@anthropic-ai/sandbox-runtime' |
| import { rmSync, statSync } from 'fs' |
| import { readFile } from 'fs/promises' |
| import { memoize } from 'lodash-es' |
| import { join, resolve, sep } from 'path' |
| import { |
| getAdditionalDirectoriesForClaudeMd, |
| getCwdState, |
| getOriginalCwd, |
| } from '../../bootstrap/state.js' |
| import { logForDebugging } from '../debug.js' |
| import { expandPath } from '../path.js' |
| import { getPlatform, type Platform } from '../platform.js' |
| import { settingsChangeDetector } from '../settings/changeDetector.js' |
| import { SETTING_SOURCES, type SettingSource } from '../settings/constants.js' |
| import { getManagedSettingsDropInDir } from '../settings/managedPath.js' |
| import { |
| getInitialSettings, |
| getSettings_DEPRECATED, |
| getSettingsFilePathForSource, |
| getSettingsForSource, |
| getSettingsRootPathForSource, |
| updateSettingsForSource, |
| } from '../settings/settings.js' |
| import type { SettingsJson } from '../settings/types.js' |
|
|
| |
| |
| |
|
|
| import { BASH_TOOL_NAME } from 'src/tools/BashTool/toolName.js' |
| import { FILE_EDIT_TOOL_NAME } from 'src/tools/FileEditTool/constants.js' |
| import { FILE_READ_TOOL_NAME } from 'src/tools/FileReadTool/prompt.js' |
| import { WEB_FETCH_TOOL_NAME } from 'src/tools/WebFetchTool/prompt.js' |
| import { errorMessage } from '../errors.js' |
| import { getClaudeTempDir } from '../permissions/filesystem.js' |
| import type { PermissionRuleValue } from '../permissions/PermissionRule.js' |
| import { ripgrepCommand } from '../ripgrep.js' |
|
|
| |
| |
| function permissionRuleValueFromString( |
| ruleString: string, |
| ): PermissionRuleValue { |
| const matches = ruleString.match(/^([^(]+)\(([^)]+)\)$/) |
| if (!matches) { |
| return { toolName: ruleString } |
| } |
| const toolName = matches[1] |
| const ruleContent = matches[2] |
| if (!toolName || !ruleContent) { |
| return { toolName: ruleString } |
| } |
| return { toolName, ruleContent } |
| } |
|
|
| function permissionRuleExtractPrefix(permissionRule: string): string | null { |
| const match = permissionRule.match(/^(.+):\*$/) |
| return match?.[1] ?? null |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function resolvePathPatternForSandbox( |
| pattern: string, |
| source: SettingSource, |
| ): string { |
| |
| if (pattern.startsWith('//')) { |
| return pattern.slice(1) |
| } |
|
|
| |
| |
| if (pattern.startsWith('/') && !pattern.startsWith('//')) { |
| const root = getSettingsRootPathForSource(source) |
| |
| return resolve(root, pattern.slice(1)) |
| } |
|
|
| |
| |
| return pattern |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function resolveSandboxFilesystemPath( |
| pattern: string, |
| source: SettingSource, |
| ): string { |
| |
| |
| if (pattern.startsWith('//')) return pattern.slice(1) |
| return expandPath(pattern, getSettingsRootPathForSource(source)) |
| } |
|
|
| |
| |
| |
| |
| export function shouldAllowManagedSandboxDomainsOnly(): boolean { |
| return ( |
| getSettingsForSource('policySettings')?.sandbox?.network |
| ?.allowManagedDomainsOnly === true |
| ) |
| } |
|
|
| function shouldAllowManagedReadPathsOnly(): boolean { |
| return ( |
| getSettingsForSource('policySettings')?.sandbox?.filesystem |
| ?.allowManagedReadPathsOnly === true |
| ) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| export function convertToSandboxRuntimeConfig( |
| settings: SettingsJson, |
| ): SandboxRuntimeConfig { |
| const permissions = settings.permissions || {} |
|
|
| |
| const allowedDomains: string[] = [] |
| const deniedDomains: string[] = [] |
|
|
| |
| if (shouldAllowManagedSandboxDomainsOnly()) { |
| const policySettings = getSettingsForSource('policySettings') |
| for (const domain of policySettings?.sandbox?.network?.allowedDomains || |
| []) { |
| allowedDomains.push(domain) |
| } |
| for (const ruleString of policySettings?.permissions?.allow || []) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if ( |
| rule.toolName === WEB_FETCH_TOOL_NAME && |
| rule.ruleContent?.startsWith('domain:') |
| ) { |
| allowedDomains.push(rule.ruleContent.substring('domain:'.length)) |
| } |
| } |
| } else { |
| for (const domain of settings.sandbox?.network?.allowedDomains || []) { |
| allowedDomains.push(domain) |
| } |
| for (const ruleString of permissions.allow || []) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if ( |
| rule.toolName === WEB_FETCH_TOOL_NAME && |
| rule.ruleContent?.startsWith('domain:') |
| ) { |
| allowedDomains.push(rule.ruleContent.substring('domain:'.length)) |
| } |
| } |
| } |
|
|
| for (const ruleString of permissions.deny || []) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if ( |
| rule.toolName === WEB_FETCH_TOOL_NAME && |
| rule.ruleContent?.startsWith('domain:') |
| ) { |
| deniedDomains.push(rule.ruleContent.substring('domain:'.length)) |
| } |
| } |
|
|
| |
| |
| |
| const allowWrite: string[] = ['.', getClaudeTempDir()] |
| const denyWrite: string[] = [] |
| const denyRead: string[] = [] |
| const allowRead: string[] = [] |
|
|
| |
| |
| const settingsPaths = SETTING_SOURCES.map(source => |
| getSettingsFilePathForSource(source), |
| ).filter((p): p is string => p !== undefined) |
| denyWrite.push(...settingsPaths) |
| denyWrite.push(getManagedSettingsDropInDir()) |
|
|
| |
| |
| const cwd = getCwdState() |
| const originalCwd = getOriginalCwd() |
| if (cwd !== originalCwd) { |
| denyWrite.push(resolve(cwd, '.claude', 'settings.json')) |
| denyWrite.push(resolve(cwd, '.claude', 'settings.local.json')) |
| } |
|
|
| |
| |
| |
| |
| |
| denyWrite.push(resolve(originalCwd, '.claude', 'skills')) |
| if (cwd !== originalCwd) { |
| denyWrite.push(resolve(cwd, '.claude', 'skills')) |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bareGitRepoScrubPaths.length = 0 |
| const bareGitRepoFiles = ['HEAD', 'objects', 'refs', 'hooks', 'config'] |
| for (const dir of cwd === originalCwd ? [originalCwd] : [originalCwd, cwd]) { |
| for (const gitFile of bareGitRepoFiles) { |
| const p = resolve(dir, gitFile) |
| try { |
| |
| statSync(p) |
| denyWrite.push(p) |
| } catch { |
| bareGitRepoScrubPaths.push(p) |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| if (worktreeMainRepoPath && worktreeMainRepoPath !== cwd) { |
| allowWrite.push(worktreeMainRepoPath) |
| } |
|
|
| |
| |
| |
| |
| |
| const additionalDirs = new Set([ |
| ...(settings.permissions?.additionalDirectories || []), |
| ...getAdditionalDirectoriesForClaudeMd(), |
| ]) |
| allowWrite.push(...additionalDirs) |
|
|
| |
| |
| |
| for (const source of SETTING_SOURCES) { |
| const sourceSettings = getSettingsForSource(source) |
|
|
| |
| if (sourceSettings?.permissions) { |
| for (const ruleString of sourceSettings.permissions.allow || []) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if (rule.toolName === FILE_EDIT_TOOL_NAME && rule.ruleContent) { |
| allowWrite.push( |
| resolvePathPatternForSandbox(rule.ruleContent, source), |
| ) |
| } |
| } |
|
|
| for (const ruleString of sourceSettings.permissions.deny || []) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if (rule.toolName === FILE_EDIT_TOOL_NAME && rule.ruleContent) { |
| denyWrite.push(resolvePathPatternForSandbox(rule.ruleContent, source)) |
| } |
| if (rule.toolName === FILE_READ_TOOL_NAME && rule.ruleContent) { |
| denyRead.push(resolvePathPatternForSandbox(rule.ruleContent, source)) |
| } |
| } |
| } |
|
|
| |
| |
| |
| const fs = sourceSettings?.sandbox?.filesystem |
| if (fs) { |
| for (const p of fs.allowWrite || []) { |
| allowWrite.push(resolveSandboxFilesystemPath(p, source)) |
| } |
| for (const p of fs.denyWrite || []) { |
| denyWrite.push(resolveSandboxFilesystemPath(p, source)) |
| } |
| for (const p of fs.denyRead || []) { |
| denyRead.push(resolveSandboxFilesystemPath(p, source)) |
| } |
| if (!shouldAllowManagedReadPathsOnly() || source === 'policySettings') { |
| for (const p of fs.allowRead || []) { |
| allowRead.push(resolveSandboxFilesystemPath(p, source)) |
| } |
| } |
| } |
| } |
| |
| |
| const { rgPath, rgArgs, argv0 } = ripgrepCommand() |
| const ripgrepConfig = settings.sandbox?.ripgrep ?? { |
| command: rgPath, |
| args: rgArgs, |
| argv0, |
| } |
|
|
| return { |
| network: { |
| allowedDomains, |
| deniedDomains, |
| allowUnixSockets: settings.sandbox?.network?.allowUnixSockets, |
| allowAllUnixSockets: settings.sandbox?.network?.allowAllUnixSockets, |
| allowLocalBinding: settings.sandbox?.network?.allowLocalBinding, |
| httpProxyPort: settings.sandbox?.network?.httpProxyPort, |
| socksProxyPort: settings.sandbox?.network?.socksProxyPort, |
| }, |
| filesystem: { |
| denyRead, |
| allowRead, |
| allowWrite, |
| denyWrite, |
| }, |
| ignoreViolations: settings.sandbox?.ignoreViolations, |
| enableWeakerNestedSandbox: settings.sandbox?.enableWeakerNestedSandbox, |
| enableWeakerNetworkIsolation: |
| settings.sandbox?.enableWeakerNetworkIsolation, |
| ripgrep: ripgrepConfig, |
| } |
| } |
|
|
| |
| |
| |
|
|
| let initializationPromise: Promise<void> | undefined |
| let settingsSubscriptionCleanup: (() => void) | undefined |
|
|
| |
| |
| |
| let worktreeMainRepoPath: string | null | undefined |
|
|
| |
| |
| const bareGitRepoScrubPaths: string[] = [] |
|
|
| |
| |
| |
| |
| |
| function scrubBareGitRepoFiles(): void { |
| for (const p of bareGitRepoScrubPaths) { |
| try { |
| |
| rmSync(p, { recursive: true }) |
| logForDebugging(`[Sandbox] scrubbed planted bare-repo file: ${p}`) |
| } catch { |
| |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| async function detectWorktreeMainRepoPath(cwd: string): Promise<string | null> { |
| const gitPath = join(cwd, '.git') |
| try { |
| const gitContent = await readFile(gitPath, { encoding: 'utf8' }) |
| const gitdirMatch = gitContent.match(/^gitdir:\s*(.+)$/m) |
| if (!gitdirMatch?.[1]) { |
| return null |
| } |
| |
| const gitdir = resolve(cwd, gitdirMatch[1].trim()) |
| |
| |
| |
| const marker = `${sep}.git${sep}worktrees${sep}` |
| const markerIndex = gitdir.lastIndexOf(marker) |
| if (markerIndex > 0) { |
| return gitdir.substring(0, markerIndex) |
| } |
| return null |
| } catch { |
| |
| return null |
| } |
| } |
|
|
| |
| |
| |
| |
| const checkDependencies = memoize((): SandboxDependencyCheck => { |
| const { rgPath, rgArgs } = ripgrepCommand() |
| return BaseSandboxManager.checkDependencies({ |
| command: rgPath, |
| args: rgArgs, |
| }) |
| }) |
|
|
| function getSandboxEnabledSetting(): boolean { |
| try { |
| const settings = getSettings_DEPRECATED() |
| return settings?.sandbox?.enabled ?? false |
| } catch (error) { |
| logForDebugging(`Failed to get settings for sandbox check: ${error}`) |
| return false |
| } |
| } |
|
|
| function isAutoAllowBashIfSandboxedEnabled(): boolean { |
| const settings = getSettings_DEPRECATED() |
| return settings?.sandbox?.autoAllowBashIfSandboxed ?? true |
| } |
|
|
| function areUnsandboxedCommandsAllowed(): boolean { |
| const settings = getSettings_DEPRECATED() |
| return settings?.sandbox?.allowUnsandboxedCommands ?? true |
| } |
|
|
| function isSandboxRequired(): boolean { |
| const settings = getSettings_DEPRECATED() |
| return ( |
| getSandboxEnabledSetting() && |
| (settings?.sandbox?.failIfUnavailable ?? false) |
| ) |
| } |
|
|
| |
| |
| |
| |
| const isSupportedPlatform = memoize((): boolean => { |
| return BaseSandboxManager.isSupportedPlatform() |
| }) |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function isPlatformInEnabledList(): boolean { |
| try { |
| const settings = getInitialSettings() |
| const enabledPlatforms = ( |
| settings?.sandbox as { enabledPlatforms?: Platform[] } | undefined |
| )?.enabledPlatforms |
|
|
| if (enabledPlatforms === undefined) { |
| return true |
| } |
|
|
| if (enabledPlatforms.length === 0) { |
| return false |
| } |
|
|
| const currentPlatform = getPlatform() |
| return enabledPlatforms.includes(currentPlatform) |
| } catch (error) { |
| logForDebugging(`Failed to check enabledPlatforms: ${error}`) |
| return true |
| } |
| } |
|
|
| |
| |
| |
| |
| function isSandboxingEnabled(): boolean { |
| if (!isSupportedPlatform()) { |
| return false |
| } |
|
|
| if (checkDependencies().errors.length > 0) { |
| return false |
| } |
|
|
| |
| if (!isPlatformInEnabledList()) { |
| return false |
| } |
|
|
| return getSandboxEnabledSetting() |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function getSandboxUnavailableReason(): string | undefined { |
| |
| |
| if (!getSandboxEnabledSetting()) { |
| return undefined |
| } |
|
|
| if (!isSupportedPlatform()) { |
| const platform = getPlatform() |
| if (platform === 'wsl') { |
| return 'sandbox.enabled is set but WSL1 is not supported (requires WSL2)' |
| } |
| return `sandbox.enabled is set but ${platform} is not supported (requires macOS, Linux, or WSL2)` |
| } |
|
|
| if (!isPlatformInEnabledList()) { |
| return `sandbox.enabled is set but ${getPlatform()} is not in sandbox.enabledPlatforms` |
| } |
|
|
| const deps = checkDependencies() |
| if (deps.errors.length > 0) { |
| const platform = getPlatform() |
| const hint = |
| platform === 'macos' |
| ? 'run /sandbox or /doctor for details' |
| : 'install missing tools (e.g. apt install bubblewrap socat) or run /sandbox for details' |
| return `sandbox.enabled is set but dependencies are missing: ${deps.errors.join(', ')} · ${hint}` |
| } |
|
|
| return undefined |
| } |
|
|
| |
| |
| |
| function getLinuxGlobPatternWarnings(): string[] { |
| |
| const platform = getPlatform() |
| if (platform !== 'linux' && platform !== 'wsl') { |
| return [] |
| } |
|
|
| try { |
| const settings = getSettings_DEPRECATED() |
|
|
| |
| if (!settings?.sandbox?.enabled) { |
| return [] |
| } |
|
|
| const permissions = settings?.permissions || {} |
| const warnings: string[] = [] |
|
|
| |
| const hasGlobs = (path: string): boolean => { |
| const stripped = path.replace(/\/\*\*$/, '') |
| return /[*?[\]]/.test(stripped) |
| } |
|
|
| |
| for (const ruleString of [ |
| ...(permissions.allow || []), |
| ...(permissions.deny || []), |
| ]) { |
| const rule = permissionRuleValueFromString(ruleString) |
| if ( |
| (rule.toolName === FILE_EDIT_TOOL_NAME || |
| rule.toolName === FILE_READ_TOOL_NAME) && |
| rule.ruleContent && |
| hasGlobs(rule.ruleContent) |
| ) { |
| warnings.push(ruleString) |
| } |
| } |
|
|
| return warnings |
| } catch (error) { |
| logForDebugging(`Failed to get Linux glob pattern warnings: ${error}`) |
| return [] |
| } |
| } |
|
|
| |
| |
| |
| function areSandboxSettingsLockedByPolicy(): boolean { |
| |
| |
| const overridingSources = ['flagSettings', 'policySettings'] as const |
|
|
| for (const source of overridingSources) { |
| const settings = getSettingsForSource(source) |
| if ( |
| settings?.sandbox?.enabled !== undefined || |
| settings?.sandbox?.autoAllowBashIfSandboxed !== undefined || |
| settings?.sandbox?.allowUnsandboxedCommands !== undefined |
| ) { |
| return true |
| } |
| } |
|
|
| return false |
| } |
|
|
| |
| |
| |
| async function setSandboxSettings(options: { |
| enabled?: boolean |
| autoAllowBashIfSandboxed?: boolean |
| allowUnsandboxedCommands?: boolean |
| }): Promise<void> { |
| const existingSettings = getSettingsForSource('localSettings') |
|
|
| |
| |
|
|
| updateSettingsForSource('localSettings', { |
| sandbox: { |
| ...existingSettings?.sandbox, |
| ...(options.enabled !== undefined && { enabled: options.enabled }), |
| ...(options.autoAllowBashIfSandboxed !== undefined && { |
| autoAllowBashIfSandboxed: options.autoAllowBashIfSandboxed, |
| }), |
| ...(options.allowUnsandboxedCommands !== undefined && { |
| allowUnsandboxedCommands: options.allowUnsandboxedCommands, |
| }), |
| }, |
| }) |
| } |
|
|
| |
| |
| |
| function getExcludedCommands(): string[] { |
| const settings = getSettings_DEPRECATED() |
| return settings?.sandbox?.excludedCommands ?? [] |
| } |
|
|
| |
| |
| |
| async function wrapWithSandbox( |
| command: string, |
| binShell?: string, |
| customConfig?: Partial<SandboxRuntimeConfig>, |
| abortSignal?: AbortSignal, |
| ): Promise<string> { |
| |
| if (isSandboxingEnabled()) { |
| if (initializationPromise) { |
| await initializationPromise |
| } else { |
| throw new Error('Sandbox failed to initialize. ') |
| } |
| } |
|
|
| return BaseSandboxManager.wrapWithSandbox( |
| command, |
| binShell, |
| customConfig, |
| abortSignal, |
| ) |
| } |
|
|
| |
| |
| |
| async function initialize( |
| sandboxAskCallback?: SandboxAskCallback, |
| ): Promise<void> { |
| |
| if (initializationPromise) { |
| return initializationPromise |
| } |
|
|
| |
| if (!isSandboxingEnabled()) { |
| return |
| } |
|
|
| |
| |
| const wrappedCallback: SandboxAskCallback | undefined = sandboxAskCallback |
| ? async (hostPattern: NetworkHostPattern) => { |
| if (shouldAllowManagedSandboxDomainsOnly()) { |
| logForDebugging( |
| `[sandbox] Blocked network request to ${hostPattern.host} (allowManagedDomainsOnly)`, |
| ) |
| return false |
| } |
| return sandboxAskCallback(hostPattern) |
| } |
| : undefined |
|
|
| |
| |
| initializationPromise = (async () => { |
| try { |
| |
| |
| |
| |
| if (worktreeMainRepoPath === undefined) { |
| worktreeMainRepoPath = await detectWorktreeMainRepoPath(getCwdState()) |
| } |
|
|
| const settings = getSettings_DEPRECATED() |
| const runtimeConfig = convertToSandboxRuntimeConfig(settings) |
|
|
| |
| await BaseSandboxManager.initialize(runtimeConfig, wrappedCallback) |
|
|
| |
| settingsSubscriptionCleanup = settingsChangeDetector.subscribe(() => { |
| const settings = getSettings_DEPRECATED() |
| const newConfig = convertToSandboxRuntimeConfig(settings) |
| BaseSandboxManager.updateConfig(newConfig) |
| logForDebugging('Sandbox configuration updated from settings change') |
| }) |
| } catch (error) { |
| |
| initializationPromise = undefined |
|
|
| |
| logForDebugging(`Failed to initialize sandbox: ${errorMessage(error)}`) |
| } |
| })() |
|
|
| return initializationPromise |
| } |
|
|
| |
| |
| |
| |
| function refreshConfig(): void { |
| if (!isSandboxingEnabled()) return |
| const settings = getSettings_DEPRECATED() |
| const newConfig = convertToSandboxRuntimeConfig(settings) |
| BaseSandboxManager.updateConfig(newConfig) |
| } |
|
|
| |
| |
| |
| async function reset(): Promise<void> { |
| |
| settingsSubscriptionCleanup?.() |
| settingsSubscriptionCleanup = undefined |
| worktreeMainRepoPath = undefined |
| bareGitRepoScrubPaths.length = 0 |
|
|
| |
| checkDependencies.cache.clear?.() |
| isSupportedPlatform.cache.clear?.() |
| initializationPromise = undefined |
|
|
| |
| return BaseSandboxManager.reset() |
| } |
|
|
| |
| |
| |
| |
| export function addToExcludedCommands( |
| command: string, |
| permissionUpdates?: Array<{ |
| type: string |
| rules: Array<{ toolName: string; ruleContent?: string }> |
| }>, |
| ): string { |
| const existingSettings = getSettingsForSource('localSettings') |
| const existingExcludedCommands = |
| existingSettings?.sandbox?.excludedCommands || [] |
|
|
| |
| |
| |
| let commandPattern: string = command |
|
|
| if (permissionUpdates) { |
| const bashSuggestions = permissionUpdates.filter( |
| update => |
| update.type === 'addRules' && |
| update.rules.some(rule => rule.toolName === BASH_TOOL_NAME), |
| ) |
|
|
| if (bashSuggestions.length > 0 && bashSuggestions[0]!.type === 'addRules') { |
| const firstBashRule = bashSuggestions[0]!.rules.find( |
| rule => rule.toolName === BASH_TOOL_NAME, |
| ) |
| if (firstBashRule?.ruleContent) { |
| |
| const prefix = permissionRuleExtractPrefix(firstBashRule.ruleContent) |
| commandPattern = prefix || firstBashRule.ruleContent |
| } |
| } |
| } |
|
|
| |
| if (!existingExcludedCommands.includes(commandPattern)) { |
| updateSettingsForSource('localSettings', { |
| sandbox: { |
| ...existingSettings?.sandbox, |
| excludedCommands: [...existingExcludedCommands, commandPattern], |
| }, |
| }) |
| } |
|
|
| return commandPattern |
| } |
|
|
| |
| |
| |
|
|
| export interface ISandboxManager { |
| initialize(sandboxAskCallback?: SandboxAskCallback): Promise<void> |
| isSupportedPlatform(): boolean |
| isPlatformInEnabledList(): boolean |
| getSandboxUnavailableReason(): string | undefined |
| isSandboxingEnabled(): boolean |
| isSandboxEnabledInSettings(): boolean |
| checkDependencies(): SandboxDependencyCheck |
| isAutoAllowBashIfSandboxedEnabled(): boolean |
| areUnsandboxedCommandsAllowed(): boolean |
| isSandboxRequired(): boolean |
| areSandboxSettingsLockedByPolicy(): boolean |
| setSandboxSettings(options: { |
| enabled?: boolean |
| autoAllowBashIfSandboxed?: boolean |
| allowUnsandboxedCommands?: boolean |
| }): Promise<void> |
| getFsReadConfig(): FsReadRestrictionConfig |
| getFsWriteConfig(): FsWriteRestrictionConfig |
| getNetworkRestrictionConfig(): NetworkRestrictionConfig |
| getAllowUnixSockets(): string[] | undefined |
| getAllowLocalBinding(): boolean | undefined |
| getIgnoreViolations(): IgnoreViolationsConfig | undefined |
| getEnableWeakerNestedSandbox(): boolean | undefined |
| getExcludedCommands(): string[] |
| getProxyPort(): number | undefined |
| getSocksProxyPort(): number | undefined |
| getLinuxHttpSocketPath(): string | undefined |
| getLinuxSocksSocketPath(): string | undefined |
| waitForNetworkInitialization(): Promise<boolean> |
| wrapWithSandbox( |
| command: string, |
| binShell?: string, |
| customConfig?: Partial<SandboxRuntimeConfig>, |
| abortSignal?: AbortSignal, |
| ): Promise<string> |
| cleanupAfterCommand(): void |
| getSandboxViolationStore(): SandboxViolationStore |
| annotateStderrWithSandboxFailures(command: string, stderr: string): string |
| getLinuxGlobPatternWarnings(): string[] |
| refreshConfig(): void |
| reset(): Promise<void> |
| } |
|
|
| |
| |
| |
| export const SandboxManager: ISandboxManager = { |
| |
| initialize, |
| isSandboxingEnabled, |
| isSandboxEnabledInSettings: getSandboxEnabledSetting, |
| isPlatformInEnabledList, |
| getSandboxUnavailableReason, |
| isAutoAllowBashIfSandboxedEnabled, |
| areUnsandboxedCommandsAllowed, |
| isSandboxRequired, |
| areSandboxSettingsLockedByPolicy, |
| setSandboxSettings, |
| getExcludedCommands, |
| wrapWithSandbox, |
| refreshConfig, |
| reset, |
| checkDependencies, |
|
|
| |
| getFsReadConfig: BaseSandboxManager.getFsReadConfig, |
| getFsWriteConfig: BaseSandboxManager.getFsWriteConfig, |
| getNetworkRestrictionConfig: BaseSandboxManager.getNetworkRestrictionConfig, |
| getIgnoreViolations: BaseSandboxManager.getIgnoreViolations, |
| getLinuxGlobPatternWarnings, |
| isSupportedPlatform, |
| getAllowUnixSockets: BaseSandboxManager.getAllowUnixSockets, |
| getAllowLocalBinding: BaseSandboxManager.getAllowLocalBinding, |
| getEnableWeakerNestedSandbox: BaseSandboxManager.getEnableWeakerNestedSandbox, |
| getProxyPort: BaseSandboxManager.getProxyPort, |
| getSocksProxyPort: BaseSandboxManager.getSocksProxyPort, |
| getLinuxHttpSocketPath: BaseSandboxManager.getLinuxHttpSocketPath, |
| getLinuxSocksSocketPath: BaseSandboxManager.getLinuxSocksSocketPath, |
| waitForNetworkInitialization: BaseSandboxManager.waitForNetworkInitialization, |
| getSandboxViolationStore: BaseSandboxManager.getSandboxViolationStore, |
| annotateStderrWithSandboxFailures: |
| BaseSandboxManager.annotateStderrWithSandboxFailures, |
| cleanupAfterCommand: (): void => { |
| BaseSandboxManager.cleanupAfterCommand() |
| scrubBareGitRepoFiles() |
| }, |
| } |
|
|
| |
| |
| |
|
|
| export type { |
| SandboxAskCallback, |
| SandboxDependencyCheck, |
| FsReadRestrictionConfig, |
| FsWriteRestrictionConfig, |
| NetworkRestrictionConfig, |
| NetworkHostPattern, |
| SandboxViolationEvent, |
| SandboxRuntimeConfig, |
| IgnoreViolationsConfig, |
| } |
|
|
| export { SandboxViolationStore, SandboxRuntimeConfigSchema } |
|
|