Skip to content

tinybox-jail: Windows AppContainer backend cannot be enabled (unsafe policy, no waitable Child) #22

Description

@senamakel

crates/tinybox-jail/src/windows.rs is not compiled, so on Windows pick_backend() returns the unsupported backend and a host that wants to run anyway has to opt into NoopBackend (unconfined).

Why it stays off

History: 40f2e4f (2026-09-30) removed the platform modules because they did not satisfy the workspace unsafe_code = "forbid" policy or the Jail contract. The Linux (Landlock) and macOS (Seatbelt) backends are re-enabled by the linked PR. Windows cannot be, for two independent reasons:

  1. unsafe. The backend is Win32 FFI (CreateAppContainerProfile, SetNamedSecurityInfoW, CreateProcessW with STARTUPINFOEXW, handle/SID cleanup). AGENTS.md says no crate relaxes the forbid, and unlike Landlock there is no unsafe-free way to apply an AppContainer to a child.
  2. No waitable Child. JailBackend::spawn returns std::process::Child, which has no stable constructor from a raw HANDLE. spawn_in_container creates the process, then closes the handle and returns Unsupported, which strands a running, unconfined-from-the-caller's-view process. is_available() is hard-coded to false for that reason.
  3. It has never run on real Windows hardware (the file header says so).

Options

  • Move the AppContainer launch behind a helper process or an existing tool that owns the unsafe (as tinybox-linux did for namespaces), and have it exec/forward stdio.
  • Or change JailBackend::spawn to return a crate-owned child type (id, wait, try_wait, kill) and carve the FFI into a crate that is explicitly allowed unsafe by an ADR.

Either needs a design decision, so this is tracked rather than done in the enable-backends PR.

Activity

  1. added
    priority: p3Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.
    on Oct 3, 2026
  2. tinysweeper commented on Oct 3, 2026

    @tinysweeper

    Windows AppContainer backend cannot be enabled due to unsafe code and no waitable Child; needs a design decision before re-implementation.

    Labelled priority: p3.

  3. added theissue type on Oct 3, 2026
  4. M3gA-Mind commented on Nov 11, 2026

    @M3gA-Mind
    Collaborator

    This looks done on main via #140 (from fork #66): windows.rs is compiled on Windows, the AppContainer backend spawns through a crate-owned child (spawn_owned_captured, Job Object limits), and a CI script fences the unsafe. is_available() stays false only for the std::process::Child API.
    Closing once someone confirms the Windows default backend uses the owned path. Reopen if it doesn't.

  5. M3gA-Mind commented on Nov 11, 2026

    @M3gA-Mind
    Collaborator

    Correction: this is not done yet. The AppContainer backend exists and is owned-spawn capable (windows.rs: is_owned_available() is true, spawn_owned_captured runs each child in its own Job Object), but the module never selects it.

    • default_backend() on Windows returns the "unsupported" backend: the Windows candidate list is empty, by design (detect.rs:31-34, :49-53).
    • The module passes default_backend() at all four jail entry points: tinybus_module/mod.rs:173, native_shell/mod.rs:36, resources_stdio.rs:108 and resources_stream.rs:159.
    • So a Windows host asking for a jail is refused: native shell via backend.require, and the jailed collectors via JailLocalHost::with_backend, which needs an owned-available backend (tinybox-host limited/jailed.rs:346-355).
    • default_owned_backend() (lib.rs:98-102), which picks AppContainer on Windows, has no non-test caller in the module.
      The likely fix is to give those call sites the owned backend (JailLocalHost already spawns through spawn_owned_captured), then prove it on the Windows runner. Keeping this open until that lands.

    The fix is in #164.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority: p3Whenever. Cosmetic, a nicety, or a cleanup with no user visible effect.

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions