@@ -11,6 +11,7 @@ use std::path::PathBuf;
1111use openshell_core:: ComputeDriverError ;
1212use openshell_core:: proto:: compute:: v1:: DriverSandbox ;
1313use openshell_isolation_interface:: contract:: { DriverFenceEvidence , ResolvedWorkloadIdentity } ;
14+ use openshell_sandbox_backend:: ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM ;
1415use openshell_sandbox_backend:: boundary_protocol:: {
1516 BoundaryConfig , BoundaryListener , GatewayVerificationKey , SandboxRuntimeDescriptor ,
1617 SandboxTlsClientConfig , SandboxTlsServerConfig , SandboxTransport ,
@@ -25,7 +26,6 @@ pub const BOOTSTRAP_PATH: &str = "/.openshell/channel/sandbox/bootstrap.json";
2526pub const RUNTIME_DESCRIPTOR_PATH : & str = "/.openshell/supervisor/runtime-descriptor.json" ;
2627pub const AUTH_BUNDLE_PATH : & str = "/.openshell/supervisor/auth.json" ;
2728pub const RESTART_METADATA_PATH : & str = "/.openshell/supervisor/restart-metadata.json" ;
28- pub const USERNS_RESOURCE_CLAIM : & str = "podman.userns" ;
2929const SOCKET_PATH : & str = "/.openshell/channel/sandbox/control.sock" ;
3030
3131pub fn supervisor_name ( id : & str ) -> String {
@@ -35,6 +35,12 @@ pub fn channel_volume_name(id: &str) -> String {
3535 format ! ( "openshell-channel-{id}" )
3636}
3737
38+ /// `keep-id` may retain the gateway user's supplementary groups in the
39+ /// container. Other user-namespace modes, including `auto`, do not.
40+ pub fn userns_preserves_host_groups ( userns : Option < & str > ) -> bool {
41+ userns. is_some_and ( |mode| mode. split ( ':' ) . next ( ) == Some ( "keep-id" ) )
42+ }
43+
3844fn invalid ( error : impl std:: fmt:: Display ) -> ComputeDriverError {
3945 ComputeDriverError :: Precondition ( error. to_string ( ) )
4046}
@@ -160,7 +166,7 @@ pub fn bootstrap_archives(
160166 container_id : & str ,
161167 generation : & str ,
162168 identity : & ResolvedWorkloadIdentity ,
163- userns : Option < & str > ,
169+ allow_extra_supplementary_groups : bool ,
164170 child_env : HashMap < String , String > ,
165171 launch_authentication : & openshell_core:: jwt:: SandboxLaunchAuthentication ,
166172) -> Result < BootstrapArchives , ComputeDriverError > {
@@ -174,8 +180,11 @@ pub fn bootstrap_archives(
174180 identity. resource_digest . clone ( ) ,
175181 ) ,
176182 ] ) ;
177- if userns. is_some_and ( |mode| mode. split ( ':' ) . next ( ) == Some ( "keep-id" ) ) {
178- resource_claims. insert ( USERNS_RESOURCE_CLAIM . into ( ) , "keep-id" . into ( ) ) ;
183+ if allow_extra_supplementary_groups {
184+ resource_claims. insert (
185+ ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM . into ( ) ,
186+ "true" . into ( ) ,
187+ ) ;
179188 }
180189 let driver_fence = DriverFenceEvidence :: Podman {
181190 container_id : container_id. into ( ) ,
@@ -439,7 +448,7 @@ mod tests {
439448 "container" ,
440449 "generation-1" ,
441450 & identity,
442- None ,
451+ false ,
443452 child_env. clone ( ) ,
444453 & authentication,
445454 )
@@ -481,6 +490,11 @@ mod tests {
481490 assert_eq ! ( config. session_id, runtime_descriptor. session_id) ;
482491 assert_eq ! ( config. driver_fence, runtime_descriptor. driver_fence) ;
483492 assert_eq ! ( config. workload_identity, identity) ;
493+ assert ! (
494+ !config
495+ . resource_claims
496+ . contains_key( ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM )
497+ ) ;
484498 runtime_descriptor. driver_fence . validate ( ) . unwrap ( ) ;
485499 let restart_metadata: RestartMetadata = serde_json:: from_slice (
486500 supervisor
@@ -499,4 +513,15 @@ mod tests {
499513 . any( |window| window == b"PRIVATE KEY" )
500514 ) ;
501515 }
516+
517+ #[ test]
518+ fn keep_id_is_the_only_userns_mode_that_preserves_host_groups ( ) {
519+ assert ! ( userns_preserves_host_groups( Some ( "keep-id" ) ) ) ;
520+ assert ! ( userns_preserves_host_groups( Some (
521+ "keep-id:uid=1000,gid=1000"
522+ ) ) ) ;
523+ assert ! ( !userns_preserves_host_groups( Some ( "auto" ) ) ) ;
524+ assert ! ( !userns_preserves_host_groups( Some ( "private" ) ) ) ;
525+ assert ! ( !userns_preserves_host_groups( None ) ) ;
526+ }
502527}
0 commit comments