@@ -10,6 +10,7 @@ import {
1010 containsGlobChars ,
1111 DANGEROUS_FILES ,
1212 getDangerousDirectories ,
13+ RESERVED_ENV_VARS ,
1314} from './sandbox-utils.js'
1415import type {
1516 FsReadRestrictionConfig ,
@@ -29,6 +30,8 @@ export interface MacOSSandboxParams {
2930 writeConfig : FsWriteRestrictionConfig | undefined
3031 ignoreViolations ?: IgnoreViolationsConfig | undefined
3132 binShell ?: string
33+ /** Custom environment variables to set in the sandbox */
34+ envVars ?: Array < { name : string ; value : string } >
3235}
3336
3437/**
@@ -674,7 +677,33 @@ export function wrapCommandWithSandboxMacOS(
674677 } )
675678
676679 // Generate proxy environment variables using shared utility
677- const proxyEnv = `export ${ generateProxyEnvVars ( httpProxyPort , socksProxyPort ) . join ( ' ' ) } && `
680+ const proxyEnvVars = generateProxyEnvVars ( httpProxyPort , socksProxyPort )
681+
682+ // Add custom environment variables (with reserved var filtering)
683+ const customEnvVars : string [ ] = [ ]
684+ if ( params . envVars && params . envVars . length > 0 ) {
685+ for ( const { name, value } of params . envVars ) {
686+ if ( RESERVED_ENV_VARS . has ( name . toUpperCase ( ) ) ) {
687+ logForDebugging (
688+ `[Sandbox macOS] Skipping reserved environment variable: ${ name } ` ,
689+ { level : 'warn' } ,
690+ )
691+ continue
692+ }
693+ // Shell-escape the value for safety
694+ const escapedValue = value . replace ( / ' / g, "'\\''" )
695+ customEnvVars . push ( `${ name } ='${ escapedValue } '` )
696+ }
697+ if ( customEnvVars . length > 0 ) {
698+ logForDebugging (
699+ `[Sandbox macOS] Added ${ customEnvVars . length } custom environment variable(s)` ,
700+ )
701+ }
702+ }
703+
704+ const allEnvVars = [ ...proxyEnvVars , ...customEnvVars ]
705+ const proxyEnv =
706+ allEnvVars . length > 0 ? `export ${ allEnvVars . join ( ' ' ) } && ` : ''
678707
679708 // Use the user's shell (zsh, bash, etc.) to ensure aliases/snapshots work
680709 // Resolve the full path to the shell binary
0 commit comments