Repository navigation
#655 [security][tools] Bash と検証のコマンドの書き込みを macOS の Seatbelt で隔離する(#502 の 1a) - #661
Merged
Kewton merged 3 commits intoOct 12, 2026
Merged
Conversation
…t, stage 1a) Wrap the two `sh -c` launch points — the model Bash tool (the `bash:verify` interval reuses the same function) and verifier/acceptance commands — in a new `os_sandbox` leaf module. When the Seatbelt backend is available, writes are confined to the workspace, the run's temp directory, the known dependency caches, and device files, so an indirect write the lexical guard cannot see fails. The lexical guard still runs first and is not weakened. `auto` continues with lexical checks only when the backend is unavailable and records `bash_sandbox_status` (applied=false, reason); `required` fails with `bash_sandbox_unavailable`; `off` keeps the previous behavior. The event name is the only new one; existing event names and schemas are unchanged. The run temp directory is passed to children via an explicit `TMPDIR`. 読み替え: `--sandbox` is hidden from the public flag table because the advertised flag count lives in docs/guide/README.md, which this issue's scope.allow does not include; it is documented in prose in SECURITY.md and both cli-reference pages instead. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Split the probe's exit-status decision into `classify_probe_exit` so the "only rc=0 is Available" rule is fixed by a unit test (rc=0, rc=71 with the status in the reason, and a missing status), and add a macOS integration test that asserts `probe()` matches a direct `sandbox-exec` run, which stays honest under a nested sandbox. Product behavior, the lexical guard, events, and existing expectations are unchanged. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
On non-macOS the applied tests are excluded, so their helpers, fixture field, and imports became dead code and broke `-D warnings` on Linux CI. Gate `outside_secret`, `read_secret`, `backend_available`, `install_available`, `run_wrapped`, `run_wrapped_success`, the `IndirectCase` fields only the applied tests read, and the `std::process`/`bounded_process` imports. Test names, counts, expectations, `src/`, and the corpus are unchanged. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
13 tasks
Kewton
deleted the
feature/issue-655-security-tools-bash-os-1-a-macos-seatbelt
branch
October 12, 2026 01:47
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
Bash ツールと検証コマンドの子プロセスを、macOS の Seatbelt(
sandbox-exec)で包みます。ワークスペース・run の一時ディレクトリ・必要なキャッシュの外には書けないようにします。#502 の段階 1a です。字句の検査(bash_write_guardなど)は変えず、その後ろに OS の層を足します。Refs #655
Refs #502
変更(16 ファイル、+1351 −9、2 commit)
src/tools/os_sandbox.rs:SandboxMode(auto・required・off)、利用できるかの判定、SandboxPolicy、プロセス全体の状態、install・status・startup_warning・wrap_command。src/tools/os_sandbox/seatbelt.rs:profile は固定の定数です。場所は-Dの param だけで渡します(WS・TMP・キャッシュ 6 種)。probe・classify_probe_exit・wrapもここにあります。bash.rs・verifier_env.rs:sh -cの直後にwrap_commandを呼びます。requiredで隔離が使えないときは、spawn の前に Blocked とbash_sandbox_unavailableを返します。lib.rs:run の開始時にinstallを呼び、auto で使えないときは警告を出し、bash_sandbox_statusの event を出します。cli.rs:--sandbox。今は隠しフラグです(下の「後続の論点」を参照)。bounded_process.rs:TMPDIRを通すのは、明示したときだけです。fixed_identifiers.rs・mod.rs:識別子とモジュールの宣言。tests/issue502_os_sandbox_write.rs(10 本、うちapplied_cargo_build_succeedsは ignored)と corpustests/corpus/apps/issue502-indirect-write/。SECURITY.md、cli-reference の en・ja。runner.rs・loop_run.rs・runtime_bash_effects.rs)と baseline は変えていません。event はbash_sandbox_statusを足しただけです。env_clearの後に許可リストが当たります(apply_child_env_allowlist)。親の秘密が子に届く経路は増えていません。検証
0a140c1cと、修正後の HEAD36d0b3ebの 2 回とも 15/15 passed でした。--include-ignoredを付けて流し、10 本すべて pass、SKIP 0 でした。sh -c cp・eval・xargs cp・python3 open(w)・find -exec cp・dd of=・sed -i)が拒否され、外の fixture は変わりません。mktemp -p "$TMPDIR"・git・cargo・node・python3)と、依存のないcargo buildは隔離の中で成功します。sandbox-execの結果が一致します。seatbelt.rsの PROFILE をそのまま使いました。cargo build --offline、npm ci --offline(GUI の写し)、next build、Playwright(キャッシュ済みの headless Chromium で起動・描画・終了)は、どれも成功しました。9047eb35に新しいテストを置くと、os_sandboxが無いので compile の時点で FAIL します。apply_backendを素通しにすると(develop と同じく隔離なし)、隔離を適用した状態の試験が 5 本 FAIL します。--jobs 1 --timeout 300、対象はos_sandbox.rs・seatbelt.rs)output.success()の変異です。36d0b3ebで分類をclassify_probe_exitに分け、テストを足して直しました。ifを変異させないので、if trueとif falseを手で当てました。どちらもテストで捕まりました(単体テストとprobe_matches_a_direct_sandbox_exec_run)。backend_name)か、キャッシュの許可が減る厳しい側の変異です。後続の論点(PM が別の Issue と #656・#658 に記録します)
dependency_setup.rs)は隔離の外です([security][tools]--offlineの外向きの通信を OS の隔離で遮断し、runtime の依存の導入を隔離の中で動かす(第 3 段) #658)。installを使い回します。origin とワークスペースが違うときに扱いが要ります。--sandboxは今は隠しフラグです。1b([security][tools] Bash と検証コマンドの書き込みを Linux の landlock で閉じ込める(第 1 段 b) #656)までに公開し、doc_drift のフラグの数も同じ PR で直します。/dev/の下全体に及びます。mktempは macOS の auto で失敗します。文書には書いてあります。sandbox/run-<uuid>)を後片付けしていません。🤖 Generated with Claude Code