Представляємо sandbox-runtime від Anthropic: пісочниця на рівні ОС для ШІ-агентів без контейнерів
У цій статті ми розглянемо новий популярний інструмент з відкритим кодом від Anthropic — sandbox-runtime (srt), системний пісочний контейнер, що лежить в основі ізольованого bash-інструмента Claude Code. Anthropic sandbox-runtime обмежує файли, до яких може звертатися процес, і хости, до яких він може підключатися. Він робить це без запуску контейнера. Також він не прив’язаний до Claude Code. Ваші власні агенти, локальні MCP-сервери та звичайні програми командного рядка можуть працювати всередині нього.
Коротко
- Розмір: пакет npm
@anthropic-ai/sandbox-runtimev0.0.81, близько 11,4 МБ у розпакованому вигляді, Apache-2.0, Node.js 22.12+. - Працює на: будь-якій macOS- або Linux-машині розробника чи CI-сервері. У macOS використовується Seatbelt; для Linux потрібні bubblewrap, socat і ripgrep. Windows — альфа-версія.
- Продуктивність: ізоляція скоротила кількість запитів дозволу Claude Code на 84% у внутрішньому використанні Anthropic (за власними даними компанії).
- Найкраще: на 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 дозволяє лише один локальний порт. Потім проксі застосовують ваші списки дозволених і заборонених доменів.
Навіщо потрібна ізоляція і файлової системи, і мережі?
Команда Anthropic стверджує, що одна межа без іншої не працює. Без мережевої ізоляції агент, якому нав’язали шкідливу інструкцію, міг би викрасти ключі 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() поверне обгорнутий рядок команди, який можна запустити.
Що означає показник 84%?
Anthropic повідомляє, що ізоляція скоротила кількість запитів дозволу на 84% у внутрішньому використанні Claude Code. Це показник, наведений самою компанією, а не результат зовнішнього тестування. Мета — подолати втому від підтверджень. Розробники, які цілий день натискають «дозволити», перестають читати, що саме вони дозволяють. Фіксована межа дає агенту змогу вільно працювати всередині неї та запитувати дозвіл лише на її межі.
</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">файлова система</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 >> .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>За замовчуванням доступ відсутній. Кожен хост має відповідати allowDomains.</p></div>
</div>
<div class="bars" id="bars">
<div class="kicker" style="margin-bottom:4px">Запити дозволу Claude Code (індексовані)</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">На 84% менше запитів у внутрішньому використанні Anthropic (за власними даними, інженерна публікація від жовтня 2025 року). Індексовано до 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">Примітиви ОС</td><td>Примітиви ОС</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>Контейнер або ВМ</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>Джерела: github.com/anthropics/sandbox-runtime · anthropic.com/engineering · v0.0.81</span><span class="mtp">Створено 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'],
['ОС застосовує межу','Seatbelt (macOS), bubblewrap (Linux) або фільтр WFP (альфа-версія Windows) застосовує правила доступу до файлів до всього дерева процесів.',2,'act'],
['Увесь трафік проходить через проксі','Пісочниця не має прямого маршруту назовні. У Linux мережевий простір імен видалено; доступ до проксі здійснюється через Unix-сокети.',3,'act'],
['Дозволений хост: з’єднання продовжується','Хост у allowedDomains проходить перевірку, після чого перевіряється, що він не перетворюється на адресу loopback або IP-адресу хмарних метаданих.',4,'ok'],
['Невідомий хост: заблоковано або надіслано запит','Заборонений або відсутній у списку хост відхиляється, або callback запиту ухвалює рішення. Порушення записується в журнал, щоб агент міг його прочитати.',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,'З’єднання заблоковано списком дозволених мереж','Немає відповідності списку дозволених: мережа за замовчуванням заборонена.']},
function(){return [0,'З’єднання заблоковано списком дозволених мереж','example.com не внесено до списку дозволених.']},
function(){return on('d-npm')?[1,'пакети встановлено (ілюстративний результат)','*.npmjs.org внесено до списку дозволених, тому реєстр доступний.']:[0,'npm ERR! network request to registry.npmjs.org failed\nЗ’єднання заблоковано списком дозволених мереж','Класичний компроміс: надмірна суворість призводить до помилок встановлення.']},
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,'<')+'\n<span class="dim">Запуск усередині пісочниці...</span>';
document.getElementById('why').textContent='';
setTimeout(function(){
t.innerHTML='<span class="p">$</span> '+b.textContent.replace(/</g,'<')+'\n<span class="'+(r[0]?'ok':'no')+'">'+(r[0]?'✓ ':'✗ ')+r[1].replace(/</g,'<')+'</span>';
document.getElementById('why').textContent=r[2];busy=false;post();
},650);
})});
// platforms
var P=['macOS використовує вбудований інструмент sandbox-exec із профілями Seatbelt, які створюються під час кожного запуску. Профіль дозволяє лише 1 локальний порт, на якому працюють проксі srt. Порушення можна переглядати в системному журналі в реальному часі.',
'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 пропонує кілька налаштувань для пошуку золотої середини:
- Маски та порти: записи на кшталт
*.npmjs.orgабоapi.example.com:443. - Callback запиту: ухвалює рішення щодо хостів, на які не поширюється жодне правило, і може повернути причину, яку прочитає модель.
- Списки дозволених ресурсів для окремої команди: відкрити реєстр лише для 1 запуску.
- Оновлення в реальному часі:
--control-fdзмінює мережеві списки під час виконання команди. - Перевірка розпізнаної адреси: блокує дозволені імена, які перетворюються на loopback-адреси або IP-адреси хмарних метаданих.
- Причини заборони домену: повідомляють агенту дозволену альтернативу, наприклад HTTPS-віддалений репозиторій git.
Як це порівнюється з іншими пісочницями для агентів?
| Функція | Anthropic sandbox-runtime | Пісочниця OpenAI Codex CLI | Docker Sandboxes | E2B |
|---|---|---|---|---|
| Ізоляція | Примітиви ОС: Seatbelt, bubblewrap, обліковий запис Windows + WFP | Примітиви ОС: Seatbelt, bubblewrap, вбудована пісочниця Windows | microVM для кожної пісочниці | Firecracker microVM для кожного сеансу |
| Де працює | Локальна машина | Локальна машина | Локальна машина | Хмара або BYOC (AWS, GCP) |
| Потрібен контейнер або ВМ | Ні | Ні | Так (microVM) | Так (керована microVM) |
| Використання поза власним агентом | Так, CLI + бібліотека для будь-якого процесу | Вбудовано в Codex | Так, CLI sbx для агентів програмування | Так, SDK для JS і Python |
| Мережа за замовчуванням | Заборонити все; список дозволених через проксі | Вимкнено в workspace-write; перемикач конфігурації | Політика вибирається під час першого запуску (наприклад, deny-all, balanced) | Увімкнено за замовчуванням; можна вимкнути |
| Список дозволених доменів | Так, маски + порти | Не розкрито (задокументовано перемикач увімкнення/вимкнення) | Так, маски + порти | Так, allowOut із масками (на основі SNI/Host) |
| Ліцензія | Apache-2.0 | Apache-2.0 | Не розкрито | Apache-2.0 (SDK) |
| Статус | Бета-версія дослідницького попереднього перегляду; Windows — альфа-версія | Постачається в Codex CLI | Готовий продукт | Готовий продукт |
Основні висновки
- srt ізолює будь-який процес на рівні ОС, і контейнер не потрібен.
- Seatbelt у macOS, bubblewrap у Linux, Windows — альфа-версія.
- Мережа за замовчуванням заборонена; кожне з’єднання проходить через проксі зі списком дозволених ресурсів на хості.
- Anthropic повідомляє про на 84% меншу кількість запитів дозволу Claude Code (внутрішні дані).
- Ширина списку дозволених ресурсів — головний регулятор безпеки; широкі домени можуть спричинити витік даних.
Перегляньте репозиторій GitHub, інженерну публікацію Anthropic та документацію щодо пісочниці Claude Code. Уся подяка належить досліднику цього проєкту. Також підписуйтеся на нас у Twitter і не забудьте приєднатися до нашого сабреддіту про машинне навчання з понад 150 тисячами учасників та підписатися на нашу розсилку. Стривайте! Ви є в Telegram? тепер ви також можете приєднатися до нас у Telegram.
Потрібно налагодити партнерство з нами для просування вашого репозиторію GitHub, сторінки Hugging Face, випуску продукту, вебінару тощо? Зв’яжіться з нами
Перекладено автоматично з англійської. Оригінал статті — за посиланням нижче.