連載「Tines 3B を読み解く」の第2回です。第1回(全体像)はこちらです。第1回で見た3つの層のうち、「動かす」層の土台にあたる、実行とネットワークの分離を扱います。
はじめに
AI にコードを書かせるのは簡単になりました。難しいのは、そのコードを「動かして大丈夫か」を決めることです。中身を全部読めるわけではありませんし、外へデータを送ったり、社内のシステムに触れたりするかもしれません。
この記事では、AI ネイティブのワークフロー基盤「Tines 3B」がこの問題を実行環境とネットワークの設計でどう扱っているかを、公式ドキュメントに沿って整理します。
こんな方に向けて書いています。
- AI が書いたコードを社内の環境で動かすことを検討している
- 「コンテナで動かせば安全」の、その先を知りたい
- 社内のシステムにつなぐとき、受信ポートを開けずに済む方法を知りたい
先に結論です。3B は実行のたびに使い捨ての環境を用意し、外へ出る通信を1か所に集め、社内へは社内側から外向きに張った接続で届かせます。そのうえで、守られない範囲もはっきりあります。
こんな場面、ありませんか
- AI が書いたコードを同じサーバーで動かしている。前の実行が残したファイルやプロセスが次の実行に影響しないか、確かめきれない。
- コードが社内のネットワークや、クラウドのメタデータ(インスタンスの認証情報が取れる場所)に届いてしまわないか。
- 社内のデータベースを使わせたいが、そのために社外から社内への受信ポートを開けたくない。
共通するのは、「動く場所と届く先を、コードの側で決められてしまう」ことへの不安です。
結論:3つの設計
3B の設計は、次の3つに整理できます。
| 設計 | 何をするか | 防ぐもの |
|---|---|---|
| 実行ごとに使い捨てる | 実行ごとに専用のサンドボックスを作り、終わったら破棄する | 実行どうしの干渉、ホストへの到達、残り物の持ち越し |
| 外への道を1本にする | 外向きの通信は、すべて egress proxy を通す | 内部宛やメタデータ宛への到達、コードによる回避 |
| 社内へは外向きの接続で届く | 社内のホストが、3B へ外向きに接続して保つ | 社内への受信ポートの開放 |
設計1:実行ごとに使い捨てる
1回の実行の流れ
ステップの実行もチャットでの試行も接続のテストも、その作業のためだけに作られたコンテナで動き、コンテナは終わるとすぐに破棄されます。流れを図にしました。
実行をまたいで残るのは /storage のボリュームと記録(出力とログ)だけです。作業ディレクトリやスクラッチ領域は、実行が終わると消えます。
サンドボックスの守り
守りを表にまとめます。
| 層 | 説明 |
|---|---|
| gVisor | コードと本物のカーネルの間に入る追加の層。システムコールを、ホストに届く前に横取りする |
| seccomp | gVisor と組み合わせた多層防御 |
| 読み取り専用のファイルシステム | ステップに与えたスクラッチ領域以外は、読み取り専用 |
| 特権の削減 | 特権を、可能な限り落とす |
| 専用のネットワーク空間 | 実行ごとに、専用のネットワーク名前空間を割り当てる |
各実行のネットワーク、ファイルシステム、プロセス空間が独立し、ホスト、他のテナント、内部サービスから切り離されます。あるステップから、別のステップのファイルやプロセスは見られません。
使い捨てなので、次の実行はいつもクリーンな状態から始まります。速さを保つために、準備済みのサンドボックスを待機させています(ウォームプール)。
時間とメモリの上限
実行には時間、メモリ、通信量の上限があります。時間を超えれば停止し、メモリを超えたステップは強制終了されます。ステップの timeout は 1〜300秒で、既定は45秒です。公式では、短く保つことが勧められています。
メモリや通信量の上限の値は公開されていません。
設計2:外への道を1本にする
egress proxy が決めること
サンドボックスの中のコードは、ネットワークへ直接出られません。外向きの要求はすべて egress proxy を通ります。判断はサンドボックスの外で行われるので、コードからは上書きできません。
役割は3つです。
| 役割 | 内容 |
|---|---|
| 認証情報の注入 | ステップは認証なしで要求し、proxy が送出のときに認証を付ける(第3回で扱います) |
| 危険な宛先の遮断 | 内部やプライベートなアドレス、クラウドのメタデータ宛の接続を拒否する(SSRFガード) |
| ネットワークの適用 | 宛先がネットワークに一致すれば、そのネットワーク経由にする |
SSRF は、コードがだまされて、本来届くべきでない内部の宛先へ要求を送ってしまう攻撃です。内部への要求を既定で遮断して、これを防ぎます。
ネットワークは宛先で自動的に決まる
「ネットワーク」は宛先(IP の範囲、ホスト名のパターン)で定義します。ステップから指定するのではなく、宛先が一致したときに自動で使われます。
使えるのは、そのスペースで作る人と動かす人の全員が、そのネットワークを使う権限を持つときだけです。権限がないスペースからの一致した通信は遮断され(fail closed)、インターネットへ迂回することはありません。
テナント全体の許可・拒否のルールもあります。宛先をホスト名か CIDR で指定し、保存すると新しい通信から効きます。
設計3:社内へは外向きの接続で届く
社内の公開していないシステムへ届けるには、「トンネル」を使います。社内のホストで Exit Node という小さなコンテナを動かし、Exit Node が 3B の tunnel gateway へ外向きに接続して、その接続を保ちます。社内向けの通信は、この接続を通って届きます。
要点は3つです。
- 受信ポートを開けません。Exit Node が外向きに接続するので、社内のファイアウォールに受信の穴は要りません。
- 相互に認証します(mTLS)。トンネルの作成時にクライアント証明書が発行され、一致する接続だけが受け入れられます。
- 届く範囲は決めた宛先だけです。宛先は IP の範囲かホスト名のパターンで定義します。
トンネルのトークンは作成時に一度だけ表示されます。失くしたら、新しいネットワークを作り直します。また、トンネルの機能はデプロイごとに有効にする仕組みなので、作成の画面に選択肢がなければ Tines に依頼します。
守ってくれないこと
守られる範囲と、利用者が担う範囲は別です。
- 宛先に一致しない通信は、既定で公開インターネットへ出ます。ネットワークに一致しない通信は、通常の経路で公開インターネットへ向かいます。「許可した宛先にしか出られない」わけではありません。送信先を絞るには、上記のルールや自社のファイアウォールなどを設計します。
- セルフホストでは、ステップ単位の cgroup が既定で無効です。cgroup はステップごとに 1 vCPU と 2 GiB を上限とする仕組みで、無効のあいだはステップ単位の CPU・メモリの制限なしで動きます。公式では、worker を増やすときに有効にすることが勧められています(運用の詳細は第9回)。
-
ALLOWED_CIDR_BLOCKSは遮断より優先されます(セルフホスト)。内部ネットワークへ届かせる範囲を書く設定です。公式では、メタデータの範囲やそれを含む広い範囲(たとえば0.0.0.0/0)を書くと、クラウドのインスタンス認証情報がワークフローのコードに露出すると警告されています。最小の範囲だけを書きます(第9回も参照)。 - 同じスペースで同じ名前のボリュームを宣言したワークフローは、同じファイルを共有します。実行ごとの分離は、ボリュームの共有までは含みません。
- 完全の保証はありません。分離は gVisor などの実装の正しさに依存します。公式では、完全な安全を保証する記述はされていません(これは筆者の整理です)。
他のやり方との違い
実行の分離の方式を、一般的な分類で比べてみます(特定の製品の仕様ではなく、考え方の整理です)。
| 方式 | 実行の単位 | 外向き通信 | 弱点 |
|---|---|---|---|
| 共有のワーカーで実行 | 1つのワーカーに、複数の実行が同居 | 実行ごとの制御は、別に設計 | 一時ファイルやプロセスが残りうる。ホストのカーネルを共有する |
| 通常のコンテナ | 実行ごとのコンテナ | 別途の設定が要る | ホストのカーネルを共有するため、脱出の影響が大きい |
| ユーザー空間のカーネル型(3B は gVisor) | 実行ごとの使い捨て環境 | 1本の出口に集める | 互換性や速度とのトレードオフがある。実装の正しさに依存する |
どの方式も万能ではありません。3B の特徴は、実行の分離と出口の一本化を同じ基盤の中で組み合わせている点です。
おわりに
- 実行のたびに、使い捨てのサンドボックスを作る。
- 外向きの通信は egress proxy の1本に集める。
- 社内へは、社内側から外向きに張った接続で届く。
「動かして大丈夫か」への答えは、「大丈夫にするための構造はある。ただし、残る範囲は設計と運用で決める」ということになりそうです。
連載の他の回
連載「Tines 3B を読み解く」(全11回):
- 第1回 AIが作るコードの乱立に、どう備えるか。Tines 3B の全体像と5つの強みを読み解く
- 第2回 AIが書いたコードを、動かして大丈夫か。Tines 3B の実行とネットワークの分離を読み解く(この記事)
- 第3回 AIエージェントに、APIキーを渡さない。Tines 3B の認証情報の設計を読み解く
- 第4回 AIに、誰の権限で何をさせるか。Tines 3B の権限とガードレールを読み解く
- 第5回 「誰が何をしたか」と「いくらかかったか」を、どう見るか。Tines 3B の監視・監査・費用を読み解く
- 第6回 AI にチャットで作らせても、実体はコード。Tines 3B の「コードファースト」を読み解く
- 第7回 本番を壊さずに直す。Tines 3B のドラフトと本番、自己修復(Autofix、Autotune)を読み解く
- 第8回 「ベンダーに縛られない」は、どこまで本当か。Tines 3B の接続口と、持ち出せる範囲を読み解く
- 第9回 自社環境で動かすなら、何を引き受けるか。Tines 3B のセルフホストを読み解く
- 第10回 契約の前に、何を書面で確かめるか。Tines 3B の導入・契約・費用を読み解く
- 第11回 Tines 3B か、他の製品か。8つの軸で見分ける
参考
公式ドキュメント(docs.3b.tines.com):
- Containerized / Isolated execution
- Understand how your workflows run
- Networks
- Tunnel
- Reach a private network through a secure tunnel
- Secure your credentials with credential proxy
- Credential proxy
- Environment variable reference
- Connectivity requirements
- How and when to scale
- Storage / Volume
- Build a workflow in your own coding tools
- Tines 3B Dictionary