Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/openshell-core/src/extension_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub const COMPUTE_SUSPEND_RESUME: &str = "openshell.compute.suspend-resume";
/// Optional stopped-state workload configuration updates retaining the resource and storage.
pub const COMPUTE_UPDATE_SANDBOX_CONFIGURATION: &str =
"openshell.compute.update-sandbox-configuration";
/// Driver declares the proxy prerequisites admitted before runtime signing.
pub const COMPUTE_PROXY_FILESYSTEM_BASELINE: &str = "openshell.compute.proxy-filesystem-baseline";

const MAX_IMPLEMENTATION_NAME_BYTES: usize = 128;
const MAX_IMPLEMENTATION_VERSION_BYTES: usize = 128;
Expand Down Expand Up @@ -133,6 +135,7 @@ pub fn gateway_metadata(family: ExtensionFamily) -> PeerMetadata {
supported_capabilities.push(COMPUTE_LAUNCH_AUTHENTICATION.to_string());
supported_capabilities.push(COMPUTE_ISOLATION_BACKEND.to_string());
supported_capabilities.push(COMPUTE_UPDATE_SANDBOX_CONFIGURATION.to_string());
supported_capabilities.push(COMPUTE_PROXY_FILESYSTEM_BASELINE.to_string());
}
PeerMetadata {
protocol_version: Some(ProtocolVersion {
Expand Down
101 changes: 101 additions & 0 deletions crates/openshell-core/src/filesystem_baseline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

//! Trusted backend prerequisites composed before effective policy admission.

use std::collections::BTreeSet;

use crate::proto::SandboxPolicy;
use crate::proto::compute::v1::ProxyFilesystemBaseline;

/// Proxy runtime paths selected by trusted backend composition.
/// An explicit empty baseline suppresses legacy defaults.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct FilesystemBaseline {
pub read_only: Vec<String>,
pub read_write: Vec<String>,
}

impl From<ProxyFilesystemBaseline> for FilesystemBaseline {
fn from(value: ProxyFilesystemBaseline) -> Self {
Self {
read_only: value.read_only,
read_write: value.read_write,
}
}
}

impl From<FilesystemBaseline> for ProxyFilesystemBaseline {
fn from(value: FilesystemBaseline) -> Self {
Self {
read_only: value.read_only,
read_write: value.read_write,
}
}
}

impl FilesystemBaseline {
/// Validate bounded, canonical POSIX path syntax without inspecting the
/// gateway host filesystem, which need not be the workload's platform.
pub fn validate(&self) -> Result<(), &'static str> {
if self.read_only.len() + self.read_write.len() > 64 {
return Err("proxy filesystem baseline has too many paths");
}
let mut seen = BTreeSet::new();
for path in self.read_only.iter().chain(&self.read_write) {
if path.len() > 4096
|| !path.starts_with('/')
|| path.chars().any(char::is_control)
|| (path != "/"
&& path[1..]
.split('/')
.any(|part| matches!(part, "" | "." | "..")))
|| !seen.insert(path)
{
return Err(
"proxy filesystem baseline requires unique canonical POSIX absolute paths",
);
}
}
Ok(())
}

/// Add prerequisites to a proxy-mode policy without replacing explicit
/// grants. An explicit read-only path stays read-only. `path_exists` is
/// used only by legacy image-local Linux defaults; advertised prerequisites
/// are unconditional and callers pass a predicate that always returns true.
/// Validate the descriptor at the trusted admission boundary before use.
pub fn enrich(&self, policy: &mut SandboxPolicy, path_exists: impl Fn(&str) -> bool) -> bool {
if policy.network_policies.is_empty()
|| (self.read_only.is_empty() && self.read_write.is_empty())
{
return false;
}
let filesystem = policy
.filesystem
.get_or_insert_with(|| crate::proto::FilesystemPolicy {
include_workdir: true,
..Default::default()
});
let mut modified = false;
for path in &self.read_only {
if !filesystem.read_only.contains(path)
&& !filesystem.read_write.contains(path)
&& path_exists(path)
{
filesystem.read_only.push(path.clone());
modified = true;
}
}
for path in &self.read_write {
if !filesystem.read_only.contains(path)
&& !filesystem.read_write.contains(path)
&& path_exists(path)
{
filesystem.read_write.push(path.clone());
modified = true;
}
}
modified
}
}
1 change: 1 addition & 0 deletions crates/openshell-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub mod error;
pub mod extension_protocol;
#[cfg(unix)]
pub mod external_driver_socket;
pub mod filesystem_baseline;
pub mod forward;
pub mod google_cloud;
pub mod gpu;
Expand Down
1 change: 1 addition & 0 deletions crates/openshell-driver-docker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,7 @@ impl DockerComputeDriver {
}),
rootfs_tar_staging_dir: String::new(),
rootfs_tar_max_bytes: 0,
proxy_filesystem_baseline: None,
extension: Some(openshell_core::extension_protocol::extension_metadata(
openshell_core::extension_protocol::ExtensionFamily::Compute,
"openshell/docker",
Expand Down
1 change: 1 addition & 0 deletions crates/openshell-driver-kubernetes/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,7 @@ impl KubernetesComputeDriver {
}),
rootfs_tar_staging_dir: String::new(),
rootfs_tar_max_bytes: 0,
proxy_filesystem_baseline: None,
extension: Some(openshell_core::extension_protocol::extension_metadata(
openshell_core::extension_protocol::ExtensionFamily::Compute,
"openshell/kubernetes",
Expand Down
1 change: 1 addition & 0 deletions crates/openshell-driver-mxc/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ impl MxcComputeBackend {
resource_capabilities: None,
rootfs_tar_staging_dir: String::new(),
rootfs_tar_max_bytes: 0,
proxy_filesystem_baseline: None,
extension: Some(openshell_core::extension_protocol::extension_metadata(
openshell_core::extension_protocol::ExtensionFamily::Compute,
"openshell/mxc",
Expand Down
1 change: 1 addition & 0 deletions crates/openshell-driver-podman/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,7 @@ impl PodmanComputeDriver {
}),
rootfs_tar_staging_dir: String::new(),
rootfs_tar_max_bytes: 0,
proxy_filesystem_baseline: None,
extension: Some(openshell_core::extension_protocol::extension_metadata(
openshell_core::extension_protocol::ExtensionFamily::Compute,
"openshell/podman",
Expand Down
1 change: 1 addition & 0 deletions crates/openshell-driver-vm/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,7 @@ impl VmDriver {
.to_string_lossy()
.into_owned(),
rootfs_tar_max_bytes: self.config.rootfs_tar_max_bytes(),
proxy_filesystem_baseline: None,
extension: Some(extension),
}
}
Expand Down
Loading
Loading