Skip to content

Commit e889339

Browse files
committed
docs(mxc): clarify mapper schema versions
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
1 parent 3451e72 commit e889339

7 files changed

Lines changed: 65 additions & 21 deletions

File tree

‎crates/openshell-driver-mxc/src/lib.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub use relay::RelayHandle;
5151
pub use policy::{EmbeddedPolicyMapper, MapCtx, MapError, MappedConfig, PolicyMapper};
5252
#[cfg(target_os = "windows")]
5353
pub use policy_map::{
54-
DEFAULT_COMMAND, DEFAULT_CONTAINMENT, DEFAULT_MXC_VERSION, LossItem, MxcMappingOptions,
55-
MxcMappingResult, OPEN_SHELL_SUPERSET_GAPS, SplitPolicyResult, build_loss_report, map_to_mxc,
56-
render_readme, split_policy,
54+
DEFAULT_COARSE_MXC_VERSION, DEFAULT_COMMAND, DEFAULT_CONTAINMENT, DEFAULT_MXC_VERSION,
55+
LossItem, MxcMappingOptions, MxcMappingResult, OPEN_SHELL_SUPERSET_GAPS, SplitPolicyResult,
56+
build_loss_report, map_to_mxc, render_readme, split_policy,
5757
};

‎crates/openshell-driver-mxc/src/policy.rs‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
//! the standalone `openshell-policy-mapper` crate). This file defines the trait
99
//! seam plus:
1010
//!
11-
//! - [`EmbeddedPolicyMapper`] — the **primary** impl. Calls
12-
//! [`crate::policy_map::map_to_mxc`] directly on the typed `SandboxPolicy`
13-
//! proto (no YAML bridge), extracts the MXC filesystem shares, normalizes
14-
//! their paths to Windows form, and rejects the create on any `error`-severity
15-
//! loss.
11+
//! - [`EmbeddedPolicyMapper`] — the **primary** impl. Calls the coarse mapper or
12+
//! governed-egress split directly on the typed `SandboxPolicy` proto (no YAML
13+
//! bridge), extracts the MXC filesystem/UI fragment, normalizes paths, and
14+
//! rejects the create on any `error`-severity loss. The generated mapping JSON
15+
//! is an intermediate representation: live requests are rebuilt by
16+
//! [`crate::mxc`] using its active schema version.
1617
//!
1718
//! **Rule: never silently drop policy.** Unmappable rules surface as
1819
//! `MapError::Unsupported` and are rejected by `CreateSandbox` before lifecycle side effects.
@@ -181,7 +182,8 @@ impl PolicyMapper for EmbeddedPolicyMapper {
181182
// Map directly off the typed proto. The default MXC driver path runs
182183
// an isolation session, so use that containment: its network branch
183184
// yields an `error` loss for any host allowlist, which rejects
184-
// network policy below.
185+
// network policy below. This coarse JSON is never sent to wxc-exec;
186+
// only the extracted filesystem/UI policy enters the live request.
185187
let opts = crate::policy_map::MxcMappingOptions {
186188
containment: ctx.containment.clone(),
187189
container_id: ctx.sandbox_id.clone(),

‎crates/openshell-driver-mxc/src/policy_map/config.rs‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,18 @@ use super::loss::{LossItem, add_loss};
1212
/// not supply a real workload command.
1313
pub const DEFAULT_COMMAND: &str = "sh -lc \"echo OpenShell policy mapped to MXC; replace process.commandLine before running a real workload\"";
1414

15-
/// Default MXC schema version emitted in `version`.
16-
pub const DEFAULT_MXC_VERSION: &str = "0.7.0-alpha";
15+
/// Default schema for the standalone coarse mapper's host-list config.
16+
///
17+
/// This is deliberately independent from [`crate::mxc::MXC_SCHEMA_VERSION`]:
18+
/// the coarse artifact uses the MXC 0.7 `allowedHosts` shape, while live driver
19+
/// requests and the governed-egress split use MXC 0.8 directional networking.
20+
pub const DEFAULT_COARSE_MXC_VERSION: &str = "0.7.0-alpha";
21+
22+
/// Compatibility name for [`DEFAULT_COARSE_MXC_VERSION`].
23+
///
24+
/// This value belongs only to [`super::map_to_mxc`] output. It is not the
25+
/// schema version used for live `wxc-exec` requests.
26+
pub const DEFAULT_MXC_VERSION: &str = DEFAULT_COARSE_MXC_VERSION;
1727

1828
/// Default MXC containment backend for the coarse mapping.
1929
pub const DEFAULT_CONTAINMENT: &str = "bubblewrap";

‎crates/openshell-driver-mxc/src/policy_map/map.rs‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use openshell_core::proto::{
1717
use serde_json::{Value, json};
1818

1919
use super::config::{
20-
DEFAULT_COMMAND, DEFAULT_CONTAINMENT, DEFAULT_MXC_VERSION, add_backend_network_loss,
20+
DEFAULT_COARSE_MXC_VERSION, DEFAULT_COMMAND, DEFAULT_CONTAINMENT, add_backend_network_loss,
2121
add_backend_specific_config, default_enforcement_mode, filesystem_default_deny_message,
2222
};
2323
use super::loss::{LossItem, add_loss};
@@ -27,8 +27,9 @@ use crate::mxc::MXC_SCHEMA_VERSION;
2727
/// coarse map (e.g. `proxy_redirect`) are reserved for the governed-egress split.
2828
#[derive(Clone, Debug)]
2929
pub struct MxcMappingOptions {
30-
/// MXC schema version written into coarse-map output. The governed-egress
31-
/// split uses the driver's MXC 0.8 schema.
30+
/// Caller-selectable schema version written only into standalone coarse-map
31+
/// output. The governed-egress split and live driver requests instead use
32+
/// [`MXC_SCHEMA_VERSION`].
3233
pub mxc_version: String,
3334
/// MXC containment backend.
3435
pub containment: String,
@@ -52,7 +53,7 @@ pub struct MxcMappingOptions {
5253
impl Default for MxcMappingOptions {
5354
fn default() -> Self {
5455
Self {
55-
mxc_version: DEFAULT_MXC_VERSION.to_owned(),
56+
mxc_version: DEFAULT_COARSE_MXC_VERSION.to_owned(),
5657
containment: DEFAULT_CONTAINMENT.to_owned(),
5758
command: DEFAULT_COMMAND.to_owned(),
5859
container_id: "openshell-policy".to_owned(),

‎crates/openshell-driver-mxc/src/policy_map/mod.rs‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@
1717
//! policy is flattened into an MXC host allowlist (`network.allowedHosts`),
1818
//! and anything MXC cannot express (ports, protocol, L7 rules, binary scope)
1919
//! is recorded in the loss report. Use this when MXC enforces network on its
20-
//! own, with no `OpenShell` proxy in the loop.
20+
//! own, with no `OpenShell` proxy in the loop. Its default schema is MXC 0.7,
21+
//! matching that host-list shape; the caller can override the coarse target.
2122
//! - [`split_policy`] — the *lossless* split for the Windows MXC compute
2223
//! driver: MXC handles filesystem + containment + loopback-only egress,
2324
//! while the full `OpenShell` network policy is preserved in a trimmed policy
24-
//! enforced by the host CONNECT proxy.
25+
//! enforced by the host CONNECT proxy. This path uses the live driver's MXC
26+
//! 0.8 directional-network schema.
27+
//!
28+
//! The coarse mapper's schema version describes its generated artifact, not the
29+
//! live driver's operating schema. The embedded driver may use a coarse mapping
30+
//! as an intermediate policy translation but does not send that JSON to MXC.
2531
//!
2632
//! The report/loss-report helpers are only exercised by the example and the
2733
//! integration tests, so the Windows lib build would otherwise warn on them;
@@ -36,7 +42,9 @@ mod loss;
3642
mod map;
3743
mod report;
3844

39-
pub use config::{DEFAULT_COMMAND, DEFAULT_CONTAINMENT, DEFAULT_MXC_VERSION};
45+
pub use config::{
46+
DEFAULT_COARSE_MXC_VERSION, DEFAULT_COMMAND, DEFAULT_CONTAINMENT, DEFAULT_MXC_VERSION,
47+
};
4048
pub use loss::{LossItem, OPEN_SHELL_SUPERSET_GAPS};
4149
pub use map::{MxcMappingOptions, MxcMappingResult, SplitPolicyResult, map_to_mxc, split_policy};
4250
pub use report::{build_loss_report, render_readme};

‎crates/openshell-driver-mxc/src/policy_map/report.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ use serde_json::{Value, json};
77

88
use super::loss::{LossItem, OPEN_SHELL_SUPERSET_GAPS, summarize_missing_mxc};
99

10-
/// Build the structured `loss-report.json` value.
10+
/// Build the structured `loss-report.json` value for a generated mapper artifact.
11+
///
12+
/// `target.schemaVersion` describes that artifact's caller-selected schema. It
13+
/// must not be interpreted as the live MXC driver's request schema.
1114
pub fn build_loss_report(
1215
source_policy: &str,
1316
generated_config: &str,

‎crates/openshell-driver-mxc/tests/policy_mapper_matrix.rs‎

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use openshell_core::proto::{
2727
NetworkPolicyRule, ProcessPolicy, SandboxPolicy, UiClipboardAccess, UiPolicy,
2828
};
2929
use openshell_driver_mxc::{
30-
EmbeddedPolicyMapper, MapCtx, MapError, MxcMappingOptions, PolicyMapper, map_to_mxc,
31-
split_policy,
30+
DEFAULT_COARSE_MXC_VERSION, DEFAULT_MXC_VERSION, EmbeddedPolicyMapper, MapCtx, MapError,
31+
MxcMappingOptions, PolicyMapper, map_to_mxc, split_policy,
3232
};
3333
use openshell_policy::{serialize_sandbox_policy, validate_sandbox_policy};
3434
use serde_json::Value;
@@ -132,6 +132,26 @@ fn assert_single_loss(
132132

133133
// ─── QUADRANT A: mappable fields, assert exact MXC output ───────────────────
134134

135+
/// The standalone coarse mapper and live governed-egress path intentionally
136+
/// target different schema shapes. Keep the compatibility constant scoped to
137+
/// the coarse artifact and prevent either side from silently drifting.
138+
#[test]
139+
fn a_schema_versions_match_their_distinct_network_shapes() {
140+
let policy = SandboxPolicy::default();
141+
let coarse = map_to_mxc(&policy, &default_opts()).config;
142+
assert_eq!(DEFAULT_MXC_VERSION, DEFAULT_COARSE_MXC_VERSION);
143+
assert_eq!(coarse["version"], DEFAULT_COARSE_MXC_VERSION);
144+
assert!(coarse["network"].get("allowedHosts").is_some());
145+
assert!(coarse["network"].get("egress").is_none());
146+
147+
let governed = split_policy(&policy, &pc_split_opts())
148+
.expect("governed split must exist when a proxy redirect is configured")
149+
.mxc_config;
150+
assert_eq!(governed["version"], "0.8.0-alpha");
151+
assert!(governed["network"].get("allowedHosts").is_none());
152+
assert!(governed["network"].get("egress").is_some());
153+
}
154+
135155
/// filesystem.read_write → readwritePaths verbatim, order preserved.
136156
#[test]
137157
fn a_rw_paths_verbatim() {

0 commit comments

Comments
 (0)