Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ The workspace is organized into six top-level directories under `src/`:
- `wxc_common` is the **cross-platform foundation**: config parsing, models, errors, logger, `ScriptRunner` / `StatefulSandboxBackend` traits, state-aware dispatch helpers, validators, ids, ui-policy, encoding. Plus a few thin Windows API helpers shared by host tools and backends (`process_util`, `string_util`, `filesystem_dacl`, `diagnostic`). It must not depend on any `backends/*` crate.
- Each Windows containment backend lives in its own `backends/*/common` crate (e.g. `appcontainer_common`, `windows_sandbox_common`, `isolation_session_common`, `hyperlight_common`, `nanvix_runner`). Backend crates depend on `wxc_common`; there are no cross-edges between backend crates. Windows Sandbox additionally has `windows_sandbox_lifecycle`, which owns the one-shot and state-aware runners and depends on `windows_sandbox_common` for the wire protocol, plus separate daemon and guest binaries.
- `learning_mode_core` is the cross-platform learning-mode denial model and output layer. It owns denial types, summaries, analyzer abstractions, plain-JSON document emission, and the serializable output-pointer type, and must not depend on any `backends/*` crate.
- `learning_mode_windows` (`backends/learning_mode/windows`) is a Windows-only backend support crate for the AppInfo-brokered Learning Mode APIs in `processmodel.dll`. It runtime-resolves the Learning Mode trace and process security-environment exports, owns their typed handle/lifecycle wrappers, decodes sealed ETL traces through `learning_mode_core`, and depends on `wxc_common` plus `learning_mode_core`; runner integration consumes it from the AppContainer backend layer.
- `learning_mode_windows` (`backends/learning_mode/windows`) is a Windows-only backend support crate for the AppInfo-brokered Learning Mode APIs in `processmodel.dll`. It runtime-resolves the Learning Mode trace and process security-environment exports, owns their typed handle/lifecycle wrappers, decodes sealed ETL traces through `learning_mode_core`, and depends on `wxc_common` plus `learning_mode_core`; runner integration consumes it from the AppContainer backend layer. The trace contract is `HRESULT Start` + retryable `HRESULT Stop` + infallible `Close`: `Stop` never consumes the trace handle, and every started trace must be closed exactly once (closing without stopping is the early-exit discard path). The process security-environment contract is `HRESULT Create` + infallible by-value `Close` and consumes a PSEC 1.0 FlatBuffer, not the legacy SBOX buffer; generated PSEC bindings live in `core/generated/process_security_environment_specification`.
- `wxc`, `lxc`, and `mxc_darwin` are thin binary crates (`wxc-exec` / `lxc-exec` / `mxc-exec-mac`) that wire up CLI args (`clap`), load/validate config, handle maintenance modes (`--probe`, `--delete`, `--setup-*`, `--audit`), and **delegate all backend dispatch to `mxc_engine`**. They contain no `match request.containment` of their own. `wxc-exec` additionally owns the Windows Ctrl-C / DACL-cleanup / `--audit` PLM-trace / telemetry orchestration around the engine call.
- `mxc_engine` is the **single execution engine** β€” the one home for "given an `ExecutionRequest`, run it". It owns: run-to-completion backend selection (`run` / `resolve_runner`, covering **all** backends, incl. the Windows ProcessContainer BaseContainer/AppContainer BFS/DACL fallback tiers via `appcontainer_common::dispatcher::dispatch_with_fallback`, and every experimental backend, feature-gated); streaming (`spawn` β†’ `Box<dyn SandboxProcess>`); state-aware lifecycle dispatch (`run_state_aware`, including Windows Sandbox and IsolationSession); host probing (`platform_support` / `PlatformSupport`); and config building (`build_request`, `SandboxPolicy` + sections, `available_tools_policy`/`user_profile_policy`/`temporary_files_policy`). It depends on the backend crates (cfg-split: appcontainer/windows_sandbox lifecycle/isolation_session/wslc/nanvix on Windows, bubblewrap/lxc/nanvix on Linux, seatbelt on macOS) so it can't live in `wxc_common`. Both the executor binaries and `mxc-sdk` call into it. `ResolvedRunner` carries the boxed runner plus (Windows only) the optional `DaclManager` guard, so `wxc-exec` can park the guard for its signal handler.
- `mxc-sdk` is the **public Rust SDK** β€” a thin facade over `mxc_engine`. Build a `SandboxRequest` with `build_request`, then either `run(request)` (run-to-completion; returns an `Output` with the `WaitOutcome`, captured `stdout`/`stderr`, warnings, and optional structured output metadata) or `spawn_sandbox(request)` (returns a `Sandbox` handle for live bidirectional stdio β€” `take_stdin`/`take_stdout`/`take_stderr`, `kill()`, `wait()` returning a `WaitOutcome` (`Exited(i32)` / `TimedOut`) as `io::Result`, `output_metadata()` after terminal completion, or `wait_with_output()`). It re-exports the engine's config-building surface (`build_request`, `mxc_sdk::policy::{SandboxPolicy sections}`, discovery helpers) and `platform_support`; `mod sandbox` (wrapping the engine's `SandboxProcess` in `Sandbox`) is its only local module. No pty is ever allocated. Streaming supports Seatbelt (macOS), Bubblewrap (Linux), and Windows ProcessContainer (AppContainer + BaseContainer); other backends return `ErrorCode::UnsupportedContainment`.
Expand Down
10 changes: 10 additions & 0 deletions docs/learning-mode/capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,16 @@ ungranted access is handled while it is recorded:
> build exposing the BaseContainer security-environment and Learning Mode APIs.
> It is not supported by the AppContainer fallback tiers; unsupported hosts
> return `backend_unavailable`.
>
Comment thread
richiemsft marked this conversation as resolved.
> `captureDenials` cannot be combined with `processContainer.leastPrivilege`;
> the Windows process security-environment API used for capture does not expose
> an LPAC token option, so MXC rejects that combination rather than silently
> weakening the requested policy.
>
> `captureDenials` also cannot currently be combined with `network.proxy`.
> The V2 process security-environment proxy contract requires a separate proxy
> AppContainer peer identity; MXC rejects the combination until that peer is
> provisioned by the capture launch path.

- `mode: "block"` (default) maps onto `learningModeLogging`
(deny-and-record) β€” the app / user-configurable flow.
Expand Down
2 changes: 2 additions & 0 deletions docs/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ production configs and the dev schema when working on experimental features:
} // dir must already exist; a unique per-run id is stamped
// into the stem (denials.<run-id>.json) and the actual
// path printed on stderr. Omit outputPath for a managed temp file.
// captureDenials cannot be combined with leastPrivilege.
// captureDenials cannot currently be combined with network.proxy.
},

"lxc": { // LXC-specific
Expand Down
62 changes: 62 additions & 0 deletions external/windows-sdk/ProcessSecurityEnvironment.fbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
Comment thread
richiemsft marked this conversation as resolved.
Outdated

namespace ProcessSecurityEnvironmentLayout;

struct SchemaVersion {
major:uint16;
minor:uint16;
}

table ProcessSecurityEnvironment {
version:SchemaVersion (required);
capabilities:string;
disallow_win32k_system_calls:bool = false;
ui_restrictions:uint64 = 0;
fs_read_write:[string];
fs_read_only:[string];
fs_deny:[string];
network_policy:NetworkPolicy;
}

table ProxyInfo {
url:string;
}

enum FilterAction : byte { deny, allow }
enum IpProtocol : byte { any, tcp, udp, icmpv4, icmpv6 }

table IpSubnet {
address:string;
prefix_length:ubyte = 0;
}

table DestinationRule {
subnet:IpSubnet;
except:[IpSubnet];
}

table PortRule {
protocol:IpProtocol = any;
port:uint16 = 0;
end_port:uint16 = 0;
}

table EndpointRule {
destinations:[DestinationRule];
ports:[PortRule];
}

table EndpointPolicy {
default_action:FilterAction = deny;
allow:[EndpointRule];
deny:[EndpointRule];
}

table NetworkPolicy {
proxy:ProxyInfo;
egress:EndpointPolicy;
allowed_appcontainer_peer:string;
}

root_type ProcessSecurityEnvironment;
file_identifier "PSEC";
10 changes: 9 additions & 1 deletion src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ members = [
"core/mxc_build_common",
"host/plm",
"core/generated/base_container_specification",
"core/generated/process_security_environment_specification",
Comment thread
richiemsft marked this conversation as resolved.
"backends/appcontainer/common",
"backends/windows_sandbox/daemon",
"backends/windows_sandbox/guest",
Expand Down Expand Up @@ -92,7 +93,7 @@ windows = { version = "0.62", features = [
"Win32_System_Time",
"Win32_System_SystemServices",
"Win32_System_SystemInformation",
"Win32_System_JobObjects",
"Win32_System_JobObjects",
] }
windows-core = "0.62"
serde = { version = "1", features = ["derive"] }
Expand Down Expand Up @@ -129,6 +130,7 @@ isolation_session_bindings = { path = "backends/isolation_session/bindings" }
mxc_pty = { path = "core/mxc_pty" }
flatbuffers = "25"
sandbox_spec = { path = "core/generated/base_container_specification" }
process_security_environment_spec = { path = "core/generated/process_security_environment_specification" }
mxc_telemetry = { path = "mxc_telemetry" }
widestring = "1"
url = "2"
Expand Down
1 change: 1 addition & 0 deletions src/backends/appcontainer/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ windows = { workspace = true }
windows-core = { workspace = true }
flatbuffers = { workspace = true }
sandbox_spec = { workspace = true }
process_security_environment_spec = { workspace = true }
widestring = { workspace = true }
winreg = { workspace = true }
learning_mode_windows = { workspace = true }
Expand Down
Loading
Loading