MarkTechPost出典公開日

Anthropicのsandbox-runtimeをご紹介:AIエージェントのためのOSレベルサンドボックス、コンテナ不要

この記事では、新たに注目を集めているオープンソースのAnthropic製 sandbox-runtime(srt)について解説します。これはClaude Codeのサンドボックス化されたbashツールを支えるOSレベルのサンドボックスです。

この記事では、新たに注目を集めているオープンソースのAnthropic製 sandbox-runtime(srt)について解説します。これはClaude Codeのサンドボックス化されたbashツールを支えるOSレベルのサンドボックスです。Anthropicのsandbox-runtimeは、プロセスが触れるファイルと到達できるホストを制限します。コンテナを起動することなくこれを実現します。また、Claude Codeに限定されません。あなた自身のエージェント、ローカルのMCPサーバー、通常のコマンドラインプログラムもその中で実行できます。

要点(TL;DR)

  • サイズ: npmパッケージ @anthropic-ai/sandbox-runtime v0.0.81、解凍後約11.4 MB、Apache-2.0、Node.js 22.12+。
  • 動作環境: 任意のmacOSまたはLinuxの開発マシン、あるいはCIマシン。macOSはSeatbeltを使用。Linuxにはbubblewrap、socat、ripgrepが必要。Windowsはアルファ版。
  • パフォーマンス: Anthropicの内部利用(自己申告)において、サンドボックス化によりClaude Codeの権限プロンプトが84%削減されました。
  • 良い点: プロセスツリー全体にファイルとネットワークの制限を強制しつつ、権限プロンプトが84%減少。
  • 悪い点: 依然としてベータのリサーチプレビューであり、Windowsサポートはアルファ版。

Anthropic sandbox-runtimeとは?

Anthropic sandbox-runtimeは、任意のプロセスをファイルシステムとネットワークの制限でラップするオープンソースツールです。 npm install -g @anthropic-ai/sandbox-runtimeでインストールし、コマンドの前に srtを付けます。CLIとしてもTypeScriptライブラリとしても動作します。

sandbox-runtimeはmacOS、Linux、Windowsでどのように動作するのか?

srtは各オペレーティングシステム固有の隔離プリミティブを使用します。その制限は、スクリプトやサブプロセスを含むプロセスツリー全体をカバーします。

  • macOS: sandbox-exec 動的に生成されたSeatbeltプロファイルを使用。ripgrepのみが必要です。
  • Linux: bubblewrap を使用し、ネットワーク名前空間を削除します。socatとripgrepも必要です。
  • Windows(アルファ版): 専用の srt-sandbox アカウント、Windows Filtering Platformによる送信フェンス、明示的なファイルACLを使用します。

トラフィックは、ホスト上で動作する HTTP および SOCKS5 プロキシを通じてのみ外部に送られます。Linux では、これらのプロキシはサンドボックスにバインドマウントされた Unix ソケットの背後に置かれます。macOS では、Seatbelt プロファイルが許可するのは 1 つの localhost ポートのみです。その後、プロキシがドメインの許可リストおよび拒否リストを適用します。

なぜファイルシステムとネットワークの両方の分離が必要なのですか?

Anthropicチームは、2つの境界のうち1つだけでは不十分だと主張しています。ネットワーク隔離がなければ、プロンプトインジェクションを受けたエージェントがSSH鍵を持ち出す可能性があります。ファイルシステム隔離がなければ、サンドボックスから脱出してネットワークアクセスを得る可能性があります。

srtのデフォルトはその論理に従っています。読み取りは、拒否されていない限りどこでも許可されます。書き込みは、許可されていない限りどこでも拒否されます。ネットワークアクセスは、ドメインが許可リストに登録されていない限り拒否されます。

MCPサーバーや自身のエージェントをサンドボックス化するにはどうすればよいのでしょうか?

MCPサーバーの場合は、 command で .mcp.json から npx に srt. 元のコマンドを引数として渡します。するとルールは ~/.srt-settings.json:

コードをコピー
{
  "network": { "allowedDomains": ["api.github.com", "*.npmjs.org"], "deniedDomains": [] },
  "filesystem": { "denyRead": ["~/.ssh"], "allowWrite": ["."], "denyWrite": [".env"] }
}

自身のエージェントのために、このライブラリは以下を公開しています。 SandboxManager。電話 initialize(config) プロキシを起動します。その後 wrapWithSandbox() ラップされたコマンド文字列を返します。これをspawnできます。

84%という数字は何を意味するのでしょうか?

Anthropic 報道 そのサンドボックス化により、社内でのClaude Code利用において権限プロンプトが84%削減されたという。これは自己申告の数値であり、外部ベンチマークではない。狙いは承認疲れだ。1日中「承認」をクリックし続ける開発者は、何を承認しているのかを読まなくなる。固定された境界により、エージェントはその内側で自由に作業し、境界に達したときだけ確認を求めることができる。

戻る</button> <button class="btn pri" id="fnext">次のステップ </button> <button class="btn" id="fplay">自動再生</button> </div> </div> <div class="pane" id="p-sim"> <div class="sim"> <div> <div class="card"> <h5>network.allowedDomains</h5> <label class="chk"><input type="checkbox" id="d-anth" checked> anthropic.com</label> <label class="chk"><input type="checkbox" id="d-npm"> *.npmjs.org</label> <label class="chk"><input type="checkbox" id="d-gh"> github.com</label> <h5 style="margin-top:12px">filesystem</h5> <label class="chk"><input type="checkbox" id="f-ssh" checked> denyRead: ~/.ssh</label> <label class="chk"><input type="checkbox" id="f-env" checked> denyWrite: .env</label> </div> </div> <div> <div class="cmds" id="cmds"> <button class="cmd" data-c="0">srt "cat README.md"</button> <button class="cmd" data-c="1">srt "cat ~/.ssh/id_rsa"</button> <button class="cmd" data-c="2">srt "curl anthropic.com"</button> <button class="cmd" data-c="3">srt "curl example.com"</button> <button class="cmd" data-c="4">srt "npm install"</button> <button class="cmd" data-c="5">srt "echo KEY=1 &gt;&gt; .env"</button> </div> <div class="term" id="term" style="margin-top:10px"><span class="dim">コマンドを選択してください。設定を切り替えて変化を確認できます。</span></div> <div class="why" id="why"></div> </div> </div> </div> <div class="pane" id="p-plat"> <div class="plat"> <div class="pc on" data-p="0"><h4>macOS</h4><span class="tag t-g">サポート対象</span><ul><li>sandbox-exec</li><li>Seatbeltプロファイル</li><li>ripgrepが必要</li></ul></div> <div class="pc" data-p="1"><h4>Linux</h4><span class="tag t-g">サポート対象</span><ul><li>bubblewrap</li><li>ネットワーク名前空間なし</li><li>socat + ripgrep</li></ul></div> <div class="pc" data-p="2"><h4>Windows</h4><span class="tag t-o">アルファ</span><ul><li>srt-sandboxアカウント</li><li>WFPエグレスフェンス</li><li>一回限りのインストール</li></ul></div> </div> <div class="desc pdetail" id="pdesc"></div> </div> <div class="pane" id="p-defs"> <div class="defs"> <div class="dc"><div class="kicker">読み取り</div><div class="big" style="color:#b5cc94">許可</div><p>デフォルトでどこでも許可されています。~/.sshのような拒否領域を設定し、allowReadで再許可できます。</p></div> <div class="dc"><div class="kicker">書き込み</div><div class="big" style="color:#ef7a73">拒否</div><p>デフォルトでどこでも拒否されています。"."や/tmpなどのパスをallowWriteで開放します。</p></div> <div class="dc"><div class="kicker">ネットワーク</div><div class="big" style="color:#ef7a73">拒否</div><p>デフォルトではアクセス不可。すべてのホストがallowedDomainsに一致する必要があります。</p></div> </div> <div class="bars" id="bars"> <div class="kicker" style="margin-bottom:4px">Claude Codeの権限プロンプト(100を基準に指数化)</div> <div class="bar"><div class="lb"><span>サンドボックスなし</span><span>100</span></div><div class="bg"><div class="fg" data-w="100" style="background:var(--muted)"></div></div></div> <div class="bar"><div class="lb"><span>サンドボックスあり</span><span>16</span></div><div class="bg"><div class="fg" data-w="16" style="background:var(--orange)"></div></div></div> <div class="note">Anthropicの社内利用ではプロンプトが84%減少(2025年10月のエンジニアリング記事による自己申告)。100を基準に指数化。</div> </div> </div> <div class="pane" id="p-cmp"> <div class="tblwrap"> <table> <thead><tr><th></th><th>srt</th><th>Codex CLI</th><th>Docker Sandboxes</th><th>E2B</th></tr></thead> <tbody> <tr class="row"><td>分離方式</td><td class="hl">OSプリミティブ</td><td>OSプリミティブ</td><td>microVM</td><td>Firecracker microVM</td></tr> <tr class="row"><td>実行環境</td><td class="hl">ローカル</td><td>ローカル</td><td>ローカル</td><td>クラウド / BYOC</td></tr> <tr class="row"><td>コンテナまたはVM</td><td class="hl">いいえ</td><td>いいえ</td><td>はい</td><td>はい</td></tr> <tr class="row"><td>ネットワークのデフォルト</td><td class="hl">すべて拒否</td><td>オフ(切り替え可)</td><td>選択したポリシー</td><td>オン</td></tr> <tr class="row"><td>ドメイン許可リスト</td><td class="hl">ワイルドカード + ポート</td><td>非公開</td><td>ワイルドカード + ポート</td><td>allowOut、ワイルドカード</td></tr> <tr class="row"><td>ライセンス</td><td class="hl">Apache-2.0</td><td>Apache-2.0</td><td>非公開</td><td>Apache-2.0(SDK)</td></tr> </tbody> </table> </div> </div> <div class="ft"><span>Sources: github.com/anthropics/sandbox-runtime · anthropic.com/engineering · v0.0.81</span><span class="mtp">Built by Marktechpost</span></div> </div> <script> (function(){ var R=document.getElementById('srt-x'); function post(){try{parent.postMessage({srtH:R.offsetHeight+40},'*')}catch(e){}} var tabs=R.querySelectorAll('.tab'); tabs.forEach(function(b){b.addEventListener('click',function(){ tabs.forEach(function(x){x.classList.remove('on')});b.classList.add('on'); R.querySelectorAll('.pane').forEach(function(p){p.classList.remove('on')}); var t=b.getAttribute('data-t');document.getElementById('p-'+t).classList.add('on'); if(t==='defs')bars();if(t==='cmp')rows();setTimeout(post,60); })}); // flow var steps=[ ['エージェントがコマンドを実行する','エージェント、MCPサーバーまたはCLIツールがコマンドを発行します。コマンドは変更されず、srtは単にそれをラップするだけです。',0,'act'], ['srtがポリシーを構築する','srtは~/.srt-settings.json(または組み込みのデフォルト)を読み込み、ホスト上でHTTPおよびSOCKS5プロキシを起動します。',1,'act'], ['OSが境界を強制する','Seatbelt(macOS)、bubblewrap(Linux)またはWFPフェンス(Windowsアルファ)が、プロセスツリー全体にファイルルールを適用します。',2,'act'], ['すべてのトラフィックがプロキシを経由する','サンドボックスには外への直接経路がありません。Linuxではネットワーク名前空間が削除され、プロキシにはUnixソケット経由でアクセスします。',3,'act'], ['許可されたホスト:接続が続行される','allowedDomains内のホストは、ループバックやクラウドメタデータのIPに解決されないことのチェックを経て、通過します。',4,'ok'], ['未知のホスト:ブロックまたは確認','拒否された、またはリストにないホストは拒否されるか、askコールバックが判断します。違反はエージェントが読めるようにログに記録されます。',4,'bad'] ]; var fi=0,timer=null; function draw(){ var s=steps[fi];var ns=R.querySelectorAll('.node'); ns.forEach(function(n,i){n.classList.remove('act','ok','bad');if(i<s[2])n.classList.add('act')}); ns[s[2]].classList.add(s[3]); var pk=document.getElementById('pkt');pk.style.left=(s[2]*22)+'%'; pk. style.background=s[3]==='ok'?'#788c5d':s[3]==='bad'?'#d4504a':'#d97757'; document.getElementById('fdesc').innerHTML='<h4>ステップ '+(fi+1)+' / '+steps.length+':'+s[0]+'</h4>'+s[1]; } document.getElementById('fnext').onclick=function(){fi=(fi+1)%steps.length;draw()}; document.getElementById('fprev').onclick=function(){fi=(fi-1+steps.length)%steps.length;draw()}; document.getElementById('fplay').onclick=function(){ if(timer){clearInterval(timer);timer=null;this.textContent='自動再生';return} this.textContent='一時停止';timer=setInterval(function(){fi=(fi+1)%steps.length;draw()},1800); }; draw(); // sim function on(id){return document.getElementById(id).checked} var C=[ function(){return [1,'# Anthropic Sandbox Runtime (srt) ...','読み取りはデフォルトで許可されており、現在のディレクトリは読み取り可能です。']}, function(){return on('f-ssh')?[0,'cat: ~/.ssh/id_rsa: Operation not permitted','~/.sshはdenyReadに入っているため、鍵を読むことはできません。']:[1,'-----BEGIN OPENSSH PRIVATE KEY----- ...','denyReadルールがなければ、読み取りはどこでもオープンです。機密情報は明示的に拒否してください。']}, function(){return on('d-anth')?[1,'<html>...</html>','anthropic.comはallowedDomainsに入っているため、プロキシが転送します。']:[0,'Connection blocked by network allowlist','許可リストに一致なし:ネットワークはデフォルトで拒否されます。']}, function(){return [0,'Connection blocked by network allowlist','example.comは許可リストに入っていません。']}, function(){return on('d-npm')?[1,'パッケージがインストールされました(出力例)','*.npmjs.orgは許可リストに入っているため、レジストリに到達できます。']:[0,'npm ERR! network request to registry.npmjs.org failed\nConnection blocked by network allowlist','古典的なトレードオフ:厳しすぎるとインストールが失敗します。']}, function(){return on('f-env')?[0,'bash: .env: Operation not permitted','denyWriteはallowWriteに優先するため、.envはプロジェクト内で保護されたままです。']:[1,'(書き込みました)','"."はallowWriteに入っているため、書き込みは成功します。']} ]; var busy=false; R.querySelectorAll('.cmd').forEach(function(b){b. addEventListener('click',function(){ if(busy)return;busy=true;var r=C[+b.getAttribute('data-c')]();var t=document.getElementById('term'); t.innerHTML='<span class="p">$</span> '+b.textContent.replace(/</g,'&lt;')+'\n<span class="dim">サンドボックス内で実行中...</span>'; document.getElementById('why').textContent=''; setTimeout(function(){ t.innerHTML='<span class="p">$</span> '+b.textContent.replace(/</g,'&lt;')+'\n<span class="'+(r[0]?'ok':'no')+'">'+(r[0]?'✓ ':'✗ ')+r[1].replace(/</g,'&lt;')+'</span>'; document.getElementById('why').textContent=r[2];busy=false;post(); },650); })}); // platforms var P=['macOSは、実行ごとに生成されたSeatbeltプロファイルを使う組み込みのsandbox-execツールを使用します。プロファイルは、srtプロキシが待ち受ける1つのlocalhostポートのみを許可します。違反はシステムログからリアルタイムで読み取れます。', 'Linuxはbubblewrapを使用し、ネットワーク名前空間を完全に削除します。プロキシには、サンドボックスにバインドマウントされたUnixソケットを通じてアクセスします。Ubuntu 24.04+では、ユーザー名前空間のためにAppArmorの変更が必要です。', 'Windows(アルファ)は、専用のsrt-sandboxアカウントでコマンドを実行します。マシン全体に適用されるWFPフィルタが、プロキシポート以外への外向きトラフィックをブロックします。セットアップには1回の昇格されたインストールが必要です。']; var pcs=R.querySelectorAll('.pc'); function pd(i){pcs.forEach(function(x){x.classList.remove('on')});pcs[i].classList.add('on');document.getElementById('pdesc').innerHTML='<h4>'+pcs[i].querySelector('h4').textContent+'</h4>'+P[i];post()} pcs.forEach(function(c,i){c.addEventListener('click',function(){pd(i)})});pd(0); function bars(){R.querySelectorAll('.fg').forEach(function(f){f.style.width='0';setTimeout(function(){f.style.width=f.getAttribute('data-w')+'%'},80)})} function rows(){R.querySelectorAll('tr.row').forEach(function(r,i){r.classList.remove('in');setTimeout(function(){r.classList.add('in')},90*i+60)})} window.addEventListener('load',post);window. addEventListener('resize',post);setTimeout(post,300); })(); </script> </body> </html> ">

本当のトレードオフ:厳格な許可リストと動作するエージェント

コーディングエージェントの仕事はファイルの編集だけではありません。依存関係のインストール、ドキュメントの取得、APIの呼び出しも行います。許可リストを厳しすぎると、 npm install 緩すぎるとサンドボックスの保護がほとんど機能しなくなります。srt には、その中間を目指すためのいくつかの調整ノブが用意されています:

  • ワイルドカードとポート: 「entries like」のような項目 *.npmjs.org または api.example.com:443.
  • コールバックの依頼: 「decides hosts no rule covers」を判定し、モデルが読める理由を返すことができます。
  • コマンドごとの許可リスト: 呼び出し1回のみのレジストリを開く。
  • 速報: --control-fd コマンドの実行中にネットワークリストをスワップします。
  • 解決済みアドレスのチェック: loopback やクラウドメタデータの IP に解決される名前をブロックします。
  • 拒否ドメインの理由: エージェントに、HTTPSのgitリモートなど、サンクション対象の代替手段を伝えます。

他のエージェントサンドボックスとどう比較されますか?

特集Anthropic sandbox-runtimeOpenAI Codex CLIサンドボックスDockerサンドボックスE2B
隔離OSプリミティブ:Seatbelt、bubblewrap、Windowsアカウント + WFPOSプリミティブ:Seatbelt、bubblewrap、ネイティブWindowsサンドボックスサンドボックスごとに 1 つの microVMセッションごとのFirecracker microVM
動作環境ローカルマシンローカルマシンローカルマシンクラウドまたは BYOC(AWS、GCP)
コンテナまたは VM が必要いいえいいえはい(microVM)はい(マネージド microVM)
独自エージェント以外での使用はい、あらゆるプロセスに対応する CLI + ライブラリCodex に組み込みはい、コーディングエージェント向けの sbx CLIはい、JS および Python SDK
ネットワークのデフォルトすべて拒否、プロキシの許可リストでオフ workspace-write、設定で切り替え可能初回起動時にポリシーを選択(例: deny-all、balanced)デフォルトでオン、無効化も可能
ドメイン許可リストはい、ワイルドカード + ポートに対応非公開(オン/オフの切り替えはドキュメント化済み)はい、ワイルドカード + ポートに対応はい、 allowOut でワイルドカード対応(SNI/Host ベース)
ライセンスApache-2.0Apache-2.0非公開Apache-2.0(SDK)
ステータスベータの研究プレビュー、Windows はアルファ版Codex CLI に同梱出荷済み製品出荷済み製品

要点まとめ

  • srt は OS レベルであらゆるプロセスをサンドボックス化し、コンテナは不要です。
  • macOS では Seatbelt、Linux では bubblewrap、Windows はアルファ版です。
  • ネットワークはデフォルトで拒否。すべての接続がホスト側の許可リストプロキシを通過します。
  • Anthropic は Claude Code の許可プロンプトが 84% 減少したと報告しています(社内データ)。
  • 許可リストの幅こそが本当のセキュリティ調整手段であり、広いドメイン指定はデータ漏洩につながり得ます。


「Check out the」の翻訳が必要です。文脈のない短い断片なので、直訳的な「〜をチェックしてください」ではなく、次の文に続く形として自然な日本語にします。 記事の一部として隣接する断片とつながるため、名詞で終わる形が適切です。例えば「以下をご覧ください」や「〜をご覧ください」といった形ですが、文が続くことを前提とすると体言止めが自然です。 ここでは「以下をご覧ください。」ではなく、記事の導入部分としてよく使われる表現を採用します。 GitHubリポジトリ, その Anthropic エンジニアリング投稿 および Claude Codeのサンドボックス化ドキュメント。本プロジェクトの研究者に全ての功績があります。また、ぜひ私たちをフォローしてください Twitter そして、私たちの 150k+ ML SubReddit および Subscribe to への登録 弊社ニュースレター。待って!Telegramは使っていますか? Telegramでもご参加いただけるようになりました。

あなたのGitHubリポジトリ、Hugging Faceページ、製品リリース、ウェビナーなどのプロモーションについて、私たちとのパートナーシップをご希望ですか? 私たちとつながりましょう

この投稿 Anthropicのsandbox-runtimeをご紹介:コンテナ不要のAIエージェント向けOSレベルサンドボックス 最初に掲載されたのは MarkTechPost.

原文の出典

MarkTechPost

内容について

原文の公開と権利は出典元に帰属します。

機械翻訳 · 原文をご参照ください