From 8ce300fb87e8b8d832a44fc1244dfb161ed3200c Mon Sep 17 00:00:00 2001 From: Drew Newberry Date: Fri, 9 Oct 2026 08:43:10 -0700 Subject: [PATCH] feat(isolation): expose trusted launch and registry data contracts Signed-off-by: Drew Newberry --- .../src/delegated.rs | 30 ++++++++++++ crates/openshell-sandbox-backend/src/lib.rs | 1 + .../openshell-supervisor/src/backend_setup.rs | 8 ++- .../src/backend_setup/registration.rs | 13 +++++ crates/openshell-supervisor/src/lib.rs | 49 ++++++++++--------- 5 files changed, 75 insertions(+), 26 deletions(-) create mode 100644 crates/openshell-sandbox-backend/src/delegated.rs create mode 100644 crates/openshell-supervisor/src/backend_setup/registration.rs diff --git a/crates/openshell-sandbox-backend/src/delegated.rs b/crates/openshell-sandbox-backend/src/delegated.rs new file mode 100644 index 000000000..8cde5f319 --- /dev/null +++ b/crates/openshell-sandbox-backend/src/delegated.rs @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Trusted launch metadata for an endpoint-registered Sandbox Protocol backend. + +use std::collections::BTreeMap; +use std::net::IpAddr; + +use openshell_core::SandboxSessionId; +use openshell_isolation_interface::contract::{OuterFenceGuarantees, ResolvedWorkloadIdentity}; +use serde::{Deserialize, Serialize}; + +use crate::boundary_protocol::SandboxTlsClientConfig; + +/// Delivered by the trusted driver separately from its opaque backend payload. +/// Endpoint selection belongs to operator configuration, not launch data. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct DelegatedLaunch { + pub backend_name: String, + pub sandbox_id: String, + pub generation: String, + pub session_id: SandboxSessionId, + pub workload_identity: ResolvedWorkloadIdentity, + pub tls: SandboxTlsClientConfig, + #[serde(default)] + pub host_gateway_ip: Option, + pub resource_claims: BTreeMap, + pub outer_fence: OuterFenceGuarantees, +} diff --git a/crates/openshell-sandbox-backend/src/lib.rs b/crates/openshell-sandbox-backend/src/lib.rs index 6baa4bf5a..c3a7a5b6e 100644 --- a/crates/openshell-sandbox-backend/src/lib.rs +++ b/crates/openshell-sandbox-backend/src/lib.rs @@ -9,6 +9,7 @@ //! types in this crate. pub mod boundary_protocol; +pub mod delegated; pub mod mediation; mod runtime; pub mod sandbox_auth; diff --git a/crates/openshell-supervisor/src/backend_setup.rs b/crates/openshell-supervisor/src/backend_setup.rs index 61fe5a71f..76570e41b 100644 --- a/crates/openshell-supervisor/src/backend_setup.rs +++ b/crates/openshell-supervisor/src/backend_setup.rs @@ -3,6 +3,9 @@ //! Backend-owned launch decoding and client construction for supervisor startup. +mod registration; +pub use registration::{BackendRegistration, BackendRegistrations}; + use std::path::PathBuf; use std::sync::{Arc, Mutex}; @@ -27,8 +30,9 @@ pub struct LaunchIdentity { pub vm_policy_identity: Option, } -/// Runtime state remains owned by the supervisor. Backends retain these same -/// handles so CA publication, provider reload, and bearer rotation stay visible +/// Runtime state remains owned by the supervisor. +/// +/// Backends retain these same handles so CA publication, provider reload, and bearer rotation stay visible /// after attachment; copying their current contents would lose later updates. pub struct BackendServices { pub ca_file_paths: Arc>>, diff --git a/crates/openshell-supervisor/src/backend_setup/registration.rs b/crates/openshell-supervisor/src/backend_setup/registration.rs new file mode 100644 index 000000000..b3dede3e4 --- /dev/null +++ b/crates/openshell-supervisor/src/backend_setup/registration.rs @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Operator-owned endpoint registration; launch payloads never select a route. + +pub use openshell_core::isolation_registration::BackendRegistration; +use serde::Deserialize; + +#[derive(Default, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct BackendRegistrations { + pub backends: Vec, +} diff --git a/crates/openshell-supervisor/src/lib.rs b/crates/openshell-supervisor/src/lib.rs index 8d498e162..43caf3605 100644 --- a/crates/openshell-supervisor/src/lib.rs +++ b/crates/openshell-supervisor/src/lib.rs @@ -16,7 +16,7 @@ compile_error!( ); mod activity_aggregator; -mod backend_setup; +pub mod backend_setup; mod denial_aggregator; mod endpoint_status; mod mechanistic_mapper; @@ -667,33 +667,34 @@ pub async fn run_sandbox( .await } -struct SandboxRunConfig { - command: Vec, - workdir: Option, - timeout_secs: u64, - interactive: bool, - await_main_process_attachment: bool, - sandbox_id: Option, - sandbox: Option, - openshell_endpoint: Option, - policy_rules: Option, - policy_data: Option, - ssh_socket_path: Option, - health_socket_path: Option, - health_port: Option, - ocsf_enabled: Arc, - ocsf_schema_version: Arc>, - upstream_proxy_args: openshell_supervisor_network::upstream_proxy::UpstreamProxyArgs, - backend_descriptor: openshell_isolation_interface::contract::BackendDescriptor, - auth_bundle: openshell_core::jwt::SupervisorAuthBundle, - admitted_isolation_backend: Option, - main_exit_marker: Option, +/// Trusted inputs for one supervisor launch. +pub struct SandboxRunConfig { + pub command: Vec, + pub workdir: Option, + pub timeout_secs: u64, + pub interactive: bool, + pub await_main_process_attachment: bool, + pub sandbox_id: Option, + pub sandbox: Option, + pub openshell_endpoint: Option, + pub policy_rules: Option, + pub policy_data: Option, + pub ssh_socket_path: Option, + pub health_socket_path: Option, + pub health_port: Option, + pub ocsf_enabled: Arc, + pub ocsf_schema_version: Arc>, + pub upstream_proxy_args: openshell_supervisor_network::upstream_proxy::UpstreamProxyArgs, + pub backend_descriptor: openshell_isolation_interface::contract::BackendDescriptor, + pub auth_bundle: openshell_core::jwt::SupervisorAuthBundle, + pub admitted_isolation_backend: Option, + pub main_exit_marker: Option, } /// Trusted composition chooses the setup before shared admission, policy, and /// lifecycle handling. Payload contents never select a backend implementation. #[allow(clippy::similar_names)] -async fn run_sandbox_with_backend( +pub async fn run_sandbox_with_backend( backend_setup: &dyn backend_setup::BackendSetup, config: SandboxRunConfig, ) -> Result { @@ -2141,7 +2142,7 @@ enum LocalPolicyIdentity { /// init maps the `sandbox` account to this pair; the host must not resolve /// guest selectors through its own account database. #[derive(Clone, Copy)] -struct VmPolicyIdentity { +pub struct VmPolicyIdentity { uid: u32, gid: u32, }