-
Notifications
You must be signed in to change notification settings - Fork 37.6k
Enabling sandboxing for terminal commands execution through copilot chat. #280236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
40882e1
Enable sandboxing for terminal commands
dileepyavan 0b15f7e
removing unused types
dileepyavan 1084d72
code review comments update
dileepyavan c0b6751
main merge
dileepyavan b1976dc
refactored the code and added utility for sandboxing
dileepyavan a7ce30e
refactored the code and added utility for sandboxing
dileepyavan 63cac43
refactored the code and added utility for sandboxing
dileepyavan caf2c45
fixing build error
dileepyavan 5c21691
review suggestions
dileepyavan cd71156
review suggestions
dileepyavan 762aaad
changes for retry
dileepyavan 5147287
changes for retry
dileepyavan 697f4f5
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/common…
dileepyavan 353d912
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan b634138
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/common…
dileepyavan 94f319d
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan a8b410c
Update src/vs/workbench/contrib/terminalContrib/chatAgentTools/browse…
dileepyavan f4e9d28
merging from main
dileepyavan 49aeae9
updating anthropic sandbox runtime to 0.0.23
dileepyavan 31ea4be
fixing tests for runInTerminalTool
dileepyavan 10ce464
refactoring changes
dileepyavan 02fec9b
review changes
dileepyavan 22c6a80
review changes
dileepyavan 544d616
review changes
dileepyavan 5b01c73
review changes
dileepyavan dd41b1b
review changes
dileepyavan 4742604
review changes
dileepyavan 4adb2a6
review changes
dileepyavan aa3945e
update to sandboxservice
dileepyavan 1e046d4
update to sandboxservice
dileepyavan e35e56f
update to sandboxservice
dileepyavan 2ed1d8d
removing extra line
dileepyavan 46534e1
formatting PR suggested by copilot
dileepyavan 07dc6df
files location change suggested for review
dileepyavan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
src/vs/workbench/contrib/terminal/common/terminalSandboxService.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Microsoft Corporation. All rights reserved. | ||
| * Licensed under the MIT License. See License.txt in the project root for license information. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
|
|
||
| import { isNative, OperatingSystem, OS } from '../../../../base/common/platform.js'; | ||
| import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; | ||
| import { ITerminalSandboxSettings } from '../../../../platform/terminal/common/terminal.js'; | ||
| import { ILogService } from '../../../../platform/log/common/log.js'; | ||
| import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; | ||
| import { dirname, join } from '../../../../base/common/path.js'; | ||
| import { FileAccess } from '../../../../base/common/network.js'; | ||
| import { URI } from '../../../../base/common/uri.js'; | ||
| import { IFileService } from '../../../../platform/files/common/files.js'; | ||
| import { VSBuffer } from '../../../../base/common/buffer.js'; | ||
| import { joinPath } from '../../../../base/common/resources.js'; | ||
| import { generateUuid } from '../../../../base/common/uuid.js'; | ||
| import { IEnvironmentService } from '../../../../platform/environment/common/environment.js'; | ||
| import { TerminalContribSettingId } from '../terminalContribExports.js'; | ||
| import { IRemoteAgentService } from '../../../services/remote/common/remoteAgentService.js'; | ||
|
|
||
| export const ITerminalSandboxService = createDecorator<ITerminalSandboxService>('terminalSandboxService'); | ||
|
|
||
| export interface ITerminalSandboxService { | ||
| readonly _serviceBrand: undefined; | ||
| isEnabled(): boolean; | ||
| wrapCommand(command: string): string; | ||
| getSandboxConfigPath(forceRefresh?: boolean): Promise<string | undefined>; | ||
| getTempDir(): URI | undefined; | ||
| setNeedsForceUpdateConfigFile(): void; | ||
| } | ||
|
|
||
| export class TerminalSandboxService implements ITerminalSandboxService { | ||
| readonly _serviceBrand: undefined; | ||
| private _srtPath: string; | ||
| private _sandboxConfigPath: string | undefined; | ||
| private _needsForceUpdateConfigFile = true; | ||
| private _tempDir: URI | undefined; | ||
| private _sandboxSettingsId: string | undefined; | ||
| private _os: OperatingSystem = OS; | ||
|
|
||
|
|
||
| constructor( | ||
| @IConfigurationService private readonly _configurationService: IConfigurationService, | ||
| @IFileService private readonly _fileService: IFileService, | ||
| @IEnvironmentService private readonly _environmentService: IEnvironmentService, | ||
| @ILogService private readonly _logService: ILogService, | ||
| @IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService, | ||
| ) { | ||
| const appRoot = dirname(FileAccess.asFileUri('').fsPath); | ||
| this._srtPath = join(appRoot, 'node_modules', '.bin', 'srt'); | ||
| this._sandboxSettingsId = generateUuid(); | ||
| this._initTempDir(); | ||
| this._remoteAgentService.getEnvironment().then(remoteEnv => this._os = remoteEnv?.os ?? OS); | ||
| } | ||
|
|
||
| public isEnabled(): boolean { | ||
| if (this._os === OperatingSystem.Windows) { | ||
| return false; | ||
| } | ||
| return this._configurationService.getValue<boolean>(TerminalContribSettingId.TerminalSandboxEnabled); | ||
| } | ||
|
|
||
| public wrapCommand(command: string): string { | ||
| if (!this._sandboxConfigPath || !this._tempDir) { | ||
| throw new Error('Sandbox config path or temp dir not initialized'); | ||
| } | ||
| return `"${this._srtPath}" TMPDIR=${this._tempDir.fsPath} --settings "${this._sandboxConfigPath}" "${command}"`; | ||
| } | ||
|
|
||
| public getTempDir(): URI | undefined { | ||
| return this._tempDir; | ||
| } | ||
|
|
||
| public setNeedsForceUpdateConfigFile(): void { | ||
| this._needsForceUpdateConfigFile = true; | ||
| } | ||
|
|
||
| public async getSandboxConfigPath(forceRefresh: boolean = false): Promise<string | undefined> { | ||
| if (!this._sandboxConfigPath || forceRefresh || this._needsForceUpdateConfigFile) { | ||
| this._sandboxConfigPath = await this._createSandboxConfig(); | ||
| this._needsForceUpdateConfigFile = false; | ||
| } | ||
| return this._sandboxConfigPath; | ||
| } | ||
|
|
||
| private async _createSandboxConfig(): Promise<string | undefined> { | ||
|
|
||
| if (this.isEnabled() && !this._tempDir) { | ||
| this._initTempDir(); | ||
| } | ||
| if (this._tempDir) { | ||
| const networkSetting = this._configurationService.getValue<ITerminalSandboxSettings['network']>(TerminalContribSettingId.TerminalSandboxNetwork) ?? {}; | ||
| const linuxFileSystemSetting = this._os === OperatingSystem.Linux | ||
| ? this._configurationService.getValue<ITerminalSandboxSettings['filesystem']>(TerminalContribSettingId.TerminalSandboxLinuxFileSystem) ?? {} | ||
| : {}; | ||
| const macFileSystemSetting = this._os === OperatingSystem.Macintosh | ||
| ? this._configurationService.getValue<ITerminalSandboxSettings['filesystem']>(TerminalContribSettingId.TerminalSandboxMacFileSystem) ?? {} | ||
| : {}; | ||
| const configFileUri = joinPath(this._tempDir, `vscode-sandbox-settings-${this._sandboxSettingsId}.json`); | ||
| const sandboxSettings = { | ||
| network: { | ||
| allowedDomains: networkSetting.allowedDomains ?? [], | ||
| deniedDomains: networkSetting.deniedDomains ?? [] | ||
| }, | ||
| filesystem: { | ||
| denyRead: this._os === OperatingSystem.Macintosh ? macFileSystemSetting.denyRead : linuxFileSystemSetting.denyRead, | ||
| allowWrite: this._os === OperatingSystem.Macintosh ? macFileSystemSetting.allowWrite : linuxFileSystemSetting.allowWrite, | ||
| denyWrite: this._os === OperatingSystem.Macintosh ? macFileSystemSetting.denyWrite : linuxFileSystemSetting.denyWrite, | ||
| } | ||
| }; | ||
| this._sandboxConfigPath = configFileUri.fsPath; | ||
| await this._fileService.createFile(configFileUri, VSBuffer.fromString(JSON.stringify(sandboxSettings, null, '\t')), { overwrite: true }); | ||
| return this._sandboxConfigPath; | ||
| } | ||
| return undefined; | ||
| } | ||
|
|
||
| private _initTempDir(): void { | ||
| if (this.isEnabled() && isNative) { | ||
| this._needsForceUpdateConfigFile = true; | ||
| const environmentService = this._environmentService as IEnvironmentService & { tmpDir?: URI }; | ||
| this._tempDir = environmentService.tmpDir; | ||
| if (!this._tempDir) { | ||
| this._logService.warn('TerminalSandboxService: Cannot create sandbox settings file because no tmpDir is available in this environment'); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.