Dockerfileからキットへ:DockerSandbox Kits仕様

投稿日: 9月 24日, 2026年

エージェントには隔離が必要であり、サンドボックスはその半分に過ぎない。どのエージェントがそこで活動し、何を得て、何に触れることができるのか、といったことがまだ明らかになっていない。これはキット、つまり通常のOCIイメージです。そのため、回答はエージェントと共に移動し、準拠するどのランタイムでも同じ意味を持ちます。本日、Docker Sandbox Kit Specification v 3 Apache 2 . 0ライセンスの下でオープンソースとしてdocker/sandbox-kit-specで公開しました。私がこれを書いた理由は以下のとおりです。

エージェントを有用にするものは、すべて権限付与です

私は多くのエージェントを抱えています。彼らがコードを書いたり、テストを実行したり、依存関係をインストールしたり、APIを呼び出したり、インフラストラクチャを構築したりしている間、私は別のことをしている。アクセス権がなければ何も起こらないので、バインドマウント、タスクに必要な範囲よりも広い範囲のトークン、制限するよりも開く方が簡単なファイアウォールルールなど、必要な権限を一つずつ付与していきます。それぞれの助成金は、個別に見れば妥当なものである。彼らは力を合わせて、私が頼りにしていた孤立状態を取り戻してくれた。しかも、誰一人として不正行為を必要としなかった。これらの穴は設定上のもので、意図的に、通常は私が追加したものです。

私はそれらを撤回するのが苦手で、私の設定が依存している助成金を再現することもできませんでした。それらの情報はファイルに記録されていません。それらは、シェル履歴、ダッシュボード、そして私の記憶の中に生きている。それを同僚に渡したり、先週のデータと比較したりすることはできません。

コンテナパッケージアプリケーション。サンドボックスにはエージェントが含まれています。

コンテナはアプリケーションをパッケージ化する。ホストカーネルを共有し、名前空間とcgroupを使用して、固定されたワークロードごとにファイルシステム、ネットワーク、およびプロセスに対する独自のビューを提供します。それは、実行され、その役割を果たし、渡されたもの以外には触れないソフトウェアにとって最適なツールです。

しかし、エージェントは確率的な行為者である。次に何をすべきかを決定し、私のファイルシステム、ネットワーク、認証情報、クラウドアカウントに対してそれを実行します。これはroot権限が必要なパッケージをインストールし、誰も想定していなかったポートを開き、最初の操作がブロックされた場合は次の操作を試みます。コンテナはそのために作られたものではありません。境界は、アクターが調査しているカーネルと同じです。

Dockerサンドボックスは独自のカーネルを持つmicroVMであるため、その境界はモデルがアクセスしたり書き換えたりできる範囲よりも下に位置します。サンドボックス内では、エージェントルートを渡して自由に動かすことができます。なぜなら、被害はサンドボックスの境界で止まるからです。サンドボックスのおかげで、安全対策を無効にした状態でエージェントを実行できるのです。

しかし、何もないSandboxは環境とは言えない。どのエージェントが実行されるのか、どのツールやMCPサーバーが利用されるのか、どのスキルや指示によって形成されるのか、そして具体的に何に触れることができるのかを、何らかの方法で規定する必要がある。

Dockerfileでは伝えられないこと

Dockerfileは、ソフトウェア自体に関するあらゆる情報、つまり、どのように構築されるか、何がパッケージ化されるか、どのように起動するかといったことすべてに答えるものです。それは決して標準化されていなかった。OCIは、生成するイメージと、レジストリがそれを配布する方法を標準化した。Dockerfileでは、ネットワーク、認証情報、ボリューム、ツール、コンテキストといった外部要素は記述されません。その半分は、 docker runフラグ、Composeファイル、CI設定、そして誰かの記憶の中に存在していた。バージョン管理なし、レビュー不可。キットには内容が書き留められています。

1つのイメージ、1つのダイジェスト

sbxを使用したことがあるなら、Kits を使用したことがあるはずです。これはフォーマットの3番目のバージョンであり、重要な変更点は、キットが独自のアーティファクトではなく、通常のOCIイメージになったことです。つまり、メディアタイプもサイドカーファイルもなく、レジストリが学習するものは何もありません。マニフェストには、 vnd.docker.sandbox.kit.descriptorという 1 つの注釈で宣言が記述され、レイヤーにはコンテンツが記述されます。

したがって、キットはdocker buildx buildでビルドされ、 docker pullでプルされ、既に実行しているツールによってスキャンおよび署名され、 FROMで動作します。ダイジェストを固定することで、コンテンツ、宣言、メタデータをまとめて固定できます。ツールと配布パスは無料です。フォーマットは学習するものです。文法、機能タイプごとのページ、 providesとrequires 、 kind: set 。

キットには2種類存在する。ワークロードが実行され、ルートファイルシステムにデータを提供する。ミックスインとはオーバーレイのことです。CLIにネットワークルール、認証情報バインディング、エージェントのコンテキストなどを加えたものです。1つのワークロードと任意の数のミックスインを起動します。

読み取れる権限

リポジトリ内のGitHub CLIミックスインの一部:

capabilities:
  - type: com.docker.sandbox/network-policy@2
    config:
      runtime:
        allow:
          - github.com
          - hosts: [api.github.com]
            methods: [GET, HEAD, POST, PATCH, PUT, DELETE]
        deny:
          - hosts: [api.github.com]
            methods: [DELETE]
            paths: [/repos/**]

  - type: com.docker.sandbox/credential@1
    optional: true
    config:
      service: github
      phase: runtime
      apiKey:
        name: GH_TOKEN
        proxyManaged: true
        inject:
          - {domain: api.github.com, header: Authorization, format: "Bearer %s"}

許可証として読んでください。このキットはGitHubへのアクセスのみを要求し、他の場所にはアクセスを要求しません。また、ほとんどのAPIに対してはアクセスを要求しますが、 /repos/**以下の削除は要求しません。なぜなら、拒否が優先されるからです。プルリクエストを作成できるトークンでは、リポジトリを削除することはできません。認証情報はプロキシによって管理されます。準拠したランタイムが指定されたドメインへのリクエストに実際の値を挿入し、サンドボックス内には監視役のみが存在します。

「尋ねる」と「従う」という2つの言葉には重みがある。キットはそれ自体に何も与えない。各投稿はリクエストであり、主催者が決定します。仕様書に記載されている動作を実装する準拠ランタイムは、リストに載っていないホストをブロックします。それがなければ、注釈は機能しない。画像があるだけで、何の効力も持たない。Docker Sandboxesは、初めて規格に準拠したランタイムです。

キットに必要なものはすべて、そのリストに記載され、入力され、バージョン管理されます。権限(ネットワークルール、認証情報、ボリューム、ポート、デバイス、スキルパス)は「このキットが実行できること」にカウントされますが、ライフサイクルフックのようにランタイムに動作を要求するエントリはカウントされません。ホストが満たせない必須リクエストがあった場合、宣言した権限よりも低い権限、あるいは高い権限でエージェントを起動するのではなく、起動を拒否します。

構成はシーケンスではなく、関数です

コンテナイメージは多重継承を解決していません。Dockerfile ステージには 1 つのFROMがあります。ミックスインは、キットがprovidesとrequiresを通じて宣言する依存関係グラフによって順序付けられたオーバーレイであり、フラグを入力した順序によって順序付けられることはありません。そのため、同じセットは常に同じイメージを構成します。

このリゾルバは意図的に厳格な動作をします。すべてのrequiresセット内で満たされるか、解決に失敗します。不足を補うために何も取得されません。許可されるワークロードは1つだけです。同じ名前のキットが2つ存在すると、片方がもう一方を暗黙のうちにシャドウするのではなく、失敗します(ClaudeワークロードをClaudeミックスインと組み合わせるのは典型的な間違いです)。キットが重複する箇所では、宣言が調整されます。ネットワークルールは統合され、フックは依存関係の順序で実行され、ガイダンスは1つのドキュメントになり、ライセンスは統合されます。互換性のないリクエストはエラーであり、コイン投げのようなものではありません。

kind: set 。それを公開すると、ビルド時に同じ整合性ルールが実行され、それらが1つの通常のキットにマージされます。一貫性のない設定は、他人の起動時ではなく、あなたのビルド時に失敗する。

差分そのものがレビューになる

リポジトリ内の Claude Code Kit は、接続を要求するホスト、認証情報、セッション間で保持されるボリューム、およびインストールと起動時のフックを宣言します。次のバージョンで別のホストや2つ目の認証情報が要求された場合、それはソフトウェアのアップデートではなく、権限の変更であり、プルリクエストには人間が拒否できる行が追加される形で表示されます。

レビューは誰かが差分を読むことに依存するため、仕様ではそれをしない2番目のゲートが定義されています。各記述子は、ホストが許可しなければならないすべてのものの正規化されたセットに還元されます。ランタイムは、設定されたレコードの更新を制御し、次のバージョンをそれと比較します。許可された範囲内のバージョンは、許可を求めることなく適用される場合があります。拡大するたびに停止して確認し、拒否ルールを削除するとカウントされます。後のgh Kit がDELETE /repos/**を削除した場合、ランタイムはアップグレードを保持します。だからこそ、宣言は人工物の傍らに置くのではなく、人工物の中に組み込まれなければならなかったのだ。

これが機能ではなく仕様である理由

他の場所で実行されたときに意味をなさなくなるキットは、信頼の境界ではなく、ベンダーロックインとなるだろう。つまり、文法は規範的であり、すべての機能タイプには、準拠するランタイムが実装しなければならない内容を説明する独自のページがあり、タイプはバージョンごとに独立しています( network-policy@ 1と@ 2どちらも現在存在します)。2つの適合性評価スイートが同梱されています。1つは成果物が適合キットであるかどうかを判定し、もう1つはランタイムがページに記載されているとおりに動作するかどうかを判定します。すべての規範的記述は、小切手または書面による権利放棄によって裏付けられています。

現在もDockerが仕様を維持管理しており、単一のベンダーが管理するべきではない。エージェントが何を実行できるかを決定するためのフォーマットは、ランタイムを販売するベンダーが所有するものであれば、その価値は低下する。Dockerサンドボックスは、唯一の実装ではなく、優れた実装の一つとなるでしょう。必要なキットが表現できない場合、または実行時義務が規定どおりに実装できない場合は、問題を報告してください。

お試しください

sbx はサンドボックス CLI です ( brew install docker/tap/sbx )。リポジトリのチェックアウトから:

cd examples
sbx run ./hello --kit ./gh .

記述子を編集すると、Kit はその記述子のみを再構築します。docker docker buildx buildそれを任意のレジストリに公開します。Docker Cloud Sandboxesは、同じ信頼モデルを使用して、弾力的な容量上で同じキットを実行します。仕様書、機能ページ、および操作手順は、docker/sandbox-kit-spec にあります。

エージェントだけでなく

エージェントが要求する権限が非常に大きいため、この問題は公になったが、通常のワークロードには常に暗黙の了解事項があった。例えば、呼び出すエンドポイント、必要な認証情報、再起動後も保持しなければならないデータ量などだ。その知識は、ヘルムチャート、ランブック、あるいは同僚の中に存在していた。ウェブサービスが間違えた場合でも、同じギャップではあるものの、それほど深刻な問題にはならない。この仕様書は、ソフトウェアが周囲の世界から必要とするものを記述するものであり、エージェントの場合は、構築するほど緊急性が高い場合に用いられた。

Dockerfileによって、ソフトウェアは再現可能になりました。Kitsによって、実行権限も再現可能になります。

著者について

シニアプリンシパルソフトウェアエンジニア、Docker氏

関連記事