From 189e840006a1d90ce9afdfa550d010e4ea1c7990 Mon Sep 17 00:00:00 2001 From: galz10 Date: Fri, 27 Mar 2026 07:50:18 -0700 Subject: [PATCH] fix(sandbox): improve Windows workspace write permissions --- .../sandbox/windows/WindowsSandboxManager.ts | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/core/src/sandbox/windows/WindowsSandboxManager.ts b/packages/core/src/sandbox/windows/WindowsSandboxManager.ts index a213d7b619..776bd40b02 100644 --- a/packages/core/src/sandbox/windows/WindowsSandboxManager.ts +++ b/packages/core/src/sandbox/windows/WindowsSandboxManager.ts @@ -256,7 +256,7 @@ export class WindowsSandboxManager implements SandboxManager { await this.grantLowIntegrityAccess(this.options.workspace); } - // Grant "Low Mandatory Level" read access to allowedPaths. + // Grant "Low Mandatory Level" write access to allowedPaths. const allowedPaths = sanitizePaths(req.policy?.allowedPaths) || []; for (const allowedPath of allowedPaths) { await this.grantLowIntegrityAccess(allowedPath); @@ -317,6 +317,7 @@ export class WindowsSandboxManager implements SandboxManager { /** * Grants "Low Mandatory Level" access to a path using icacls. + * This effectively allows a Low Integrity process to WRITE to the path. */ private async grantLowIntegrityAccess(targetPath: string): Promise { if (os.platform() !== 'win32') { @@ -357,7 +358,23 @@ export class WindowsSandboxManager implements SandboxManager { } try { - await spawnAsync('icacls', [resolvedPath, '/setintegritylevel', 'Low']); + const stats = await fs.promises.stat(resolvedPath); + if (stats.isDirectory()) { + // For directories, we enable inheritance (OI)(CI) so new files created + // by the CLI or other Medium processes inherit the Low label. + // We also use /T to recursively apply to existing files. + // /C continues on errors, /Q is quiet. + await spawnAsync('icacls', [ + resolvedPath, + '/setintegritylevel', + '(OI)(CI)Low', + '/T', + '/C', + '/Q', + ]); + } else { + await spawnAsync('icacls', [resolvedPath, '/setintegritylevel', 'Low']); + } this.allowedCache.add(resolvedPath); } catch (e) { debugLogger.log(