@@ -13,6 +13,7 @@ use openshell_core::proto::compute::v1::DriverSandbox;
1313use openshell_isolation_interface:: contract:: {
1414 OuterFenceGuarantee , OuterFenceGuarantees , ResolvedWorkloadIdentity ,
1515} ;
16+ use openshell_sandbox_backend:: ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM ;
1617use openshell_sandbox_backend:: boundary_protocol:: {
1718 BoundaryConfig , BoundaryListener , GatewayVerificationKey , SandboxRuntimeDescriptor ,
1819 SandboxTlsClientConfig , SandboxTlsServerConfig , SandboxTransport ,
@@ -70,6 +71,12 @@ pub fn channel_volume_name(id: &str) -> String {
7071 format ! ( "openshell-channel-{id}" )
7172}
7273
74+ /// `keep-id` may retain the gateway user's supplementary groups in the
75+ /// container. Other user-namespace modes, including `auto`, do not.
76+ pub fn userns_preserves_host_groups ( userns : Option < & str > ) -> bool {
77+ userns. is_some_and ( |mode| mode. split ( ':' ) . next ( ) == Some ( "keep-id" ) )
78+ }
79+
7380fn invalid ( error : impl std:: fmt:: Display ) -> ComputeDriverError {
7481 ComputeDriverError :: Precondition ( error. to_string ( ) )
7582}
@@ -195,19 +202,26 @@ pub fn bootstrap_archives(
195202 container_id : & str ,
196203 generation : & str ,
197204 identity : & ResolvedWorkloadIdentity ,
205+ allow_extra_supplementary_groups : bool ,
198206 child_env : HashMap < String , String > ,
199207 launch_authentication : & openshell_core:: jwt:: SandboxLaunchAuthentication ,
200208) -> Result < BootstrapArchives , ComputeDriverError > {
201209 launch_authentication. validate ( ) . map_err ( invalid) ?;
202210 let session_id = launch_authentication. supervisor . session_id ;
203211 let tls = generate_sandbox_tls_material ( session_id) . map_err ( invalid) ?;
204- let resource_claims = BTreeMap :: from ( [
212+ let mut resource_claims = BTreeMap :: from ( [
205213 ( "podman.container_id" . into ( ) , container_id. into ( ) ) ,
206214 (
207215 "podman.image_identity" . into ( ) ,
208216 identity. resource_digest . clone ( ) ,
209217 ) ,
210218 ] ) ;
219+ if allow_extra_supplementary_groups {
220+ resource_claims. insert (
221+ ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM . into ( ) ,
222+ "true" . into ( ) ,
223+ ) ;
224+ }
211225 let runtime_generation = launch_authentication
212226 . supervisor
213227 . runtime_generation
@@ -496,6 +510,7 @@ mod tests {
496510 "container" ,
497511 "generation-1" ,
498512 & identity,
513+ false ,
499514 child_env. clone ( ) ,
500515 & authentication,
501516 )
@@ -541,6 +556,11 @@ mod tests {
541556 . outer_fence
542557 . validate ( & runtime_descriptor. generation )
543558 . unwrap ( ) ;
559+ assert ! (
560+ !config
561+ . resource_claims
562+ . contains_key( ALLOW_EXTRA_SUPPLEMENTARY_GROUPS_RESOURCE_CLAIM )
563+ ) ;
544564 let restart_metadata: RestartMetadata = serde_json:: from_slice (
545565 supervisor
546566 . get ( & PathBuf :: from (
@@ -558,4 +578,15 @@ mod tests {
558578 . any( |window| window == b"PRIVATE KEY" )
559579 ) ;
560580 }
581+
582+ #[ test]
583+ fn keep_id_is_the_only_userns_mode_that_preserves_host_groups ( ) {
584+ assert ! ( userns_preserves_host_groups( Some ( "keep-id" ) ) ) ;
585+ assert ! ( userns_preserves_host_groups( Some (
586+ "keep-id:uid=1000,gid=1000"
587+ ) ) ) ;
588+ assert ! ( !userns_preserves_host_groups( Some ( "auto" ) ) ) ;
589+ assert ! ( !userns_preserves_host_groups( Some ( "private" ) ) ) ;
590+ assert ! ( !userns_preserves_host_groups( None ) ) ;
591+ }
561592}
0 commit comments