From b32a129600dc9ed4fe605ff384bd80ecdf6f1e28 Mon Sep 17 00:00:00 2001 From: Dileep Yavanmandha Date: Fri, 1 May 2026 16:07:12 -0700 Subject: [PATCH] Changes to include workspaceStorage directory for allowRead --- .../common/terminalSandboxService.ts | 8 +++++++- .../browser/terminalSandboxService.test.ts | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.ts index 60741322837d3..00764929df3e3 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.ts @@ -667,7 +667,7 @@ export class TerminalSandboxService extends Disposable implements ITerminalSandb } private _updateAllowReadPathsWithAllowWrite(configuredAllowRead: string[] | undefined, allowWrite: string[]): string[] { - return [...new Set([...(configuredAllowRead ?? []), ...getTerminalSandboxReadAllowListForCommands(this._os, this._commandReadAllowKeywords), ...this._getSandboxRuntimeReadPaths(), ...allowWrite])]; + return [...new Set([...(configuredAllowRead ?? []), ...getTerminalSandboxReadAllowListForCommands(this._os, this._commandReadAllowKeywords), ...this._getSandboxRuntimeReadPaths(), ...this._getWorkspaceStorageReadPaths(), ...allowWrite])]; } private _resolveLinuxFileSystemPaths(paths: string[] | undefined): string[] { @@ -704,6 +704,12 @@ export class TerminalSandboxService extends Disposable implements ITerminalSandb return path === this._appRoot || path.startsWith(`${this._appRoot}${this._os === OperatingSystem.Windows ? win32.sep : posix.sep}`); } + private _getWorkspaceStorageReadPaths(): string[] { + const workspaceStorageHome = this._remoteEnvDetails?.workspaceStorageHome ?? this._environmentService.workspaceStorageHome; + const workspaceId = this._workspaceContextService.getWorkspace().id; + return [URI.joinPath(workspaceStorageHome, workspaceId).path]; + } + private _getUserHomePath(): string | undefined { const nativeEnv = this._environmentService as IEnvironmentService & { userHome?: URI }; return this._remoteEnvDetails?.userHome?.path ?? nativeEnv.userHome?.path; diff --git a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/browser/terminalSandboxService.test.ts b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/browser/terminalSandboxService.test.ts index 8d7c3c93d34af..185551f47bb83 100644 --- a/src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/browser/terminalSandboxService.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/chatAgentTools/test/browser/terminalSandboxService.test.ts @@ -419,6 +419,26 @@ suite('TerminalSandboxService - network domains', () => { ok(!config.filesystem.allowRead.includes('/app/node_modules/@vscode/ripgrep'), 'Sandbox config should not redundantly include app root child paths'); }); + test('should reallow reads from workspace storage', async () => { + remoteAgentService.remoteEnvironment = { + ...remoteAgentService.remoteEnvironment!, + workspaceStorageHome: URI.file('/home/user/.vscode-server/data/User/workspaceStorage') + }; + + const sandboxService = store.add(instantiationService.createInstance(TerminalSandboxService)); + const configPath = await sandboxService.getSandboxConfigPath(); + + ok(configPath, 'Config path should be defined'); + const configContent = createdFiles.get(configPath); + ok(configContent, 'Config file should be created'); + + const config = JSON.parse(configContent); + const expectedWorkspaceStoragePath = URI.joinPath(remoteAgentService.remoteEnvironment.workspaceStorageHome, workspaceContextService.getWorkspace().id).path; + + ok(config.filesystem.denyRead.includes('/home/user'), 'Sandbox config should deny arbitrary reads from the user home'); + ok(config.filesystem.allowRead.includes(expectedWorkspaceStoragePath), 'Sandbox config should re-allow reads from workspace storage'); + }); + test('should only add command-specific allowRead paths for the current command keywords', async () => { const sandboxService = store.add(instantiationService.createInstance(TerminalSandboxService)); const configPath = await sandboxService.getSandboxConfigPath();