feat(isolation): запис агента обмежено worktree на рівні ОС - #60
Merged
Conversation
Рішення Vitalii: ізолюємо лише файловий запис і лише в межі worktree. Повна ізоляція (мережа, exec) ламає підписочні CLI — вони ходять у власні API і запускають тулчейни, — тож її вимикали б назад цілком. Вузька межа, яку не хочеться вимикати, захищає більше за широку, яку вимкнули. sandbox.isolation: worktree (вимкнено за замовчуванням, як skill_profiles) обгортає CLI у sandbox-exec: запис дозволений у worktree, TMPDIR і явно перелічені sandbox.isolation_writable; усе інше read-only. Мережа й allowlist команд лишаються декларативними. Корінь — worktree, а не тека вузла: агент штатно чіпає весь чекаут, і звуження до теки вузла зробило б пісочницю непридатною, а не суворішою. Шлях канонізується обовʼязково. sandbox-exec звіряє резолвлені шляхи, і профіль із логічним /var/folders/… не покриває реальний /private/var/… — пісочниця забороняла б запис навіть у власний worktree. Симптом «усе зламалось», причина непомітна; на це є тест. На непідтримуваній платформі — відмова run-а, а не тихий запуск без ізоляції: виглядати захищеним, не будучи ним, гірше за явну відмову. Реалізовано macOS (перевірено живим прогоном пісочниці в тесті), Linux свідомо не вгадуємо. Побічно: PATH_LOCK у тестах більше не отруюється — одна тимчасова невдача за budget перетворювалась на десяток PoisonError, і справжню причину доводилось відкопувати з-під наслідків.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Рішення
Ізолюємо лише файловий запис і лише в межі worktree.
Повна ізоляція (мережа, exec) ламає підписочні CLI — вони ходять у власні API і запускають тулчейни, — тож її вимикали б назад цілком. Вузька межа, яку не хочеться вимикати, захищає більше за широку, яку вимкнули.
Що це дає: агент, який зірвався, не може зіпсувати робоче дерево, чужі worktree, конфіги користувача чи систему — усе поза worktree для нього read-only.
Механізм
sandbox.isolation: worktree(вимкнено за замовчуванням, той самий принцип, що вskill_profiles) обгортає CLI уsandbox-exec. Дозволено на запис: worktree,TMPDIRі явно переліченіsandbox.isolation_writable(для стану CLI на кшталт~/.claude) — кожен отвір видно в конфігу.Корінь — worktree, а не тека вузла: агент штатно чіпає весь чекаут (код, тести, конфіги), і звуження до теки вузла зробило б пісочницю непридатною, а не суворішою.
Пастка, яку варто знати
Шлях обовʼязково канонізується.
sandbox-execзвіряє резолвлені шляхи: профіль із логічним/var/folders/…не покриває реальний/private/var/folders/…, і пісочниця забороняє запис навіть у власний worktree. Симптом — «усе зламалось», причина — непомітна. Я наступив на це під час перевірки; тепер на це є тест.Fail closed
На непідтримуваній платформі — відмова run-а, а не тихий запуск без ізоляції: виглядати захищеним, не будучи ним, гірше за явну відмову. Реалізовано macOS; Linux свідомо не вгадуємо (
bwrapбез можливості перевірити — це саме той випадок, коли неперевірений код у безпековому місці гірший за його відсутність).Найважливіший тест модуля справді запускає пісочницю і перевіряє, що запис у worktree проходить, а запис у
$HOME— ні. Він доводить ізоляцію, а не збирання рядка профілю.Побічна знахідка
Під час перевірки набір впав десятьма помилками. Розібрався: одна тимчасова невдача (
budget-exceededпід паралельним clippy+лінтом) отруювалаPATH_LOCK, і сусідні тести падали каскадомPoisonError— справжню причину доводилось відкопувати з-під наслідків. Замок лише серіалізує мутацію PATH і жодного інваріанта не боронить, тож теперunwrap_or_else(into_inner). Перевірив, що це не моя регресія: 3/3 прогони чисті і наmain, і зі зміною.Карта
Заразом актуалізовано
docs/conformance.md:ЧАСТКОВОтепер не борг, а зафіксована межа);directory.rsпершим.Перевірка
cargo test --workspace— 459 passed, clippy й лінт чисті.