Skip to content
Closed
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
6 changes: 6 additions & 0 deletions docs/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ cannot mix both formats in one request.
{ "windowsPort": 8080, "containerPort": 80, "protocol": "tcp" }
]
},
"apple_container": { // Apple Container settings (macOS, 0.9 only)
"image": "docker.io/library/alpine:3.23", // Required OCI image with /bin/sh
"cpuCount": 2, // Optional positive virtual CPU count
"memoryMb": 1024 // Optional positive memory limit in MB
},
"seatbelt": { // macOS sandbox settings (macOS only)
"profileOverride": null, // Optional raw TinyScheme profile (escape hatch)
"guiAccess": false, // Allow GUI Mach services / IOKit / pty for window-drawing apps
Expand Down Expand Up @@ -348,6 +353,7 @@ force a particular backend.
| `"hyperlight"` | MicroVM isolation via Hyperlight + Unikraft with an embedded CPython snapshot (experimental) |
| `"isolation_session"` | Windows isolation session β€” runs the workload as a freshly-provisioned, per-execution isolated user account in its own OS-managed session (experimental). Dual-mode: one-shot and state-aware. |
| `"seatbelt"` | macOS sandbox isolation (Seatbelt) |
| `"apple_container"` | Experimental Apple Container configuration surface for macOS. Requires schema version `0.9.0-alpha`, `--experimental`, and `experimental.apple_container.image`. Runtime execution is currently fail-closed with `unsupported_containment`. |
| `"bubblewrap"` | Unprivileged Linux sandboxing via Bubblewrap/user namespaces (experimental) |

Only the backend section matching the selected `containment` value is accepted;
Expand Down
66 changes: 66 additions & 0 deletions schemas/dev/mxc-config.schema.0.9.0-alpha.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,32 @@
}
],
"definitions": {
"AppleContainer": {
"additionalProperties": false,
"description": "One-shot Apple Container backend settings.",
"properties": {
"cpuCount": {
"description": "Requested virtual CPU count.",
"maximum": 4294967295,
"minimum": 1.0,
"type": "integer"
},
"image": {
"$ref": "#/definitions/NonBlankString",
"description": "OCI image reference. The image must provide `/bin/sh`."
},
"memoryMb": {
"description": "Requested memory limit in megabytes.",
"maximum": 18446744073709551615,
"minimum": 1.0,
"type": "integer"
}
},
"required": [
"image"
],
"type": "object"
},
"CaptureDenials": {
"additionalProperties": false,
"description": "Windows denial-capture settings.",
Expand Down Expand Up @@ -773,6 +799,10 @@
},
"type": "object"
},
"NonBlankString": {
"pattern": "\\S",
"type": "string"
},
"NonEmptyString": {
"minLength": 1,
"type": "string"
Expand Down Expand Up @@ -869,13 +899,24 @@
"isolation_session"
],
"type": "string"
},
{
"description": "AppleContainer",
"enum": [
"apple_container"
],
"type": "string"
}
]
},
"OneShotExperimental": {
"additionalProperties": false,
"description": "Experimental settings.",
"properties": {
"apple_container": {
"$ref": "#/definitions/AppleContainer",
"description": "Optional one-shot Apple Container backend settings."
},
"telemetry": {
"$ref": "#/definitions/Telemetry",
"description": "Optional telemetry override."
Expand Down Expand Up @@ -913,6 +954,31 @@
"macos_sandbox"
]
}
},
{
"else": true,
"if": {
"properties": {
"containment": {
"const": "apple_container"
}
},
"required": [
"containment"
]
},
"then": {
"properties": {
"experimental": {
"required": [
"apple_container"
]
}
},
"required": [
"experimental"
]
}
}
],
"description": "A complete one-shot `0.9.0-alpha` configuration request.",
Expand Down
83 changes: 83 additions & 0 deletions schemas/dev/mxc-config.schema.0.9.0-dev.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,72 @@
"title": "MXC Configuration",
"description": "MXC container execution configuration. Defines the recommended config format for both one-shot and state-aware sandbox lifecycle requests. A few deprecated field spellings not listed here are also accepted via serde aliases.",
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"containment": {
"const": "apple_container"
}
},
"required": [
"containment"
]
},
"then": {
"properties": {
"experimental": {
"allOf": [
{
"$ref": "#/definitions/Experimental"
},
{
"required": [
"apple_container"
]
}
]
}
},
"required": [
"experimental"
]
}
}
],
"definitions": {
"AppleContainer": {
"description": "Apple Container backend config.",
"properties": {
"cpuCount": {
"description": "Requested virtual CPU count.",
"maximum": 4294967295,
"minimum": 1.0,
Comment thread
richiemsft marked this conversation as resolved.
"type": [
"integer",
"null"
]
},
"image": {
"description": "OCI image reference. The image must provide `/bin/sh`.",
"pattern": "\\S",
"type": "string"
},
"memoryMb": {
"description": "Requested memory limit in megabytes.",
"maximum": 18446744073709551615,
"minimum": 1.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"image"
],
"type": "object"
},
"BaseProcessUi": {
"additionalProperties": false,
"description": "BaseProcessContainer UI isolation settings.",
Expand Down Expand Up @@ -184,12 +249,30 @@
"bubblewrap"
],
"type": "string"
},
{
"description": "Apple Container VM backend (experimental, macOS).",
"enum": [
"apple_container"
],
"type": "string"
}
]
},
"Experimental": {
"description": "Experimental features (only honored with `--experimental`). This block is intentionally **permissive** (no `deny_unknown_fields`): experimental backends are in flux, so the schema documents the known shapes for editor help without rejecting in-progress fields. The strict, closed contract is the stable (top-level) surface.",
"properties": {
"apple_container": {
"anyOf": [
{
"$ref": "#/definitions/AppleContainer"
},
{
"type": "null"
}
],
"description": "Apple Container backend config (macOS)."
},
"isolation_session": {
"anyOf": [
{
Expand Down
29 changes: 25 additions & 4 deletions sdk/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ child.on('close', (code) => console.log('exit:', code));
| `0.8.0-alpha` | Stable (current) | [`schemas/stable/mxc-config.schema.0.8.0-alpha.json`](https://github.com/microsoft/mxc/blob/main/schemas/stable/mxc-config.schema.0.8.0-alpha.json) |
| `0.9.0-alpha` | Dev (experimental backends, the `experimental.*` block, state-aware sandbox lifecycle) | [`schemas/dev/mxc-config.schema.0.9.0-dev.json`](https://github.com/microsoft/mxc/blob/main/schemas/dev/mxc-config.schema.0.9.0-dev.json) |

Pick `0.8.0-alpha` for new code on any supported platform.
Pick `0.8.0-alpha` for new code on any supported platform unless selecting
Apple Container, which requires `0.9.0-alpha`.

> **Stable schemas document only the non-experimental surface.** Experimental backends (`windows_sandbox`, `wslc`, `microvm`, `hyperlight`, `isolation_session`), the `experimental.*` block, and state-aware lifecycle live in `0.9.0-dev`. The parser still accepts them when paired with `--experimental` regardless of which schema your config validates against β€” schema choice affects editor validation, not runtime behavior.
> **Stable schemas document only the non-experimental surface.** Experimental backends (`windows_sandbox`, `wslc`, `microvm`, `hyperlight`, `isolation_session`, `apple_container`), the `experimental.*` block, and state-aware lifecycle live in `0.9.0-dev`. The parser still accepts them when paired with `--experimental` regardless of which schema your config validates against β€” schema choice affects editor validation, not runtime behavior.
> Apple Container is the exception: its config version must be exactly
> `0.9.0-alpha`.

> **Network host allow/block lists are not implemented on Windows.** `network.allowedHosts` / `network.blockedHosts` have no enforcement on this platform β€” use `network.defaultPolicy` (`allow` / `block`) or `network.proxy` to constrain network access.

Expand Down Expand Up @@ -140,9 +143,9 @@ for all three connectivity modes and backend-specific support.
| --- | --- | --- | --- |
| Windows 11 24H2+ (verified on 25H2) | `processcontainer` | `windows_sandbox`, `wslc`, `microvm`, `isolation_session` | `processcontainer`: 26100 (24H2)<br>`isolation_session`: 26340.9212 ([Insider Preview](https://learn.microsoft.com/en-us/windows-insider/release-notes/experimental/preview-build-26340-9212)) |
| Linux x64 / ARM64 | `bubblewrap` | `lxc` | β€” |
| macOS ARM64 (schema `0.7.0-alpha`+) | `seatbelt` | β€” | β€” |
| macOS ARM64 (schema `0.7.0-alpha`+) | `seatbelt` | `apple_container` (config only) | β€” |

The default `processcontainer`, `bubblewrap`, `lxc`, and `seatbelt` backends work out of the box. **Experimental backends** (`windows_sandbox`, `wslc`, `microvm`, `isolation_session`, `hyperlight`) require `{ experimental: true }` in `SandboxSpawnOptions` when you spawn β€” see [Choosing a Backend](#choosing-a-backend).
The default `processcontainer`, `bubblewrap`, `lxc`, and `seatbelt` backends work out of the box. **Experimental backends** (`windows_sandbox`, `wslc`, `microvm`, `isolation_session`, `hyperlight`, `apple_container`) require `{ experimental: true }` in `SandboxSpawnOptions` when you spawn β€” see [Choosing a Backend](#choosing-a-backend).

> **Hyperlight** is an opt-in build flavor (Linux x64 and Windows x64) gated by the `--with-hyperlight` cargo feature. Default shipped binaries do not include it; build from source with `build.bat --with-hyperlight` (Windows) or the equivalent cargo invocation on Linux.

Expand Down Expand Up @@ -268,6 +271,7 @@ console.log(result.stdout);
| `microvm` | `microvm` | Windows | Experimental | [`docs/nanvix-microvm/nanvix.md`](https://github.com/microsoft/mxc/blob/main/docs/nanvix-microvm/nanvix.md) β€” MicroVM via NanVix on Windows Hypervisor Platform |
| `wslc` | (concrete only) | Windows | Experimental | [`docs/wsl/wsl-container-getting-started.md`](https://github.com/microsoft/mxc/blob/main/docs/wsl/wsl-container-getting-started.md) |
| `isolation_session` | (concrete only) | Windows | Experimental | [`docs/isolation-session/oneshot.md`](https://github.com/microsoft/mxc/blob/main/docs/isolation-session/oneshot.md) |
| `apple_container` | (concrete only) | macOS ARM64 | Experimental, config only | β€” |

Experimental backends require `{ experimental: true }` in `SandboxSpawnOptions`:

Expand All @@ -277,6 +281,23 @@ config.process!.commandLine = 'cmd /c whoami';
const pty = spawnSandboxFromConfig(config, { experimental: true });
```

Apple Container has a dedicated builder because it requires an OCI image and
schema version `0.9.0-alpha`:

```typescript
import { createAppleContainerConfig } from '@microsoft/mxc-sdk';

const config = createAppleContainerConfig(
Comment thread
richiemsft marked this conversation as resolved.
{ version: '0.9.0-alpha' },
{ image: 'docker.io/library/alpine:3.23', cpuCount: 2, memoryMb: 1024 },
);
config.process!.commandLine = 'echo hello';
```

This increment exposes and validates the configuration contract only.
`spawnSandboxFromConfig(config, { experimental: true })` currently fails with
`unsupported_containment` before creating Apple Container resources.

Backend-specific tuning lives on the returned `ContainerConfig`. The full set of fields per backend is in the JSON schemas β€” they're the source of truth:

- Stable backends: [`schemas/stable/`](https://github.com/microsoft/mxc/tree/main/schemas/stable/)
Expand Down
26 changes: 25 additions & 1 deletion sdk/node/src/generated/v0_9_0_alpha/wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@
* Regenerate with:
* cargo run --manifest-path src/Cargo.toml -p mxc_schema_gen -- types --version 0.9.0-alpha --out sdk/node/src/generated/v0_9_0_alpha/wire.ts
*/
/**
* One-shot Apple Container backend settings.
*/
export interface AppleContainer {
/**
* Requested virtual CPU count.
*/
cpuCount?: number;
/**
* OCI image reference. The image must provide `/bin/sh`.
*/
image: NonBlankString;
/**
* Requested memory limit in megabytes.
*/
memoryMb?: number;
}

/**
* Windows denial-capture settings.
*/
Expand Down Expand Up @@ -395,14 +413,20 @@ export interface NetworkRule {
to?: NetworkPeer[];
}

export type NonBlankString = string;

export type NonEmptyString = string;

export type OneShotContainment = "process" | "processcontainer" | "appcontainer" | "lxc" | "bubblewrap" | "seatbelt" | "macos_sandbox" | "vm" | "windows_sandbox" | "microvm" | "hyperlight" | "wslc" | "isolation_session";
export type OneShotContainment = "process" | "processcontainer" | "appcontainer" | "lxc" | "bubblewrap" | "seatbelt" | "macos_sandbox" | "vm" | "windows_sandbox" | "microvm" | "hyperlight" | "wslc" | "isolation_session" | "apple_container";

/**
* Experimental settings.
*/
export interface OneShotExperimental {
/**
* Optional one-shot Apple Container backend settings.
*/
apple_container?: AppleContainer;
/**
* Optional telemetry override.
*/
Expand Down
25 changes: 24 additions & 1 deletion sdk/node/src/generated/wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,25 @@
* Regenerate with:
* cargo run --manifest-path src/Cargo.toml -p mxc_schema_gen -- types --legacy-wire --out sdk/node/src/generated/wire.ts
*/
/**
* Apple Container backend config.
*/
export interface AppleContainer {
/**
* Requested virtual CPU count.
*/
cpuCount?: number | null;
/**
* OCI image reference. The image must provide `/bin/sh`.
*/
image: string;
/**
* Requested memory limit in megabytes.
*/
memoryMb?: number | null;
[k: string]: unknown;
}

/**
* BaseProcessContainer UI isolation settings.
*/
Expand Down Expand Up @@ -69,12 +88,16 @@ export type ClipboardPolicy = "none" | "read" | "write" | "all";
/**
* Containment backend (abstract intent or concrete backend).
*/
export type Containment = "process" | "processcontainer" | "vm" | "windows_sandbox" | "lxc" | "microvm" | "hyperlight" | "wslc" | "seatbelt" | "isolation_session" | "bubblewrap";
export type Containment = "process" | "processcontainer" | "vm" | "windows_sandbox" | "lxc" | "microvm" | "hyperlight" | "wslc" | "seatbelt" | "isolation_session" | "bubblewrap" | "apple_container";

/**
* Experimental features (only honored with `--experimental`). This block is intentionally **permissive** (no `deny_unknown_fields`): experimental backends are in flux, so the schema documents the known shapes for editor help without rejecting in-progress fields. The strict, closed contract is the stable (top-level) surface.
*/
export interface Experimental {
/**
* Apple Container backend config (macOS).
*/
apple_container?: AppleContainer | null;
/**
* IsolationSession backend config (Windows).
*/
Expand Down
2 changes: 2 additions & 0 deletions sdk/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export {
ContainmentTypes,
ContainmentBackend,
ExperimentalBackends,
AppleContainerConfig,
ContainerConfig,
ProcessContainerConfig,
NetworkAction,
Expand All @@ -65,6 +66,7 @@ export {
// Export sandbox spawning functions
export {
createConfigFromPolicy,
createAppleContainerConfig,
Comment thread
richiemsft marked this conversation as resolved.
spawnSandbox,
spawnSandboxAsync,
spawnSandboxFromConfig,
Expand Down
Loading
Loading