大企業で働いた経験があれば、標準的な企業ノートPCのセットアップを目にしたことがあるだろう。エンドポイント保護、ブラウザフィルタリング、デバイス管理、ネットワーク制御、証明書ストア、シークレットスキャナー…。これらは、信頼された従業員が誤って認証情報を漏洩したり、悪意あるパッケージをインストールしたり、間違ったページにアクセスしたりするのを防ぐためのツールだ。このようなツールが存在するのは、開発者が広範なアクセス権を持ち、コードを実行し、依存関係をインストールし、システム間でデータをコピーし、内部・外部のサービスに認証するからだ。エンタープライズセキュリティは、この強力で開かれた環境をより安全にするために構築されてきた。
エージェントはこの問題の規模と形状を変える。あなたは一人の開発者にノートPCを与えているわけではない。数千、あるいは数百万の「信頼できない開発者」を生み出しているかもしれない。これらの開発者はあなたに代わってコードを書き、コマンドを実行し、パッケージをインストールし、ネットワークリクエストを行うことができる。人間の開発者にとって、環境はデフォルトで開かれている必要があることが多い。彼らは探索、デバッグ、ツールのインストール、新しいサービスへのアクセスが必要だからだ。しかしエージェントに対しては、デフォルトを変えることができる。タスクが既知であれば、ネットワークを狭くできる。エージェントがGitHubとLLMプロバイダのみを必要とするなら、インターネット上のあらゆるホストと通信できるべきではない。資格情報が必要なら、その資格情報はランタイム内に存在する必要すらない。ここでサンドボックスネットワーキングがエージェントハーネスの第一級市民となる。
LangSmithサンドボックスは、エージェントに隔離された環境を提供し、メインのインフラストラクチャに影響を与えずにコードを実行しファイルシステムを操作できるようにする。しかし、隔離だけでは不十分だ。エージェントはモデルプロバイダ、GitHub、パッケージレジストリ、内部サービス、データAPIなど、外部APIを呼び出す必要がある。サンドボックス認証プロキシ(Auth Proxy)は、エージェントが生成した動作と外界との境界を制御するために設計された。
その仕組みはこうだ。エージェントまたはサンドボックスコードがアウトバウンドリクエストを発行し、そのリクエストはAuth Proxyを通過する。プロキシはその宛先に対して設定されたポリシーをチェックし、リクエストをブロック、許可、またはヘッダーを付加することができる。リクエストはランタイムに認証情報を公開することなく宛先に到達する。簡単なルールの例としては、サンドボックスがapi.openai.comを呼び出す際に、LangSmithワークスペースのシークレットから取得したAuthorizationヘッダーを注入するものがある。別のルールでは、api.github.comの特定のパスに対してGitHubトークンを注入する。
このモデルにより、次の3つのことが容易になる。第一に、認証情報がランタイムの外に留まる。エージェントはAPIキーを読み取ることなくAPIを使用でき、プロンプトインジェクション、悪意ある依存関係、偶発的なログ記録、モデルの誤りによる被害を軽減する。第二に、ネットワークアクセスが明示的になる。エージェントが特定のサービスとのみ通信すべきなら、それはエージェントの判断に任せるのではなくインフラポリシーとしてコード化されるべきだ。第三に、チームは関心事の明確な分離を得る。エージェントはタスクに集中し、サンドボックスは隔離を提供し、プロキシはネットワーク認可と認証情報注入を処理し、アプリケーションまたは認証サービスはユーザースコープのアクセスとトークンリフレッシュを管理する。
Auth Proxyはさまざまなポリシー設定をサポートしており、最も強力なのはリクエストの特性に応じてヘッダーを注入する機能だ。ヘッダータイプには以下がある:workspace_secret(LangSmithワークスペース設定に保存されたシークレットを参照)、plaintext(そのまま保存および返却、非機密ヘッダー用)、opaque(書き込み専用、保存時に暗号化、APIで返却しない)。例えば、OpenAIルールでは以下のように注入する:{"name": "Authorization", "type": "workspace_secret", "value": "Bearer {OPENAI_API_KEY}"}。サンドボックスコードはAPIキーを知る必要がなく、.envファイルも、ファイルシステムにマウントされたシークレットも不要だ。単にAPIを呼び出すだけで、プロキシが宛先に一致するルールに従って適切なヘッダーを追加する。
認証情報はネットワーク問題の半分に過ぎない。エージェントには送信ポリシーも必要だ。なぜなら、依存関係をインストールし、スクリプトを取得し、APIを呼び出し、信頼できないコンテンツからの指示に従う可能性があるからだ。すべてのサンドボックスにオープンなインターネットアクセスがあれば、侵害された、または混乱したエージェントが本来アクセスすべきでない場所に到達する可能性がある。同じプロキシ境界は、チームがどの宛先が期待されるかを定義する場所にもなる。モデルプロバイダAPIを許可し、その他すべてをブロックする;エージェントが必要とするGitHub APIパスのみを許可し、任意のGitHub関連ドメインは許可しない;パッケージレジストリを許可するが内部ミラーのみ;既知の悪意ある、または信頼できないパッケージレジストリをブロックする;許可されていないサードパーティサービスへの偶発的な呼び出しを防ぐ。これはパッケージ管理で特に重要だ。コーディングエージェントがpip install、npm install、またはcurl | bashを実行できる場合、コードを取得して実行できる。セキュリティの問題は、サンドボックスが実行を封じ込められるかだけでなく、コードの出所とデータの送信先を制御できるかどうかである。
高度なユースケースでは、静的な設定では不十分な場合がある。LangSmith Fleetのエージェントは、委任アクセスやOAuthトークンリフレッシュを必要とするかもしれないが、実際の認証情報処理はエージェントランタイムの外に保持したい。その他の例として、短命なOAuthアクセストークン、ユーザーごとのスコープ付きトークン、内部認証サービスによって生成される認証情報、宛先や現在のユーザーコンテキストに基づいてリフレッシュが必要なトークンなどがある。これらのケースに対応するため、Auth Proxyはコールバックを用いた動的認証情報をサポートしている。proxy_configの下にコールバックエンドポイントを設定する。サンドボックスが一致するホストにリクエストを行い、プロキシがキャッシュされた認証情報を持っていない場合、プロキシはターゲットのホストとポートを指定してコールバックエンドポイントを呼び出す。エンドポイントは注入するヘッダーを返し、プロキシは設定されたTTLだけ結果をキャッシュする。コールバックはJSONオブジェクトを返す。プロキシはそれらのヘッダーをアウトバウンドリクエストに注入する。コールバックが失敗したり、不正なJSONを返したり、非2xxステータスで応答したりした場合、プロキシはフェイルクローズし、認証情報なしでリクエストを送信する代わりにサンドボックスリクエストを拒否する。これにより、サンドボックスネットワーク層が認証フローに参加できるようになり、リフレッシュトークンや長期認証情報をサンドボックスに公開しなくて済む。
サンドボックスネットワークパスを制御することで、プロキシは認証情報インジェクションを超えて、いくつかの自然な拡張が可能になる。DNSリマッピング:チームは公開パッケージレジストリへのリクエストを内部のArtifactoryやパッケージミラーに解決させたいかもしれない。LLM APIリクエストを内部ゲートウェイに向けることもできる。エージェントは通常のインストールコマンドを実行するが、ネットワーク層はそれらのリクエストを承認されたインフラストラクチャに向ける。ネットワークログ:エージェントが長期間にわたって意味のある作業を行う場合、チームはどのサービスを呼び出したか、どのパッケージを取得したか、どのドメインにアクセスしようとしたかを知りたい。ネットワークログはエージェント行動の監査証跡の一部となる。リクエスト変換:プロキシはアウトバウンドリクエストを確認するため、PIIの編集、組織メタデータの追加、リクエスト形状の強制、ポリシーに違反するペイロードのブロックなど、決定論的な変換を適用する場所になり得る。
より広いポイントは、エージェントインフラストラクチャにはランタイムの外にあり、エージェントの指示や決定にさらされないコントロールプレーンが必要だということだ。Auth Proxyは、認証情報を環境外に保持し、アウトバウンドトラフィックを制御されたレイヤーを通じてルーティングし、言語、SDK、パッケージマネージャー、CLI全体で一貫してポリシーを適用することにより、サンドボックスエージェントに安全なデフォルトを提供する。結果として、エージェントは必要なシステムにアクセスできる一方、認証情報とネットワークポリシーはプラットフォームの制御下に置かれる。