@@ -429,16 +429,35 @@ export function generateDockerCompose(
429429 // Note: UID/GID values are logged by the container entrypoint if needed for debugging
430430
431431 // Build volumes list for agent execution container
432- // For chroot mode, use the real user's home (not /root when running with sudo)
432+ // SECURITY: Mount only specific paths needed, NOT the entire home directory
433+ // This prevents access to sensitive paths like ~/actions-runner, ~/work (other repos), etc.
433434 const effectiveHome = config . enableChroot ? getRealUserHome ( ) : ( process . env . HOME || '/root' ) ;
434435 const agentVolumes : string [ ] = [
435436 // Essential mounts that are always included
436437 '/tmp:/tmp:rw' ,
437- `${ effectiveHome } :${ effectiveHome } :rw` ,
438- // Mount agent logs directory to workDir for persistence
439- `${ config . workDir } /agent-logs:${ effectiveHome } /.copilot/logs:rw` ,
440438 ] ;
441439
440+ // Mount specific subdirectories of home instead of the entire home directory
441+ // This prevents access to sensitive paths like ~/actions-runner, ~/work (other repos)
442+ const copilotConfigDir = path . join ( effectiveHome , '.copilot' ) ;
443+
444+ // Ensure .copilot directory exists on host before mounting
445+ if ( ! fs . existsSync ( copilotConfigDir ) ) {
446+ fs . mkdirSync ( copilotConfigDir , { recursive : true } ) ;
447+ }
448+
449+ // Mount ~/.copilot for MCP config (read-only) and logs (write via separate mount)
450+ agentVolumes . push ( `${ copilotConfigDir } :${ copilotConfigDir } :ro` ) ;
451+ // Mount agent logs directory to workDir for persistence (overlays the ro mount above)
452+ agentVolumes . push ( `${ config . workDir } /agent-logs:${ effectiveHome } /.copilot/logs:rw` ) ;
453+
454+ // Mount the workspace directory if specified (the actual project being worked on)
455+ if ( config . containerWorkDir && config . containerWorkDir !== '/workspace' ) {
456+ // Only mount if it's a real path (not the default /workspace)
457+ agentVolumes . push ( `${ config . containerWorkDir } :${ config . containerWorkDir } :rw` ) ;
458+ logger . debug ( `Mounting workspace directory: ${ config . containerWorkDir } ` ) ;
459+ }
460+
442461 // Add chroot-related volume mounts when --enable-chroot is specified
443462 // These mounts enable chroot /host to work properly for running host binaries
444463 if ( config . enableChroot ) {
@@ -472,11 +491,33 @@ export function generateDockerCompose(
472491 '/dev:/host/dev:ro' , // Read-only device nodes (needed by some runtimes)
473492 ) ;
474493
475- // User home directory for project files and Rust/Cargo (read-write)
476- // Note: $HOME is already mounted at the container level, this adds it under /host
477- // Use getRealUserHome() to get the actual user's home (not /root when running with sudo)
494+ // SECURITY: Mount specific home subdirectories instead of entire $HOME
495+ // This prevents access to sensitive paths like ~/actions-runner, ~/work (other repos)
478496 const userHome = getRealUserHome ( ) ;
479- agentVolumes . push ( `${ userHome } :/host${ userHome } :rw` ) ;
497+
498+ // Mount ~/.copilot for MCP config under /host (read-only for chroot)
499+ const hostCopilotDir = path . join ( userHome , '.copilot' ) ;
500+ if ( fs . existsSync ( hostCopilotDir ) ) {
501+ agentVolumes . push ( `${ hostCopilotDir } :/host${ hostCopilotDir } :ro` ) ;
502+ }
503+
504+ // Mount ~/.cargo for Rust binaries (read-only) if it exists
505+ const hostCargoDir = path . join ( userHome , '.cargo' ) ;
506+ if ( fs . existsSync ( hostCargoDir ) ) {
507+ agentVolumes . push ( `${ hostCargoDir } :/host${ hostCargoDir } :ro` ) ;
508+ }
509+
510+ // Mount ~/.local/bin for user-installed tools (read-only) if it exists
511+ const hostLocalBin = path . join ( userHome , '.local' , 'bin' ) ;
512+ if ( fs . existsSync ( hostLocalBin ) ) {
513+ agentVolumes . push ( `${ hostLocalBin } :/host${ hostLocalBin } :ro` ) ;
514+ }
515+
516+ // Mount the workspace directory under /host if specified
517+ if ( config . containerWorkDir && config . containerWorkDir !== '/workspace' ) {
518+ agentVolumes . push ( `${ config . containerWorkDir } :/host${ config . containerWorkDir } :rw` ) ;
519+ logger . debug ( `Mounting workspace directory under /host: ${ config . containerWorkDir } ` ) ;
520+ }
480521
481522 // /tmp is needed for chroot mode to write:
482523 // - Temporary command scripts: /host/tmp/awf-cmd-$$.sh
@@ -533,7 +574,7 @@ export function generateDockerCompose(
533574 // Also hide /run/docker.sock (symlink on some systems)
534575 agentVolumes . push ( '/dev/null:/host/run/docker.sock:ro' ) ;
535576
536- logger . debug ( 'Selective mounts configured: system paths (ro), home (rw), Docker socket hidden' ) ;
577+ logger . debug ( 'Selective mounts configured: system paths (ro), workspace (rw), Docker socket hidden' ) ;
537578 }
538579
539580 // Add SSL CA certificate mount if SSL Bump is enabled
0 commit comments