AIが書いたコードに、どこまで操作を任せるか
顧客から届いた問い合わせCSV(カンマ区切りで表データを保存する形式)を、AIが作ったコードで整理する場面を考えます。これは仕組みを説明する仮想例です。
運用チームは、業務API(ソフトウェアから別の機能を呼び出す仕組み)からコードに追加情報を読み取らせたいと考えています。運用チームは、本番環境のAPI鍵や自由な更新権限をコードに渡しません。
このとき確認する対象は二つあります。一つは、コードが動く環境とホスト側の分離条件です。もう一つは、外部APIのどの操作を許すかです。追加情報を取得する接続条件と、許可するAPI操作の範囲をそれぞれ定めます。
Plimsollは、既存の実行基盤の前段で、呼び出しごとの最低隔離条件とAPI操作の権限を扱うツールです。本稿は固定コミットの公式資料と実装を確認しています。
普通のcontainer・VM・proxyで足りる範囲
コンテナはホストのOSカーネル(OSの中核部分)を共有する実行環境です。VM(仮想マシン)は、別のゲストOSを動かす環境です。鍵を持つproxy(通信の仲介役)を置けば、コードに直接API鍵を渡さずに済む構成も作れます。
固定コードを一つの実行先で動かし、必要な隔離・認証・操作許可を自分で管理できているなら、本稿では既存構成を続けられると考えます。
実行先や要求が変わる運用では、「この呼び出しが要求する最低条件を満たすか」「失敗した要求は実行済みか」を呼び出し側が確かめたい場合があります。Plimsollでは、この契約と、API権限の選択・操作制限を共通の呼び出し口で扱います。採用の判断は、既存運用で何を確認できているかから始めます。
最低条件を指定し、実行前の拒否と実行後の失敗を分ける
隔離条件の文書では、呼び出し側が MinimumIsolation に許容する最低の分類を指定できます。分類をtierと呼び、process・container・kernel・vmの四つで報告します。
daemonは要求を受けて実行を管理するサーバです。providerは実際にコードを動かす基盤です。
| 報告tier | この版での代表的な実行基盤 | 確認する境界 |
|---|---|---|
| process | daemon内のQuickJS(JavaScriptエンジン)/WASM(WebAssembly) | 別のOSプロセスの壁ではなく、敵対的なコード向けではない |
| container | 通常のDockerなど | ホストカーネルを共有する |
| kernel | gVisor/runscを使うDocker | 設定と起動時検査を根拠に報告する分類 |
| vm | E2BやDocker CloudのmicroVM(軽量な仮想マシン) | 実行基盤の種類と検査に依存し、セルフホストVMを一律に提供する意味ではない |
tierはdaemonの観測、構成、providerの情報に基づく報告で、ハードウェアに根差した暗号的な実行環境の証明(attestation)ではありません。
実行前の検査コードは、指定された最低条件を満たせなければ、コードを実行基盤へ渡す前に拒否します。最低条件を指定しない場合、呼び出し側独自の追加条件は設けられません。
一方、結果を受け取った後にtierの不足を見つける ErrIsolationEvidenceMismatch は、既にコードが動いた可能性を残します。これを自動再実行してよい根拠にはできません。
結果と拒否の契約では、実行前に拒否したエラーには未実行を示す標識を付けます。公式clientは応答が自分の要求IDと対応するかも確認します。標識のないエラーや対応しない応答は、未実行と決め付けられません。更新操作を重ねてしまわないために、この区別が必要です。
上流APIの鍵は窓口側で扱い、許可した操作だけ仲介する
APIへの操作許可をgrantと呼びます。daemon経由で実行する場合、サーバ側の設定は、どの認証済みの呼び出し元がgrantを利用できるかを制限します。呼び出し元が任意の権限を自称して通せる形ではありません[1]。
grantがない実行、または許可先リストが空の実行では、外部APIを呼び出す権限がありません。grantを付けても、コードに一般的な直接ネットワークアクセスを与える設計ではありません[3]。
コードを隔離して動かす環境をsandboxと呼びます。仲介役をbrokerと呼びます。コードから依頼を受け、許可された操作を上流APIへ送る際に、broker側でそのAPIの資格情報を付けます。上流APIは、実際の業務データや機能を持つ相手側です[2]。
grantの文書は、操作の種類を表すHTTPメソッドと、対象を表すパスで許可範囲を絞る仕組みを説明しています。読み取り用のルールを設定した仮想例なら、同じ対象への更新操作まで許したことにはなりません。
資格情報の扱いでは、JWT(JSON Web Token)方式は実行ごとに認証トークンを作ります。static方式(設定済みのトークンを使う方式)は、bearer token(所持者が提示して使う認証トークン)を再利用します。実行ごとの取得処理があることと、常に短命の資格情報を新規生成することは分けて読みます。
backendごとの制約には、Docker Cloudのguest(隔離環境内で動くコード)が、その実行のguard(呼び出しを検査する窓口)用の制限付き資格情報を持つ例外もあります。「秘密が一切guestにない」という保証に広げず、上流APIの資格情報を分離する設計として捉えます。
許可したAPI、残る状態、実行記録を確認する
brokerのroute認可は、操作とパスを確認し、送信本文の意味までは検査しません。許可されたAPIも、コードが読んだデータの持ち出し先になり得ます。送ってよいデータと許可先の組み合わせは、運用側で判断します[6]。
状態を次の呼び出しへ残すsessionもあります。同じ認証済みcaller(呼び出し元)に結び付くため、複数の顧客を共通callerで扱うアプリは、顧客ごとの分離を管理します[4]。session内のgrantを有効にすると、前の呼び出しが残したコードも後のgrantを利用し得ます[5]。
brokerの終了処理は、その実行に対する後続の呼び出しを拒否し、進行中の呼び出しをcancelします。既に起きた業務更新を取り消す機能ではありません。JWTは実行終了で失効せず、期限の検査は上流APIにも必要です。static tokenに自動で期限を加える仕組みでもありません。
実行記録には、要求・結果のハッシュ、provider、tier、実行時刻などが入ります。ハッシュは内容を識別する値です。公式のGo clientは、自分が送った要求と受け取った結果から値を再計算し、記録との対応を確認します。
この照合は、保持している要求・結果とdaemonの記録の整合性を確認するものです。実行環境の証拠はdaemonの説明であり、侵害されたdaemonは虚偽を述べられます。記録だけでコードの正しさや無害性、業務成果まで確認したことにはなりません。
開発段階と導入時の判断
この版のREADMEのStatusは、pre-1.0・単独作者・外部ユーザなしと説明しています。SECURITYは第三者監査が未実施と明記しています。CI(変更ごとに行う自動検査)の実施状況と、第三者監査の実施状況を区別します[7]。
導入文書のDocker/gVisor手順はLinuxを前提とします。daemonをセルフホストする構成と、クラウドproviderで実行する構成の費用・運用条件も区別します。本稿では導入や実行試験は行っておらず、作者の文書・実装を静的に照合しています。
採用を検討するチームは、要求した最低条件、未実行の判定、許可先へのデータ送信、顧客ごとの状態分離を、自分の運用要件で確認します。Plimsollの価値はこれらの契約をまとめて扱えることにあり、安全性全体の保証ではありません。



