From 44e2ab638e7a1867d0f41038b854ba5aa4c671d0 Mon Sep 17 00:00:00 2001 From: Ryan Whitworth Date: Tue, 31 Mar 2026 22:14:54 -0400 Subject: [PATCH 1/3] Require OPENSHELL_ALLOW_INSECURE=1 to confirm --disable-tls --- crates/openshell-server/src/main.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/openshell-server/src/main.rs b/crates/openshell-server/src/main.rs index 4dd8e9e92..9acef6ccd 100644 --- a/crates/openshell-server/src/main.rs +++ b/crates/openshell-server/src/main.rs @@ -139,6 +139,15 @@ async fn main() -> Result<()> { let args = Args::parse(); + // Require explicit acknowledgment for insecure mode. + if args.disable_tls && std::env::var("OPENSHELL_ALLOW_INSECURE").as_deref() != Ok("1") { + eprintln!( + "ERROR: --disable-tls removes all transport security.\n\ + Set OPENSHELL_ALLOW_INSECURE=1 to confirm." + ); + std::process::exit(1); + } + // Initialize tracing let tracing_log_bus = TracingLogBus::new(); tracing_log_bus.install_subscriber( @@ -229,6 +238,7 @@ async fn main() -> Result<()> { } if args.disable_tls { + eprintln!("WARNING: TLS disabled — all traffic is plaintext"); info!("TLS disabled — listening on plaintext HTTP"); } else if args.disable_gateway_auth { info!("Gateway auth disabled — accepting connections without client certificates"); From 6a2d58018854e92d38ded88d91f28647a802c20b Mon Sep 17 00:00:00 2001 From: Ryan Whitworth Date: Tue, 31 Mar 2026 22:15:10 -0400 Subject: [PATCH 2/3] Verify sandbox identity on GetSandboxProviderEnvironment calls --- crates/openshell-server/src/grpc.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/crates/openshell-server/src/grpc.rs b/crates/openshell-server/src/grpc.rs index 450685ff0..ad126fd56 100644 --- a/crates/openshell-server/src/grpc.rs +++ b/crates/openshell-server/src/grpc.rs @@ -901,8 +901,25 @@ impl OpenShell for OpenShellService { &self, request: Request, ) -> Result, Status> { + // Verify caller identity: the requesting sandbox must only access its + // own provider environment. The x-sandbox-id metadata header is set by + // the sandbox supervisor when it calls back to the gateway. + let caller_sandbox_id = request + .metadata() + .get("x-sandbox-id") + .and_then(|v| v.to_str().ok()) + .map(String::from); + let sandbox_id = request.into_inner().sandbox_id; + if let Some(ref caller) = caller_sandbox_id { + if caller != &sandbox_id { + return Err(Status::permission_denied( + "cannot access another sandbox's provider environment", + )); + } + } + let sandbox = self .state .store From 56c8d4e96b85af8e165d265a37408d9429293ebc Mon Sep 17 00:00:00 2001 From: Ryan Whitworth Date: Tue, 31 Mar 2026 23:25:26 -0400 Subject: [PATCH 3/3] Require x-sandbox-id header; reject requests without it The previous check silently skipped authorization when the header was absent, allowing any caller to read any sandbox's credentials. --- crates/openshell-server/src/grpc.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/openshell-server/src/grpc.rs b/crates/openshell-server/src/grpc.rs index ad126fd56..3ed2fad0a 100644 --- a/crates/openshell-server/src/grpc.rs +++ b/crates/openshell-server/src/grpc.rs @@ -908,16 +908,14 @@ impl OpenShell for OpenShellService { .metadata() .get("x-sandbox-id") .and_then(|v| v.to_str().ok()) - .map(String::from); + .ok_or_else(|| Status::permission_denied("missing x-sandbox-id header"))?; let sandbox_id = request.into_inner().sandbox_id; - if let Some(ref caller) = caller_sandbox_id { - if caller != &sandbox_id { - return Err(Status::permission_denied( - "cannot access another sandbox's provider environment", - )); - } + if caller_sandbox_id != sandbox_id { + return Err(Status::permission_denied( + "cannot access another sandbox's provider environment", + )); } let sandbox = self