maestro/docs/operations/bash-sandbox-provisioning.md
2026-06-03 05:08:00 +00:00

102 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bash サンドボックス 本番プロビジョニング手順 (aao)
> **順序厳守**: 先に「2. パッケージのプリベイク」を完了してから「4. 設定切替」を行う。逆順だと、サンドボックス内で `pip install` は拒否され、かつパッケージも無い状態になり、python3 を使う既存タスクoffice 処理・data 処理等)が全滅する。
## 0. 前提
- 本番 worker は aao ホスト上の Node プロセスとして動くalpine コンテナではない。bwrap は `--ro-bind /usr` でホストの `/usr` をサンドボックスに持ち込むため、**プリベイク先はホストのシステム python の site-packages**。`/home` 配下の venv はサンドボックスに mount されず見えないので不可。
- アクセス: `ssh aao``user@your-host`)。落とし穴: root でビルドしない / DB は `maestro.db` 参照)。
## 1. bwrap / python の確認・導入
```bash
ssh aao
# bwrap (bubblewrap) と user namespace
which bwrap || sudo apt-get install -y bubblewrap
bwrap --ro-bind / / true && echo "bwrap OK" || echo "bwrap NG — user namespace を有効化する必要あり"
# user namespace が無効ならDebian/Ubuntu:
# sudo sysctl -w kernel.unprivileged_userns_clone=1
# 永続化: /etc/sysctl.d/ に kernel.unprivileged_userns_clone=1 を追記
# python3 + pip
which python3 pip3 || sudo apt-get install -y python3 python3-pip
```
## 2. パッケージのプリベイク(システム python へ)
リポジトリの `runtime/python-requirements.txt` をホストのシステム python に入れる。読み取り専用 bind されるので全サンドボックスから import 可能になる。
```bash
# リポジトリの最新を pull 済みの前提
cd <maestro repo on aao>
# 推奨: 付属スクリプト冪等・import 検証付き)。権限が要る場合は sudo を付ける
sudo bash scripts/prebake-python.sh
# ↑ これは内部で `pip3 install --break-system-packages -r runtime/python-requirements.txt`
# を実行し、最後に全パッケージの import を検証する。
# 注: `scripts/build-all.sh` は最後にこの prebake を自動実行する(--skip-python で無効化)。
# ただし build-all を sudo 無しで動かす運用では system へ書けず失敗(非致命的に警告)するため、
# その場合は上記のように prebake を別途 sudo で実行すること。
#
# distro パッケージを優先したい場合C 拡張のビルド回避):
# sudo apt-get install -y python3-numpy python3-pandas python3-pil python3-lxml python3-bs4 python3-matplotlib
# 残り (pypdf, pymupdf, pdfplumber, openpyxl, xlsxwriter, xlrd, odfpy, striprtf,
# python-docx, python-pptx, markdownify, markdown, tabulate,
# python-dateutil, charset-normalizer) のみ pip
```
## 3. プリベイク検証
サンドボックス外(ホスト)で全 import が通ることを確認:
```bash
python3 -c "import pypdf, fitz, pdfplumber, docx, pptx, openpyxl, xlsxwriter, xlrd, odf, striprtf, bs4, lxml, markdownify, markdown, numpy, pandas, tabulate, dateutil, matplotlib, PIL, charset_normalizer, yaml; print('all imports OK')"
```
`fitz` は pymupdf。失敗するものがあれば `runtime/python-requirements.txt` を見直すか apt で補う。
## 4. 設定切替
`config.yaml``safety` セクション:
```yaml
safety:
bash_sandbox: always # bwrap 必須・不在なら起動失敗(本番推奨)
```
worker を再起動: `scripts/server.sh restart`。起動ログに `[startup] bash sandbox enabled — bwrap verified` が出れば OK。bwrap 不在なら `always` は起動失敗するfail-closed
> `auto` のままでも bwrap があればサンドボックスは効く。`always` は「bwrap が無ければ動かさない」明示の本番ガード。
## 5. 切替後の統合検証(設計 Task 9
テストタスクを 1 件流し、Bash ツールで以下を実行して期待結果を確認:
```bash
# 1) シークレットが見えない
python3 -c "import os; print(os.environ.get('MCP_ENCRYPTION_KEY'))" # → None
# 2) 他タスク dir / config に到達不可
cat ../../config.yaml 2>&1 || echo "blocked-as-expected"
# 3) ネット到達不可(内部サービス)
python3 -c "import socket; socket.create_connection(('10.0.0.10',8080),2)" 2>&1 || echo "net-blocked-as-expected"
# 4) プリベイク済みパッケージが使える
python3 -c "import pypdf, fitz, pandas; print('ok')" # → ok
# 5) install は拒否される(消えるインストールにならない)
pip install requests 2>&1 # → "Package installation is not available ... これは preinstalled ..."
```
加えて、既存の office 処理 / data 処理系 piece のタスクを数件流し、`--unshare-net` + プリベイクで完結することを確認dogfooding。不足パッケージが出たら `runtime/python-requirements.txt` に追加 → 手順 2 を再実行(実行時 `pip install` は恒久的に不可)。
## 6. ロールバック
```yaml
safety:
bash_sandbox: auto # bwrap があれば使い、無ければ hardened-whitelist にフォールバック
# もしくは offbwrap を使わない。env スクラブは維持。デバッグ用)
```
`scripts/server.sh restart`。コード変更不要、設定のみで戻せる。
## 補足: Docker イメージ運用の場合
`Dockerfile` (`node:22-alpine`) には `bash bubblewrap python3 py3-pip` + `pip install -r runtime/python-requirements.txt``--break-system-packages`)を追加済み。ただし alpine/musl では `pandas/numpy/lxml/Pillow/pymupdf` の wheel 解決にビルド依存が要る場合があるため、イメージビルドを実機で検証すること(`pymupdf>=1.24` に pin 済)。コンテナ運用では `features: nesting=1`user namespaceが前提。