diff --git a/docs-site/src/content/docs/concepts/macos-structural-strategy.md b/docs-site/src/content/docs/concepts/macos-structural-strategy.md index 012bae2e..fd5426d0 100644 --- a/docs-site/src/content/docs/concepts/macos-structural-strategy.md +++ b/docs-site/src/content/docs/concepts/macos-structural-strategy.md @@ -175,7 +175,7 @@ Recommendation from scoring: pursue Option A as the primary path, keep ESF as an - Run MACOS-001 through MACOS-009 from `examples/firma-run/e2e/macos-structural-assertions.md` on macOS 12+ Apple Silicon and Intel. - Include raw socket, proxy-env-unset, child process, direct DNS, policy deny, startup sidecar-down, and mid-session sidecar-loss cases. - Keep the runtime claim as non-structural (default mode) until the suite is reliable on supported macOS versions. -- Publish known-limits table: sandbox-exec deprecation caveats, DNS stub port limitation, loopback-all allow scope. +- Keep the central known-limits table in [the sandbox boundary](../sandbox/) current as evidence changes. ### Milestone 4: VZ Guest Runner Contract diff --git a/docs-site/src/content/docs/concepts/sandbox.md b/docs-site/src/content/docs/concepts/sandbox.md index 749376fe..3a28717f 100644 --- a/docs-site/src/content/docs/concepts/sandbox.md +++ b/docs-site/src/content/docs/concepts/sandbox.md @@ -94,11 +94,25 @@ Use this matrix as the current release claim for `firma run` confinement. It tra | Fail-closed startup | **Yes.** Backend, sidecar, policy, and seccomp setup failures block launch. | **Yes for startup.** Launch is blocked unless proxy-only mode is explicitly accepted and the sidecar path is prepared. | **Yes / experimental.** Network-deny mode still uses the same startup fail-closed path. | **Target / experimental.** Artifact validation and contract generation fail closed; runner-side preflight must also prove the guest boundary. | **Yes for startup.** Launch is blocked unless proxy-only mode is explicitly accepted and the sidecar path is prepared. | **Planned.** | | Fail-closed runtime | **Yes.** With no direct egress route, sidecar or bridge loss breaks outbound traffic. | **Partial.** Proxy-routed clients fail, but direct sockets can bypass. | **Partial / experimental.** External egress remains denied, but loopback-all scope is a residual caveat. | **Target / experimental.** Guest route and bridge loss behavior must be proven by the runner and hardware E2E tests. | **Partial.** Proxy-routed clients fail, but direct sockets can bypass. | **Planned.** | | Child/process-tree bypass resistance | **Yes.** Child processes inherit the network namespace. | **No.** Children can ignore or clear proxy env. | **Partial / experimental.** Child processes should inherit the MAC sandbox label for external egress denial; loopback remains reachable and hardware E2E is pending. | **Target / experimental.** Guest boundary should cover the process tree; runner and guest proof are pending. | **No.** Children can ignore or clear proxy env. | **Planned.** | -| Syscall/seccomp enforcement | **Linux-only.** Static seccomp cBPF is supported for the Linux `bwrap` path with a bounded Cedar-subset projection. | **No.** seccomp is unavailable on macOS. | **No seccomp.** Uses TrustedBSD MAC network rules, not syscall filtering. | **Target only.** Contract can carry a seccomp filter path for an in-guest Linux runner; this branch does not implement guest loading. | **No current claim.** | **Planned.** Linux guest path should reuse static kernel controls where applicable. | +| Syscall/seccomp enforcement | **Linux-only.** Static seccomp cBPF is supported for the Linux `bwrap` path with a bounded Cedar-subset projection. | **No.** seccomp is unavailable on macOS. | **No seccomp.** Uses TrustedBSD MAC network rules, not syscall filtering. | **Target only.** Contract can carry a seccomp filter path for an in-guest Linux runner; guest-side loading is not part of the current release claim. | **No current claim.** | **Planned.** Linux guest path should reuse static kernel controls where applicable. | | Immutable execution envelope | **Yes.** Runtime fixes identity, env, mounts, routing, and optional seccomp before launch. | **Partial.** Runtime creates a deterministic launch envelope, but proxy-only children can still bypass network intent. | **Partial / experimental.** Launch envelope plus MAC profile are fixed before process start; residual loopback caveat remains. | **Target / experimental.** Versioned launch contract records command, env, mounts, network endpoints, and required invariants. | **Partial.** Runtime injects env and identity into the WSL launch, but no structural boundary backs it. | **Planned.** | | Interactive CLI/TUI support | **Yes.** Stdio, signals, and exit status are preserved through the wrapper path. | **Yes.** Host-process compatibility path preserves normal CLI behavior. | **Yes / experimental.** Still host-process based through `sandbox-exec`. | **Target / experimental.** Runner must preserve stdio, signals, exit status, terminal resize, and TTY behavior. | **Partial.** Basic process execution is supported; WSL terminal behavior depends on host setup. | **Planned.** | | Evidence status | Runtime code, Linux E2E harness, and FIR-111 seccomp spike artifacts exist. | Runtime proof logs and unit tests support the proxy-only claim. | Runtime code and unit tests exist; macOS hardware E2E assertions are written but not yet green evidence. | Runtime contract code and unit tests exist; signed VZ runner, guest image lifecycle, route proof, and hardware E2E are still pending. | Runtime code and unit tests support the proxy-only claim. | Planned backend; no release evidence. | +## Known limits + +These limits are part of the current release posture. Treat them as constraints +on what `firma run` can claim today, not as implementation bugs. + +| Limit | Current status | Practical effect | +| ----- | -------------- | ---------------- | +| macOS default `vz` is proxy-only | The default macOS backend launches a host process with proxy environment injection and a host-side bridge. | Cooperative HTTP clients are mediated, but raw sockets, direct DNS, and proxy-env-unset children can bypass the Sidecar. | +| macOS `sandbox-exec` mode is loopback-scoped | `FIRMA_RUN_VZ_STRUCTURAL_NETWORK=1` blocks external IP egress, but allows loopback so the proxy bridge and DNS stub can work. | Other host services listening on loopback remain reachable; this is not Linux-equivalent network namespace confinement. | +| VZ guest mode is a launch contract | `FIRMA_RUN_VZ_GUEST=1` validates runner and image paths, writes the launch contract, and spawns the configured runner. | The signed Virtualization.framework runner, guest lifecycle, guest routing, guest DNS, and in-guest proof are not part of the current release. | +| macOS hardware E2E evidence is not complete | The macOS assertion schema exists, but the structural suite is not yet green on supported macOS hardware. | macOS has no current release claim for Linux-style egress, DNS, child-process or runtime fail-closed guarantees. | +| WSL2 is proxy-only | The current `wsl2` backend injects proxy env into the launched command. | It is useful for compatibility, but it is not a mandatory network boundary for non-cooperative processes. | +| seccomp is Linux-only static cBPF today | Managed seccomp is available for the Linux `bwrap` path as a static filter with a bounded Cedar-subset projection. | macOS and WSL2 do not get seccomp enforcement, and Linux syscall filtering is not live Cedar policy evaluation. | + **Structural** means the sandbox removes the agent's ability to bypass the proxy at the OS level — no extra cooperation from the agent is required. The experimental macOS network-deny mode is narrower than Linux because it is loopback-scoped rather than bridge-port-scoped. The experimental macOS VZ guest mode has the stronger structural target, but the runner and guest image own the actual Virtualization.framework lifecycle and in-guest enforcement. **Proxy-only** means enforcement depends on the agent or its HTTP library respecting `HTTP_PROXY`. On proxy-only backends, `firma run` fails closed unless you pass `--allow-non-structural` to acknowledge this limitation. `NO_PROXY` / `no_proxy` are cleared in all built-in profiles to prevent a host-env override from silently routing traffic around the proxy Sidecar on macOS and WSL2.