powered by TechFeed
表示モード
Deep Dive

AIエージェントが生成するコードを本番環境から隔離する — Google Cloud Run Sandboxesが示す「権限ではなくデータを渡す」設計

8月10日、Shuva Jyoti Karが「Cloud Run Sandboxes: Building Secure Execution Plane for AI Agents」と題した記事を公開した。この記事では、Cloud Run Sandboxesを使ってAIエージェントが動的に生成するコードを安全に実行するためのアーキテクチャについて詳しく紹介されている。

8月10日、Shuva Jyoti Karが「Cloud Run Sandboxes: Building Secure Execution Plane for AI Agents」と題した記事を公開した。この記事では、Cloud Run Sandboxesを使ってAIエージェントが動的に生成するコードを安全に実行するためのアーキテクチャについて詳しく紹介されている。


問題の本質:「信頼していないコードを実行する」ということ

記事はある夜の出来事から始まる。午前2時13分、AIエージェントが顧客データセットの分析を依頼された。タスク自体は無害だった。だが、エージェントが生成したPythonプログラムはアプリケーションランタイムの中で直接実行された。その結果、生成されたコードはサービスのファイルシステム、環境変数、ネットワークアクセス、実行時アイデンティティをすべて継承した。

Shuva Jyoti Karはこれを「アーキテクチャ上の問題」と呼ぶ。

アプリケーションが自ら書いていないコードを実行するとき、何が起きるか?

LLMが生成するコードは、実行前にその振る舞いを完全に決定できない。これが従来のアプリケーションコードとの根本的な違いだ。通常のコードはレビューされ、デプロイされ、組織が管理している。エージェントが生成するコードはランタイムで生まれる

「コンテナに入れればよい」という答えは不完全だ。エージェントのワークロードは短命で粒度が細かく、一つのタスクで複数のプログラム生成・テスト実行・ツール呼び出しが発生する。そのたびに独立したコンテナをプロビジョニングしていては運用コストが現実的でない。


Cloud Run Sandboxesが提供する境界

Cloud Run Sandboxesは、既存のCloud Runサービスインスタンスの内側に、動的なコードのための分離された実行環境を作る仕組みだ。別のCloud RunサービスでもVMでもなく、既存インスタンスから呼び出せる「実行プリミティブ」として機能する。

信頼ドメインは明確に二分される:

  • アプリケーション:アイデンティティ、認可、ポリシー、クレデンシャル、オーケストレーションを所有する
  • サンドボックス:動的に生成された、あるいは完全には信頼できないコードを実行する

デフォルトでは、サンドボックス内のプロセスは以下にアクセスできない:

  • Cloud Runサービスの環境変数
  • Googleのメタデータサーバー(=サービスアカウントのトークン取得経路)
  • コンテナルートファイルシステムへの書き込み(読み取り専用ビューのみ)
  • アウトバウンドネットワーク(明示的に許可した場合のみ有効)

メタデータサーバーの遮断は特に重要な設計上の決断だ。Google Cloudではインスタンス上で動作するプロセスが169.254.169.254へアクセスすることでサービスアカウントのアクセストークンを取得できる(AWSにおけるIMDSv1に相当する仕組みであり、Workload Identityでも同様のフローが使われる)。サンドボックスがこの経路を遮断することで、生成コードがサービスアカウントの権限を悪用してCloud StorageやBigQueryなどへ横断的にアクセスする攻撃経路を原則として閉じることができる。

ネットワークアクセスは「アンビエントな権限」ではなく、アプリケーションが明示的に付与する「ケイパビリティ」になる。この設計思想が重要だ。

ただし一点、見落としやすい制約がある。サンドボックスは独立したリソースプールを持たない。CPUとメモリは既存のCloud Runインスタンスと共有される。複数の並行実行があれば、アプリケーション自身と競合する。たとえばサンドボックス内のコードが計算集約的な処理でCPUを専有した場合、同一インスタンスで動くオーケストレーション層のレイテンシが直接悪化する。並行サンドボックス数やタイムアウト設計は、この共有リソース前提を踏まえて慎重に決める必要がある。


実装の核心:「権限ではなくデータを渡す」

記事が提示するアーキテクチャパターンは明快だ。AIデータアナリストを例に取る。ユーザーが「Q2とQ1の売上を比較し、最も落ち込んだ顧客5社をグラフにしてくれ」と依頼する場合:

  • アプリケーションが行うこと:ユーザー認証、データアクセス権の確認、本番DBからの必要データ取得
  • サンドボックスが受け取るもの:クレデンシャルではなく、バウンドされたCSVファイル
User
  ↓
Authenticate
  ↓
Authorize dataset
  ↓
Query production data
  ↓
Bounded dataset → Sandbox

生成されたPythonコードは本番DBのクレデンシャルを必要としない。

クレデンシャルをコードに渡すのではなく、認可済みのデータをコードに渡す。

デプロイとコード例

サービスデプロイ時に--sandbox-launcherフラグを付けるだけで有効になる:

gcloud beta run deploy agent-service \
  --image=REGION-docker.pkg.dev/PROJECT/agents/analyst:latest \
  --sandbox-launcher

一回限りの実行はsandbox doで完結する:

sandbox do -- python3 /workspace/analysis.py

アプリケーションからはサブプロセスとして呼び出す:

import subprocess
result = subprocess.run(
    [
        "/usr/local/gcp/bin/sandbox",
        "do",
        "--",
        "python3",
        "/workspace/analysis.py",
    ],
    capture_output=True,
    text=True,
    timeout=30,
)
if result.returncode != 0:
    raise RuntimeError(result.stderr)
print(result.stdout)

複数ステップのワークフロー(コードエージェントがリポジトリを検査し、テストを実行し、成果物をパッケージする、など)では、サンドボックスを存続させてsandbox execを繰り返し呼び出すことができる:

sandbox run --detach agent-workspace -- sleep 1h
sandbox exec agent-workspace -- python3 inspect.py
sandbox exec agent-workspace -- python3 test.py
sandbox delete agent-workspace
ワークロード 実行モデル
単一の生成プログラム sandbox do
複数ステップのエージェント sandbox run + sandbox exec
サンドボックスを超えて残すべき状態 明示的なエクスポート/永続化

セキュリティ上の注意点

記事は重要な点を強調している。サンドボックスは分離メカニズムであり、認可システムではない

サンドボックスが答えるのは「このコードが実行環境に対して何ができるか」という問いだ。「このコードに何を許すべきか」という問いに答えるのはアプリケーション側の責務であり続ける。入力の検証、出力のバリデーション、ポリシーの評価はすべてアプリケーションが担う。サンドボックスはその前提となる実行境界を提供するものだ。

なお、Cloud Run上でのサービスアカウント権限の設計指針についてはCloud Run IAMドキュメントが参考になる。また、Cloud Runの実行基盤として使われているコンテナサンドボックス技術gVisorの概要を把握しておくと、Sandboxesが提供する分離の技術的な背景をより深く理解できる。


※編集部の考察:Cloud Run Sandboxesのアーキテクチャパターンは、LangGraphVertex AI Agent Builderといったフレームワークとの組み合わせでも適用できる。コードインタープリタを内部ツールとして持つエージェントの実行プレーンとして、信頼境界の設計指針として参照する価値がある。

詳細はCloud Run Sandboxes: Building Secure Execution Plane for AI Agentsを参照していただきたい。