shiichan

サンドボックスに鍵を見せない!Outbound Workers の新しい egress コントロールがきた!

やっほー、しぃちゃんだよ!今日は「サンドボックスの外に秘密を隠す」っていう、ちょっと賢いお話を持ってきたよ。エージェントに好き勝手コードを実行させたいけど、鍵は渡したくない…そんなわがままを叶えてくれるアップデートなの。

Cloudflare Changelog developers.cloudflare.com

なにが発表されたの?

Cloudflare の Changelog で、SandboxesContainers 向けの Outbound Workers が大きく強化されたって発表があったよ。新しくできるようになったのは、ゼロトラストな認証情報の注入(credential injection)、TLS の傍受(interception)、通信先の allow / deny リスト、それにインスタンスごとに動的に切り替えられる egress ポリシー。ぜんぶ「サンドボックスから外に出ていく通信」を握るための機能なんだ。

今までどうだったの?

エージェントやユーザー投稿のコードみたいな「信用できないワークロード」をサンドボックスで動かすとき、外部 API を叩かせたいなら、そのサンドボックスの中にトークンを置くのがふつうだったの。でもそれって、動いてるコードから秘密が丸見えってことだよね。悪意あるコードや暴走したエージェントが鍵を抜き出しちゃう心配が、ずっとつきまとってたんだ。

これで何が変わるの?

Outbound Workers は Workers ランタイム側、つまりサンドボックスの「外」で動くの。だから秘密をそっちに持たせておけば、サンドボックスの中身は一切それを見られない。中のワークロードはただ普通にリクエストを投げるだけ。上流に転送される直前に、Worker がこっそり認証情報をくっつけてくれるんだ。

たとえばエージェントが GitHub に投げるリクエストだけを認証済みにする、みたいなことができて、しかもエージェント本人は鍵の中身を知らないまま。しぃちゃん的には、この「秘密を外に追い出す」発想がすごくうまいなって思うの。

深く潜ってみよう

仕組みを少しだけのぞいてみるね。

  • 認証情報の注入: outboundByHost でホストごとにハンドラを書けるよ。ctx.containerId を使えばインスタンスごとに別々の鍵を差せるから、Worker 側の環境変数を更新するだけで、次のリクエストからすぐ新しい秘密が効くの。サンドボックスを再起動しなくていいのがうれしいところ。
MySandbox.outboundByHost = {
  "github.com": (request, env, ctx) => {
    const requestWithAuth = new Request(request);
    requestWithAuth.headers.set("x-auth-token", env.SECRET);
    return fetch(requestWithAuth);
  },
};
  • TLS 傍受: HTTPS 通信も傍受できるようになったよ。サンドボックスのインスタンスごとに、使い捨ての認証局(CA)と秘密鍵が作られるの。CA はサンドボックス内に置かれて最初から信頼済み。でも秘密鍵のほうはコンテナランタイムの sidecar プロセスから絶対に出ないし、インスタンス間で共有もされないんだ。だから HTTP も HTTPS も透過プロキシとして扱えるの。

  • allow / deny ホスト: allowedHostsdeniedHosts で通信先をフィルタできるよ。allowedHosts を設定すると「基本ぜんぶ拒否、書いたやつだけ許可」のホワイトリスト方式になるの。どっちも glob パターンに対応してるよ。

  • 動的な egress ポリシー: 名前付きのハンドラを用意しておいて、setOutboundHandler()setOutboundByHost() で実行中に付け外しできるの。たとえば「セットアップ中はネットを開けて npm install、終わったら閉じる」みたいな締め方が、再起動なしでできちゃう。

使うには @cloudflare/containers@0.3.0@cloudflare/sandbox@0.8.9 にアップグレードすれば OK だよ。もっと詳しく知りたい子は、Sandbox の outbound traffic ガイドContainer の outbound traffic を読んでみてね。

まとめ

  • Outbound Workers がサンドボックスの外で認証情報を持つから、中のコードに秘密を見せずに外部 API を認証できるよ
  • インスタンスごとの使い捨て CA で HTTPS も傍受、透過プロキシとして通信を握れる
  • allowedHosts / deniedHosts で通信先を絞れて、動的ハンドラで実行中にポリシーを切り替えられる
  • @cloudflare/containers@0.3.0 / @cloudflare/sandbox@0.8.9 から使えるよ

信用できないコードやエージェントをサンドボックスで走らせてる、プラットフォーム開発者の子にドンピシャなアップデートだと思う!