Repository navigation
[security][tools] --offline の外向きの通信を OS の隔離で遮断し、runtime の依存の導入を隔離の中で動かす(第 3 段) #658
Description
背景
#502 の第 3 段です(#502 の「設計の決定」の節、2026-10-11 承認)。#502 は 1a・1b(書き込み隔離)の merge で閉じ、ネットワークと依存の導入はこの Issue に引き継ぎます。
- 判断 3:第 1 段ではネットワークを変えず、この段で
--offlineのときだけ OS で遮断します(localhost は許可)。 - 判断 5:第 1 段はモデルの Bash と検証コマンドだけを隔離し、この段で runtime の依存の導入へ広げます。
問題
--offlineは今、runtime の依存の導入と、既知のコマンド(npm・pnpm・yarn・cargo の install、curl、wget)を字句で止めるだけです。ネットワークを使う任意のプログラム(python の urllib、node の fetch 等)は止まらず、文書も「network sandbox ではない」と書いています。- runtime の依存の導入のうち、python の
pip install -e .は、パッケージの build backend(setup の script 等)という任意のコードを、隔離の外で実行します。npm の導入は今も--ignore-scriptsで lifecycle script を止めていますが、隔離の外で動きます。
設計(決定)
--offlineの外向きの通信の遮断:- macOS(Seatbelt):
--offlineのとき、profile に外向きの通信の拒否を足し、localhost(loopback)への通信と unix socket は許可します。 - Linux(landlock):ABI4(kernel 6.7)の TCP の connect の制限を使います。landlock は宛先のアドレスを区別できず port だけで制限するため、「localhost だけ許可」はそのままは書けません。決定(2026-10-11):すべての TCP の connect を拒否し、run の dev server の port だけ許可します。同じ port の外部ホストへの接続は通ること、UDP は ABI4 では制限できないことを文書に書きます。ABI4 が無い kernel では「ネットワークは字句検査だけ」と
bash_sandbox_statusの reason に書きます。 --offlineでない run のネットワークは変えません。provider・API の要求は commandagent 本体の通信で、隔離の対象の外です(変えません)。
- macOS(Seatbelt):
- 依存の導入の隔離(判断 5):runtime の依存の導入(python の venv と
pip install -e .、npm の install)の起動を、第 1 段の隔離(書き込みはワークスペース・run の一時ディレクトリ・判断 2 のキャッシュ、読み取りは第 2 段の規則、ネットワークは許可)で包みます。--offlineのときは今どおり依存の導入そのものを止めます(変えません)。 - モード:依存の導入も
--sandboxのモードに従います。requiredで使えないときは、依存の導入を正直に失敗させます(既存の失敗の観測と理由の文に、隔離が使えないことを書く。既存の status の値と event の名前は変えない)。 - 字句検査は変えません。
--offlineの字句の拒否(既知のコマンド)は、隔離が効いていても先に働きます。
規模の見積り
- 新規:macOS の profile のネットワークの規則 約 20〜30 行、Linux の ABI4 の規則 約 50〜70 行、葉モジュールの方針の追加 約 20〜30 行。合わせて約 100〜130 行。
- 配線:依存の導入の 2 つの起動点 各 3〜4 行、
--offlineを方針へ渡す 約 5 行。 - 試験:約 150 行。新規 500 行を超えない見込みなので、分けません。
受け入れ条件
-
--offlineで、隔離の中から外への TCP の接続(試験では到達しない予約アドレスへの connect)が OS により拒否される(macOS は入れ子でない環境、Linux は CI。ABI4 が無いときはその旨を記録して外す)。 -
--offlineで、localhost の dev server(試験の中で立てる)への接続が macOS では通る。Linux は dev server の port だけ通る形で、その制限(port 単位、UDP は対象外)を文書に書く。 -
--offlineでない run では、隔離の中からの外への接続の挙動が今と同じである。 - 依存の導入が隔離の中で成功する(キャッシュ済みの python と npm の fixture)。build backend(setup の script 等)からの tempdir の中の「外」への書き込みが失敗し、「外」の fixture が変わらない。
- cargo build・npm install・Next.js の
next build・Playwright を、--offlineでない run の隔離の中で動かした結果を、第 1・2 段の記録と合わせて残す(判断 2 のキャッシュで足りるかを確かめる)。 - 隔離が使えないとき:
autoは依存の導入を今どおり隔離の外で動かして「未適用」を記録し、requiredは依存の導入を正直に失敗させる。 - 文書の
--offlineの説明を、「OS が遮断するもの(隔離が使えるとき)」と「字句検査だけのもの」に分けて書き換える。 - 字句検査を緩めていない。
- event の既存の名前と schema を変えていない(新しい field・event の追加は可)。
- 既存の検証・受入・証跡・リリースゲートを緩めていない(AGENTS.md の honest-failure 方針)。
- 成長上限の baseline を引き上げていない。成長上限の対象のファイル(「参照」の一覧)を変えていない。
-
cargo fmt --all -- --check・cargo clippy --all-targets -- -D warnings・cargo testが通る。
対象ファイル
src/tools/os_sandbox.rssrc/tools/os_sandbox/seatbelt.rssrc/tools/os_sandbox/landlock.rssrc/minimal_loop/dependency_setup.rssrc/lib.rs(tools::os_sandbox::installに--offlineと run の dev server の port を渡す配線だけ。port は葉モジュールの側でplanner::profile::resolve_profile_runtimeとplanner::signals::requested_port_from_textから求め、preflight と run の記録のモジュールは変えない。2026-10-13 追記:設計の「--offlineを方針へ渡す 約 5 行」の配線先が対象から漏れていたため)tests/issue502_os_sandbox_network.rs(新規)SECURITY.mddocs/guide/ja/cli-reference.mddocs/guide/en/cli-reference.md
参照
- 成長上限の対象のファイル:
src/planner/runner.rs・src/minimal_loop/loop_run.rs・src/minimal_loop/loop_run/runtime_bash_effects.rs(変えない) - 1a・1b・2 の葉モジュール(
src/tools/os_sandbox.rs) - landlock の ABI4(kernel 6.7)は TCP の bind・connect を port で制限する。アドレス・UDP は制限できない。
- 設計調査の記録:ローカルの workspace/tmp/1007/wave1/results/H-18/report.md の 2 章(ネットワーク)
根拠(develop d708619a)
--offlineの説明(字句だけ):src/tools/offline_policy.rs:1-9、src/cli.rs:505-512、SECURITY.md:41-43、docs/guide/ja/cli-reference.md:80、docs/guide/en/cli-reference.md:81--offlineは依存の導入そのものを止める:src/minimal_loop/dependency_setup.rs:724-733- python の依存の導入(
sh -c、隔離なし):src/minimal_loop/dependency_setup.rs:902-921 - npm の依存の導入(
--ignore-scripts、隔離なし):src/minimal_loop/dependency_setup.rs:749-751 - 依存の導入も検証と同じ環境の正規化(
normalized_command_at_root)で起動する:src/minimal_loop/verifier_env.rs:25-29
関連(参考)
-
[security][tools] Bash の字句検査では、プログラム経由の間接書き込みや検証コマンドの副作用を閉じ込められない #502(親)
-
1a・1b・2(前提)
-
分割の Issue:1a [security][tools] Bash と検証コマンドの書き込みを OS の隔離で閉じ込める(第 1 段 a:macOS の Seatbelt と共通の土台) #655(macOS の書き込み隔離と共通の土台)、1b [security][tools] Bash と検証コマンドの書き込みを Linux の landlock で閉じ込める(第 1 段 b) #656(Linux の書き込み隔離)、2 [security][tools] Bash と検証コマンドの、home の秘密の場所の読み取りを OS の隔離で拒否する(第 2 段:読み取り隔離) #657(読み取り隔離)、3 [security][tools]
--offlineの外向きの通信を OS の隔離で遮断し、runtime の依存の導入を隔離の中で動かす(第 3 段) #658(ネットワークと依存の導入) -
1a([security][tools] Bash と検証コマンドの書き込みを OS の隔離で閉じ込める(第 1 段 a:macOS の Seatbelt と共通の土台) #655)のレビュー(H-23):runtime の依存の導入(
src/minimal_loop/dependency_setup.rsのsh -c)は 1a の隔離の外で、ワークスペースの setup.py や npm の postinstall が外に書ける。この Issue で隔離の中に入れるまでの間、SECURITY.md への明記は[security][tools] 書き込み隔離(1a)の後続:workflow の子 node の隔離の記録・mktemp の案内・run の一時ディレクトリの後片付け・文書の追記 #659 で行う。
Activity
Merge pull request #671 from Kewton/feature/issue-658-security-tools-…
Kewton commentedon Oct 13, 2026
PR #671 で develop に merge しました(merge commit
72807847、CI・acceptance・Next.js oracles すべて success)。merge 前レビュー H-29・修正だけの再確認 H-30 とも blocker 0 で、merge 前に 4 点(macOS の依存の導入の stdin、unix socket の bind、landlock のコメント、port 不明時の文書)を直しました。後続は #672、#668・#669 への追記で扱います。