@@ -478,6 +478,7 @@ impl ProcessHandle {
478478 interactive : bool ,
479479 policy : & SandboxPolicy ,
480480 ca_paths : Option < & ( PathBuf , PathBuf ) > ,
481+ tls_environment_mode : child_env:: TlsEnvironmentMode ,
481482 provider_env : & HashMap < String , String > ,
482483 ) -> Result < Self > {
483484 Self :: spawn_impl (
@@ -488,6 +489,7 @@ impl ProcessHandle {
488489 interactive,
489490 policy,
490491 ca_paths,
492+ tls_environment_mode,
491493 provider_env,
492494 )
493495 }
@@ -506,6 +508,7 @@ impl ProcessHandle {
506508 interactive : bool ,
507509 policy : & SandboxPolicy ,
508510 ca_paths : Option < & ( PathBuf , PathBuf ) > ,
511+ tls_environment_mode : child_env:: TlsEnvironmentMode ,
509512 provider_env : & HashMap < String , String > ,
510513 ) -> Result < Self > {
511514 Self :: spawn_impl (
@@ -515,6 +518,7 @@ impl ProcessHandle {
515518 interactive,
516519 policy,
517520 ca_paths,
521+ tls_environment_mode,
518522 provider_env,
519523 )
520524 }
@@ -529,6 +533,7 @@ impl ProcessHandle {
529533 interactive : bool ,
530534 policy : & SandboxPolicy ,
531535 ca_paths : Option < & ( PathBuf , PathBuf ) > ,
536+ tls_environment_mode : child_env:: TlsEnvironmentMode ,
532537 provider_env : & HashMap < String , String > ,
533538 ) -> Result < Self > {
534539 let mut cmd = Command :: new ( program) ;
@@ -563,12 +568,13 @@ impl ProcessHandle {
563568 // inherited environment. The entrypoint drops to the sandbox user
564569 // before `exec`; without this strip, sandbox code could recover
565570 // supervisor credentials from its inherited environment.
571+ let user_environment = configured_user_environment ( ) ;
566572 apply_canonical_process_environment (
567573 & mut cmd,
568574 policy,
569575 workspace,
570576 interactive,
571- & configured_user_environment ( ) ,
577+ & user_environment ,
572578 ) ;
573579 strip_supervisor_only_env ( & mut cmd) ;
574580
@@ -580,9 +586,28 @@ impl ProcessHandle {
580586
581587 strip_proxy_env ( & mut cmd) ;
582588
583- // Set TLS trust store env vars so sandbox processes trust the ephemeral CA
589+ // In interception mode OpenShell trust is authoritative. In direct
590+ // additional-CA mode, retain all caller values and only fill gaps.
584591 if let Some ( ( ca_cert_path, combined_bundle_path) ) = ca_paths {
585- for ( key, value) in child_env:: tls_env_vars ( ca_cert_path, combined_bundle_path) {
592+ // Provider credentials are injected before this point. Reassert
593+ // caller TLS values in additive mode so a provider environment
594+ // cannot accidentally replace a caller-selected trust store.
595+ if matches ! (
596+ tls_environment_mode,
597+ child_env:: TlsEnvironmentMode :: FillMissing
598+ ) {
599+ for ( key, value) in & user_environment {
600+ if child_env:: is_tls_environment_variable ( key) {
601+ cmd. env ( key, value) ;
602+ }
603+ }
604+ }
605+ for ( key, value) in child_env:: tls_env_vars_for_mode (
606+ ca_cert_path,
607+ combined_bundle_path,
608+ tls_environment_mode,
609+ & user_environment,
610+ ) {
586611 cmd. env ( key, value) ;
587612 }
588613 }
@@ -694,6 +719,7 @@ impl ProcessHandle {
694719 interactive : bool ,
695720 policy : & SandboxPolicy ,
696721 ca_paths : Option < & ( PathBuf , PathBuf ) > ,
722+ tls_environment_mode : child_env:: TlsEnvironmentMode ,
697723 provider_env : & HashMap < String , String > ,
698724 ) -> Result < Self > {
699725 let mut cmd = Command :: new ( program) ;
@@ -728,12 +754,13 @@ impl ProcessHandle {
728754
729755 // Strip supervisor-only identity material from the entrypoint's
730756 // inherited environment.
757+ let user_environment = configured_user_environment ( ) ;
731758 apply_canonical_process_environment (
732759 & mut cmd,
733760 policy,
734761 workspace,
735762 interactive,
736- & configured_user_environment ( ) ,
763+ & user_environment ,
737764 ) ;
738765 strip_supervisor_only_env ( & mut cmd) ;
739766
@@ -745,9 +772,28 @@ impl ProcessHandle {
745772
746773 strip_proxy_env ( & mut cmd) ;
747774
748- // Set TLS trust store env vars so sandbox processes trust the ephemeral CA
775+ // In interception mode OpenShell trust is authoritative. In direct
776+ // additional-CA mode, retain all caller values and only fill gaps.
749777 if let Some ( ( ca_cert_path, combined_bundle_path) ) = ca_paths {
750- for ( key, value) in child_env:: tls_env_vars ( ca_cert_path, combined_bundle_path) {
778+ // Provider credentials are injected before this point. Reassert
779+ // caller TLS values in additive mode so a provider environment
780+ // cannot accidentally replace a caller-selected trust store.
781+ if matches ! (
782+ tls_environment_mode,
783+ child_env:: TlsEnvironmentMode :: FillMissing
784+ ) {
785+ for ( key, value) in & user_environment {
786+ if child_env:: is_tls_environment_variable ( key) {
787+ cmd. env ( key, value) ;
788+ }
789+ }
790+ }
791+ for ( key, value) in child_env:: tls_env_vars_for_mode (
792+ ca_cert_path,
793+ combined_bundle_path,
794+ tls_environment_mode,
795+ & user_environment,
796+ ) {
751797 cmd. env ( key, value) ;
752798 }
753799 }
0 commit comments