Document the trust model and the outer-clamp design - #728
Conversation
This PR records the sandbox trust model and the platform-asymmetry clamp design in docs/versioning.md. It is documentation only: the mechanisms that would make an outer clamp genuinely unbypassable are OS infrastructure outside this repository, so it states the design honestly and defers enforcement rather than implying a guarantee that does not exist. Details * New "Trust model and the outer clamp" section describes the one-principal authorization model -- there is no mandatory second channel, because the same principal authors both the config and the command line -- and the three mechanisms that back it: secure defaults, loud logging of any relaxation, and rejection of catastrophic capabilities in shipped builds. * States the precondition explicitly: the model holds only where the invoker and the config author are the same trust principal. MXC does not enforce that, so an embedder passing a config derived from lower-trust input has two principals and must constrain the config itself. * Platform-asymmetry table covers the Windows broker, Linux LSM and root policy, Bubblewrap, macOS SIP and root policy, and an optional cross-platform in-repo clamp-policy file, each with whether it is truly unbypassable and its status. The Windows fallback row is qualified as absent from a stock build: BFS needs the non-default tier2_bfs feature plus bfscfg.exe, and the DACL path needs explicit config opt-in. * States plainly that the unbypassable rows (broker, LSM, SIP) are OS infrastructure out of scope for this repository, and that the in-repo clamp-file candidate would be a trust-boundary gate, not a kernel guarantee. Clamp enforcement itself is deferred. Tests * Documentation only; no code paths or CI gates are affected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Generated-with: claude-opus-4.8 Copilot-Session: cd48fff2-bde9-487a-ab67-012e9bbc0796
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
| is a tight sandbox. | ||
| 2. **Explicit + loud relaxation.** Fields that open a network, UI, capability, | ||
| or Seatbelt boundary beyond their secure default are logged at parse time as | ||
| `SECURITY: boundary relaxed: …`, so those relaxations are never silent — they |
There was a problem hiding this comment.
2 states relaxations "are never silent," but log_boundary_relaxations deliberately skips blockedHosts. Under the secure defaultPolicy=block, a non-empty blockedHosts flips networking OFF->ON (allow-all-except) on the Hyperlight and NanVix. Shall we update this to note per-host blockedHosts filtering on the micro-VM backends is a known audit gap? File bugs to fix the backends so defaultPolicy=block stays authoritative?
| | Platform | Clamp mechanism | Unbypassable? | Status | | ||
| |---|---|---|---| | ||
| | Windows — BaseContainer tier | OS sandbox broker enforces the policy inside `Experimental_CreateProcessInSandbox` | Yes — the broker is the kernel-side authority | OS-infra (outside this repo) | | ||
| | Windows — AppContainer fallback tiers (BFS / DACL) | AppContainer + `bfscfg.exe` BFS or host-side DACL ACEs; used when the BaseContainer API is absent | Partial — enforcement is partly host-side, not a single kernel broker | Existing backend behavior, but **not present in a stock build**: BFS requires the non-default `tier2_bfs` feature plus `bfscfg.exe` on the host, and the DACL path requires explicit config opt-in | |
There was a problem hiding this comment.
The AppContainer-fallback row says the DACL path "requires explicit config opt-in," but it is enabled by default: FallbackPolicy::allow_dacl_mutation defaults to true (models.rs:531) and is only changed when explicitly set (config_parser.rs:1114-1117), and Tier-3 DACL is reached automatically when BaseContainer/BFS are unavailable. So DACL is the default stock fallback and is opt-out, not opt-in - unlike BFS, which really does require the non-default tier2_bfs feature. Suggest: "BFS is absent from a stock build; the DACL path is the default stock fallback (enabled unless fallback.allowDaclMutation:false)."
|
|
||
| ## Trust model and the outer clamp | ||
|
|
||
| MXC's authorization model and the (optional) unbypassable upper bound on what a |
There was a problem hiding this comment.
The section's opening line advertises "the (optional) unbypassable upper bound on what a config can relax," but the body correctly establishes that no in-repo unbypassable clamp ships: every "Yes" row is OS infrastructure out of scope, and the only in-repo row is "No — bypassable by a local admin / Deferred." The lead sentence promises something the section then retracts. Suggest tightening to e.g. "…and the platform-dependent external bounds that can constrain it."
This PR records the sandbox trust model and the platform-asymmetry clamp design
in docs/versioning.md. It is documentation only: the mechanisms that would make
an outer clamp genuinely unbypassable are OS infrastructure outside this
repository, so it states the design honestly and defers enforcement rather than
implying a guarantee that does not exist.
Details
authorization model -- there is no mandatory second channel, because the same
principal authors both the config and the command line -- and the three
mechanisms that back it: secure defaults, loud logging of any relaxation, and
rejection of catastrophic capabilities in shipped builds.
the config author are the same trust principal. MXC does not enforce that, so
an embedder passing a config derived from lower-trust input has two principals
and must constrain the config itself.
Bubblewrap, macOS SIP and root policy, and an optional cross-platform in-repo
clamp-policy file, each with whether it is truly unbypassable and its status.
The Windows fallback row is qualified as absent from a stock build: BFS needs
the non-default tier2_bfs feature plus bfscfg.exe, and the DACL path needs
explicit config opt-in.
infrastructure out of scope for this repository, and that the in-repo
clamp-file candidate would be a trust-boundary gate, not a kernel guarantee.
Clamp enforcement itself is deferred.
Tests
🔗 References
Stack, merge bottom-up. This PR targets
user/gudge/trust-model-profileoverride-devonly. The stacking is load-bearing: this document calls mechanisms 2 and 3 implemented, which holds only once #726 and #727 have merged.seatbelt.profileOverridein shipped builds (mechanism 3)