From 10c1d77a4f3842812293d138a4e447356149ab5b Mon Sep 17 00:00:00 2001 From: Hypatia May Date: Thu, 6 Aug 2026 13:50:48 +0800 Subject: [PATCH] fix(landlock-run): address release review feedback --- .../implemented/feature/2026-07-06-sandbox.i18n.yaml | 4 ++-- .../notes/implemented/feature/2026-07-06-sandbox.md | 2 +- .../notes/implemented/feature/2026-07-06-sandbox.zh.md | 2 +- .github/workflows/landlock-run-release.yml | 10 ++++++++-- native/landlock-run/docs/release.md | 2 +- packages/bash/bash-sandbox/tests/landlock.e2e.ts | 6 +++--- .../sandbox/sandbox-local/tests/packed-install.e2e.ts | 6 ++++-- 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml b/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml index 5f8dfa4e65..b927bf9f72 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-06-sandbox.md -2026-07-06-sandbox.md: 69a3f1bd181bc06d9a176fa45b1e091991cfa682 -2026-07-06-sandbox.zh.md: eeca55b61da24df215f7a9b7ba8dbf9ab2387f20 +2026-07-06-sandbox.md: de00453eace87ef89e7e05bfe20e1ff956ee4d19 +2026-07-06-sandbox.zh.md: db84e9b3872fb5807720c75310c9ee58f2b9fdb7 diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.md b/.agents/notes/implemented/feature/2026-07-06-sandbox.md index 69a3f1bd18..de00453eac 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.md +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.md @@ -128,7 +128,7 @@ Each phase gets its full design when picked up, validated against the code at th - **Second consumer** — `subagent-acp` optionally confines child agents (per-call policy; unconfined default — a child agent must write its own persistence). - **More environments** — an environment-coherent capability group example (e.g. bash+fs against one container). -- **Windows chain** — `PLATFORM_CHAINS.win32` is reserved and empty (fail-closed); filling it means a confinement runner from the AppContainer/restricted-token family, shipped from its own repository on the `node-addon-landlock-run` template, plus its profile dialect, denial signatures, and runner-failure rules. Wrapping the third-party landstrip runner instead was [considered and rejected](../../rejected/feature/2026-07-26-evaluate-landstrip-for-windows-sandbox-rung.md) — not battle-tested enough for a security invariant. +- **Windows chain** — `PLATFORM_CHAINS.win32` is reserved and empty (fail-closed); filling it means a confinement runner from the AppContainer/restricted-token family, shipped from the main repository under `native/` following the `node-addon-landlock-run` template, plus its profile dialect, denial signatures, and runner-failure rules. Wrapping the third-party landstrip runner instead was [considered and rejected](../../rejected/feature/2026-07-26-evaluate-landstrip-for-windows-sandbox-rung.md) — not battle-tested enough for a security invariant. ## Alternatives considered diff --git a/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md b/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md index eeca55b61d..db84e9b387 100644 --- a/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md +++ b/.agents/notes/implemented/feature/2026-07-06-sandbox.zh.md @@ -128,7 +128,7 @@ fs/web/todo 在进程内执行,因此它们的沙箱语义是各自 seam 层 - **第二个消费方**——`subagent-acp` 可选地约束子 agent(按调用策略;默认无约束——子 agent 必须写入自己的持久化)。 - **更多环境**——环境一致的能力组示例(如 bash+fs 对一个容器)。 -- **Windows 链**——`PLATFORM_CHAINS.win32` 保留为空(失败关闭);填充它意味着来自 AppContainer/restricted-token 家族的约束 runner,从其自己的仓库按 `node-addon-landlock-run` 模板交付,加上其 profile 方言、拒绝签名和 runner 失败规则。改为包装第三方 landstrip runner 的方案[经考虑后已驳回](../../rejected/feature/2026-07-26-evaluate-landstrip-for-windows-sandbox-rung.md)——它所经受的实战检验还不足以承载安全不变式。 +- **Windows 链**——`PLATFORM_CHAINS.win32` 保留为空(失败关闭);填充它意味着来自 AppContainer/restricted-token 家族的约束 runner,由主仓库在 `native/` 下按 `node-addon-landlock-run` 模板交付,加上其 profile 方言、拒绝签名和 runner 失败规则。改为包装第三方 landstrip runner 的方案[经考虑后已驳回](../../rejected/feature/2026-07-26-evaluate-landstrip-for-windows-sandbox-rung.md)——它所经受的实战检验还不足以承载安全不变式。 ## 曾考虑的替代方案 diff --git a/.github/workflows/landlock-run-release.yml b/.github/workflows/landlock-run-release.yml index dca6c9eed1..c69ebbe5ee 100644 --- a/.github/workflows/landlock-run-release.yml +++ b/.github/workflows/landlock-run-release.yml @@ -158,6 +158,14 @@ jobs: name: npm-tarballs path: native/landlock-run/dist/npm + - name: Configure npm token fallback + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + if [[ -n "$NPM_TOKEN" ]]; then + echo "NODE_AUTH_TOKEN=$NPM_TOKEN" >> "$GITHUB_ENV" + fi + - name: Publish tarballs run: | version="${GITHUB_REF#refs/tags/landlock-run-v}" @@ -166,5 +174,3 @@ jobs: while IFS= read -r tarball; do npm publish "dist/npm/${tarball}" --access public "${tag_args[@]}" done < dist/npm/publish-order.txt - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/native/landlock-run/docs/release.md b/native/landlock-run/docs/release.md index a95cffd47f..353a489c2c 100644 --- a/native/landlock-run/docs/release.md +++ b/native/landlock-run/docs/release.md @@ -45,7 +45,7 @@ Use the main repository's `Landlock Run Release` workflow so every binary is bui 2. Create and push the `landlock-run-vX.Y.Z` tag matching the package versions. 3. Run the same workflow from that tag with `publish=true`. -The workflow publishes only from the final packed tarballs, in `publish-order.txt` order (platform packages before the entry that optionally depends on them). It supports npm trusted publishing through GitHub OIDC; without it, provide an `NPM_TOKEN` secret in the `npm-publish` environment. Packages publish with `--access public`. +The workflow publishes only from the final packed tarballs, in `publish-order.txt` order (platform packages before the entry that optionally depends on them). A current-platform rehearsal can still query npm for metadata about an incompatible optional platform package; that package cannot supply the host launcher, which comes from the matching local tarball. Publishing every platform package before the entry ensures a public entry version never points ahead of its platform packages. The workflow supports npm trusted publishing through GitHub OIDC; without it, provide an `NPM_TOKEN` secret in the `npm-publish` environment. Packages publish with `--access public`. Manual local fallback (current platform's packages only) — always through `pack-release.mjs`, never `pnpm publish` directly (pnpm's pack path strips the launcher's executable bit; see [packaging.md](packaging.md)): diff --git a/packages/bash/bash-sandbox/tests/landlock.e2e.ts b/packages/bash/bash-sandbox/tests/landlock.e2e.ts index 0c5cfbe563..7579292fe1 100644 --- a/packages/bash/bash-sandbox/tests/landlock.e2e.ts +++ b/packages/bash/bash-sandbox/tests/landlock.e2e.ts @@ -13,14 +13,14 @@ import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local' /** * KEYLESS consumer-integration proof: the REAL `LocalSandboxProvider` (bwrap - * rung forced off, so the npm-distributed `landlock-run` confines) underneath the + * rung forced off, so the workspace `landlock-run` launcher confines) underneath the * REAL `SandboxBashExecutor`, driven through the executor's public run/start * paths. Verifies the WORLD (files exist or don't) plus the stamped result * facts; the backend-only confinement proofs live with * `@deepseek-ai/dsh-sandbox-local`. * - * Self-skips when the running kernel does not enforce Landlock; the - * launcher binary itself arrives with `pnpm install` (`node-addon-landlock-run`). + * Self-skips when the running kernel does not enforce Landlock. CI builds the launcher from + * `native/landlock-run` before running this file. */ const probe = spawnSync(launcherPath(), ['--probe'], { timeout: 5_000, encoding: 'utf8' }) diff --git a/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts b/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts index caf0a32c68..612751e6da 100644 --- a/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts +++ b/packages/sandbox/sandbox-local/tests/packed-install.e2e.ts @@ -9,8 +9,10 @@ import { afterAll, beforeAll, describe, expect, it } from 'vitest' /** * Keyless publish-path rehearsal. It packs the provider, its workspace peers, and the current * repository's Landlock entry/platform packages, then installs those exact tarballs in an external - * plain-Node consumer. No registry copy, tsx, path mapping, or workspace resolution can hide - * missing files, dependency errors, or lost executable modes. + * plain-Node consumer. The host launcher comes from the exact local tarballs, so no registry copy, + * tsx, path mapping, or workspace resolution can hide missing files, dependency errors, or lost + * executable modes. npm may still query registry metadata for an incompatible optional platform + * package that cannot supply the host launcher. * * The installed launcher must match the host architecture, remain executable, and either confine a * real process with bwrap disabled or fail closed on a non-enforcing kernel. Skips off Linux or