DSH / Atlas
2026-07-26rejectedfeature

Evaluate landstrip before building a Windows sandbox launcher

在构建 Windows 沙箱启动器之前先评估 landstrip

The [sandbox decision](../../implemented/feature/2026-07-06-sandbox.md) leaves `PLATFORM_CHAINS.win32` empty and plans to fill it with "a confinement runner from the AppContainer/restricted-token family, shipped from its own repository on the `node-addon-landlock-run` template" — an estimated ~1,500-line new repo (the landlock-run subtree is ~1,460 lines of C/TS/scripts/tests plus docs and CI) authored and maintained

English

Problem

The sandbox decision leaves PLATFORM_CHAINS.win32 empty and plans to fill it with "a confinement runner from the AppContainer/restricted-token family, shipped from its own repository on the node-addon-landlock-run template" — an estimated ~1,500-line new repo (the landlock-run subtree is ~1,460 lines of C/TS/scripts/tests plus docs and CI) authored and maintained in-house.

Since that note was written, a maintained third-party runner has appeared: @landstrip/landstrip (npm, actively developed, Rust core with prebuilt per-platform optionalDependencies) covers Landlock + seccomp on Linux, Seatbelt on macOS, and AppContainer/restricted-user on Windows, with JSON/YAML policy input and a trap-fd denial-reporting channel. It is exec-wrapped like bwrap, so it fits the chain's confine(argv) shape without touching the Linux/macOS rungs.

Proposal

When the Windows sandbox phase is picked up, evaluate wrapping landstrip's Windows backend as the win32 chain runner before authoring an in-house AppContainer launcher repository. The evaluation must answer:

  • Probe synthesis. landstrip has no --probe; the chain's functional-probe contract would have to be synthesized from a trap run.
  • Dialect mapping. Denial and runner-failure stderr dialects, and fail-closed exit-code classification, need explicit mapping into the chain's vocabulary.
  • License. The binaries are LGPL-2.1-or-later; distribution review is required before it enters the shipped closure.
  • Source and build record. Each in-house launcher binary is byte-pinned to a native CI build of a ~300-line reviewable C file; landstrip is a single-maintainer Rust binary set. For the existing Linux rung that trade is already settled — do not swap it (sandbox note and the launcher's own migration away from a Rust dependency). For a rung we have not built, weighing third-party maintenance against a second in-house native repo is a genuinely open question.

Alternatives considered

  • Build the in-house AppContainer launcher as planned. Still the default if the evaluation fails on license, source/build auditability, or probe fit; the cost is owning a second native security launcher repo indefinitely.
  • Swap the Linux Landlock rung to landstrip too. Rejected outright: sandbox correctness is a security invariant, the current launcher has reviewable C source and binaries byte-pinned to native CI builds, and it already migrated away from a Rust dependency for exactly this reason.

Acceptance criteria

  • Before any Windows-rung implementation starts, an evaluation records the probe, dialect, license, source repository, release process, and binary build answers, and the go/no-go is added to the sandbox note's deferred-phases plan.

Risks

  • Single-maintainer supply chain in a security-critical position — the reason this is an evaluation gate, not an adoption decision.
  • The package is young; its API and packaging may churn before the Windows phase starts, so re-verify against the live registry then.

中文

问题

沙箱决策PLATFORM_CHAINS.win32 留空,并计划用「AppContainer/受限令牌(restricted-token)家族的一个约束运行器,按 node-addon-landlock-run 模板从其独立仓库发布」来填充——一个估计约 1,500 行、需要自研编写并维护的新仓库(landlock-run 子树约为 1,460 行 C/TS/脚本/测试,外加文档与 CI)。

自那份决策记录写成以来,出现了一个持续维护的第三方运行器:@landstrip/landstrip(npm 包,活跃开发中,Rust 内核,附带按平台预构建的 optionalDependencies)覆盖 Linux 上的 Landlock + seccomp、macOS 上的 Seatbelt,以及 Windows 上的 AppContainer/受限用户,支持 JSON/YAML 策略输入和基于 trap-fd 的拒绝上报通道。它与 bwrap 一样采用 exec 包装方式,因此无需触碰 Linux/macOS 层级即可契合链的 confine(argv) 形态。

提案

当 Windows 沙箱阶段启动时,在动手编写自研 AppContainer 启动器仓库之前,先评估将 landstrip 的 Windows 后端包装为 win32 链运行器。评估必须回答:

  • 探测合成。 landstrip 没有 --probe;链所要求的功能探测约定必须从一次 trap 运行中合成出来。
  • 方言映射。 拒绝与运行器失败两类 stderr 方言,以及失败关闭的退出码分类,都需要显式映射到链的词汇中。
  • 许可证。 其二进制文件采用 LGPL-2.1-or-later 许可;在进入随产品发布的依赖闭包之前需要先做分发审查。
  • 源码与构建记录。 每个自研启动器二进制都逐字节锁定到一个约 300 行、可完整评审的 C 文件的原生 CI 构建;而 landstrip 是单一维护者手中的一组 Rust 二进制文件。对既有的 Linux 层级而言,这笔权衡早有定论——不要替换它(见沙箱 Agent Note以及该启动器自身移除 Rust 依赖的迁移记录)。而对一个我们尚未构建的层级,在第三方维护与第二个自研原生仓库之间如何取舍,是一个真正悬而未决的问题。

曾考虑的替代方案

  • 按原计划构建自研 AppContainer 启动器。 若评估在许可证、源码/构建可审计性或探测契合度上不通过,这仍是默认选项;代价是要长期维护第二个原生安全启动器仓库。
  • 把 Linux Landlock 层级也换成 landstrip。 直接否决:沙箱正确性是安全不变量,当前启动器有可审阅的 C 源码,其二进制逐字节锁定到原生 CI 构建,而且它正是出于这一原因才迁移摆脱了 Rust 依赖。

验收标准

  • 在任何 Windows 层级实现开始之前,先有一份评估记录下探测、方言、许可证、源代码仓库、发布流程和二进制构建问题的答案,并把「采用/不采用」(go/no-go)结论加入沙箱 Agent Note 的延后阶段计划。

风险

  • 处于安全关键位置的单一维护者供应链——这正是本提案定为一道评估门禁、而非采用决定的原因。
  • 该包尚且年轻;在 Windows 阶段启动之前其 API 与打包方式可能反复变动,届时需对照在线注册表重新核验。