Repository navigation
[security][tools] Bash と検証コマンドの、home の秘密の場所の読み取りを OS の隔離で拒否する(第 2 段:読み取り隔離) #657
Description
背景
#502 の第 2 段です(#502 の「設計の決定」の節、2026-10-11 承認)。#502 は 1a・1b(書き込み隔離)の merge で閉じ、読み取り側はこの Issue に引き継ぎます。
#501 で、資格情報ファイルの遮断は型付きツール・MCP・pack の入力・Bash の字句上の直接参照に入りました。一方、#502 のコメント(#501 の引き継ぎ、#568・#576・#582・#602・#603・#635 のレビュー)にある次の形は、字句に秘密の名前が現れないため、字句検査では閉じません。
- 秘密でない名前の symlink を通した、dotenv・ssh・aws の資格情報の読み取り
- ファイルを読む環境変数(
BASH_ENV等) - heredoc の python が実行時に組み立てる名前
echo $HOME/*のような名前の一覧
H-18 の試作(macOS、偽の鍵)では、Seatbelt の読み取りの拒否で、symlink 経由の鍵が読めないことを確かめました。Linux の landlock は未確認です。
問題
- 1a・1b の後も、Bash と検証コマンドは、OS の利用者が読めるものをすべて読めます。home の鍵・クラウドの資格情報を、字句に現れない形で読み、出力に載せられます。
- landlock は「許可した木の中の一部だけを拒否する」書き方ができません(許可リスト型)。
設計(決定)
- 拒否リスト型(判断 4):home の秘密の場所の読み取りを拒否し、他は今どおり読めるようにします。一覧は今の資格情報の判定([security][tools] 通常の Read で、モデルがワークスペースの .env(API キー)を承認なしに読める #501)の規則と揃え、home に特有の場所(gnupg、gh・gcloud の設定、kube の設定)を足します。具体的な一覧は「参照」。一覧は 1 か所に置き、macOS と Linux の backend が同じものを使います。
- macOS(Seatbelt):profile に
(deny file-read* …)を足します。home の秘密の場所に加え、ワークスペースの中の資格情報ファイル([security][tools] 通常の Read で、モデルがワークスペースの .env(API キー)を承認なしに読める #501 の名前の規則。dotenv・envrc・npm の設定等。テンプレートの名前は除く。一覧は「参照」)の読み取りも拒否します。場所は-Dの param と、名前の規則の正規表現で渡します。 - Linux(landlock):読み取りを handled access に入れると、許可しない場所はすべて読めなくなります。拒否リストを、run の開始時に「home の祖先の各階層で、秘密の場所を含まない兄弟をすべて許可する」許可リストに展開して表します。
- run の開始の後に、展開した階層に新しく作られた場所は読めません(文書に書く)。
- ワークスペースの中の資格情報ファイルは閉じられません(判断 4)。字句検査に残ることを文書に書きます。
- 決定(2026-10-11):home の npm の設定も読み取りを拒否します。private registry の認証を使う npm は Bash の中で失敗します。トークンを Bash に読ませない方針の帰結として文書に書きます。
- 環境変数で読ませる形:
BASH_ENV等が home の秘密の場所を指す形は、隔離で閉じます。ワークスペースの中の資格情報ファイルを指す形は、macOS では隔離で、Linux では字句検査で守ります。 - 範囲の外:凍結された検証入力(protected paths)の書き込み拒否は、Bash の呼び出しごとに完了の契約の一覧を隔離へ渡す配線が要り、成長上限の対象の経路に触るため、この Issue では扱いません(後続の候補)。
- 字句検査は変えません。誤拒否の多い部分を緩めるかは、この Issue の後に、別の Issue で
requiredの run の誤拒否の実績を見て判断します。
規模の見積り
- 新規:秘密の場所の一覧と展開 約 60〜80 行、macOS の profile の追加 約 30〜40 行、Linux の許可リストへの展開 約 100〜130 行。合わせて約 200〜250 行。
- 配線:葉モジュールの方針に読み取りの規則を足す 約 10 行。1a・1b の起動点は変えない。
- 試験:約 200 行と corpus。新規 500 行を超えない見込みなので、分けません。
受け入れ条件
- 偽の鍵を置いた tempdir の fixture で(試験は
HOMEを tempdir に向け、実際の home を読まない)、macOS と Linux の両方で、home の秘密の場所の読み取り(直接、秘密でない名前の symlink 経由、BASH_ENV経由、heredoc の python が組み立てた名前)が隔離で失敗する。 - macOS で、ワークスペースの中の dotenv のファイルを秘密でない名前の symlink 経由で読む形が、隔離で失敗する。テンプレートの名前(example・sample・template)のファイルは読める。
- Linux で、ワークスペースの中の dotenv のファイルを名指しする形が字句検査で拒否されることを確かめ、symlink 経由の形は隔離で閉じないことを文書に書く。
- Linux の許可リストへの展開で、ツールチェーン(cargo・rustup・npm・node・python・pyenv や nvm の配下)・git・システムの場所が読めることを確かめる。
--versionと小さな build(依存のない crate のcargo build、キャッシュ済みの fixture のnpm ci)の結果を、macOS(入れ子でない環境)と Linux(CI)で記録する。 - home の npm の設定を拒否したとき、private registry の認証を使う
npmが失敗することを文書に書く(トークンを Bash に読ませない方針の帰結)。 -
bash_sandbox_statusの reason に、読み取りの隔離の適用・未適用を出す(既存のイベントの schema に field を足すだけで、名前と既存の field は変えない)。 - 秘密情報、[security][tools] 通常の Read で、モデルがワークスペースの .env(API キー)を承認なしに読める #501・[security][tools] Bash の書き込み検査の字句解析がバッククオートのコマンド置換を扱わず、中の書き込みを見逃してワークスペース外へ書き込める(#576 の調査で発見) #581・[security][tools] Bash の字句解析が二重引用の中の $(…)・${…} の " を引用の閉じと読み違え、後ろをコメントとして消してワークスペース外へ書き込める(#581 のレビューで発見) #585・[security][tools] Bash の 2 段目の path 検査が、$・glob・動的な値で静的な相対パスや展開先を確かめず、ワークスペース外を読める(#571 を統合) #582・[security][tools] Bash の書き込み先で、引用した閉じ記号と実行される glob・brace が混ざると、外向き symlink の先への書き込みを拒否しない(#582 のレビューで発見) #602・[security][tools] Bash の 2 段目の path 検査が、空白を含む静的パスと = 付きの引数を候補にせず、外を読める(#582 のレビューで発見) #603・[security][tools] Bash の閉じ込めの検査が、引用していない CR を区切りとして扱い、/ を含まない相対の語を候補にしないため、外向き symlink を通して外を読み書きできる(#602・#603 のレビューで発見) #613 の印と判定が緩む向きに変わらない。今の decision の表で、R・A・W・P・S が 1→0 になる行と、V が 0→1 になる行が 0 件。
- 字句検査を緩めていない。
- event の既存の名前と schema を変えていない(新しい field の追加は可)。
- 既存の検証・受入・証跡・リリースゲートを緩めていない(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/tools/os_sandbox/secret_locations.rs(新規)tests/issue502_os_sandbox_read.rs(新規)tests/corpus/apps/issue502-indirect-read/expectations.toml(新規)tests/corpus/apps/issue502-indirect-read/(新規。fixture)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 の葉モジュール(
src/tools/os_sandbox.rs) - ワークスペースの中の資格情報ファイルの名前の規則([security][tools] 通常の Read で、モデルがワークスペースの .env(API キー)を承認なしに読める #501):
.env・.env.*・.envrc・.npmrc・.pypirc・.netrc・.git-credentials・.ssh、service-account*.json、*.private.key・*.private.pem、*.p12・*.pfx。テンプレート:.env.example・.env.sample・.env.template - home の秘密の場所の一覧(案):
~/.ssh、~/.aws、~/.gnupg、~/.netrc、~/.git-credentials、~/.npmrc、~/.pypirc、~/.docker/config.json、~/.kube、~/.config/gh、~/.config/gcloud - 設計調査の記録:ローカルの workspace/tmp/1007/wave1/results/H-18/report.md の 2・4 章(試作のログは SSD の wave1-20261007/h18/probe-log.md)
根拠(develop d708619a)
- 資格情報の名前の規則:
src/tools/sensitive_path.rs:94-117(sensitive_name_rule)、パスの規則(aws・docker・gcloud):src/tools/sensitive_path.rs:146-166、テンプレートの名前:src/tools/sensitive_path.rs:16 - Bash の字句上の秘密の拒否:
src/tools/bash.rs:195(sensitive_bash_rejection)、src/tools/bash.rs:716 - 「Bash の任意のプログラムが秘密を読めないとは言えない、[security][tools] Bash の字句検査では、プログラム経由の間接書き込みや検証コマンドの副作用を閉じ込められない #502 で追跡」の記述:
SECURITY.md:109-115 - 凍結された検証入力の判定と、その一覧の出どころ:
src/tools/bash_write_guard.rs:234、src/minimal_loop/protected_paths.rs:30、src/minimal_loop/completion.rs:31
関連(参考)
-
[security][tools] Bash の字句検査では、プログラム経由の間接書き込みや検証コマンドの副作用を閉じ込められない #502(親)、[security][tools] 通常の Read で、モデルがワークスペースの .env(API キー)を承認なしに読める #501
-
1a・1b(前提)、3:ネットワークと依存の導入
-
後続の候補:凍結された検証入力の書き込みを OS の隔離で拒否する(Bash の呼び出しごとに一覧を渡す配線が要る)。字句検査の誤拒否の多い部分を、
requiredの run に限って緩めるかの判断。 -
分割の 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(ネットワークと依存の導入)
Activity
Merge pull request #670 from Kewton/feature/issue-657-security-tools-…
Kewton commentedon Oct 13, 2026
PR #670 で develop に merge しました(merge commit
e79191fd、CI・acceptance・Next.js oracles すべて success)。merge 前レビュー(H-28)は blocker 0 で、見つかった限界は SECURITY.md に明記し、後続は #668(Linux の reason・展開の上限)と #669(macOS の rename、private registry)で扱います。