Перейти к основному содержимому

Полный доступ к диску — неверная единица доверия для агентов

macOS рассматривает полный доступ к диску как бинарное, долговременное разрешение для каждого бинарника. Рабочие нагрузки агентов эпизодичны и определяются во время выполнения, поэтому доверие должно ограничиваться рамками задачи.

Макрофотография печатной платы с дорожками, паяными соединениями и компонентами поверхностного монтажа при малой глубине резкости.

Разрешение шире, чем задача

Полный доступ к диску (FDA) в macOS — это единое разрешение TCC (Transparency, Consent, and Control), которое снимает барьеры песочницы на чтение по всему домашнему каталогу. На практике одно одобрение охватывает хранилище Mail, каталоги профилей Safari и Chrome, связку ключей для входа, базу данных Messages и любые учётные данные разработчика, лежащие в ~/.aws, ~/.ssh или ~/.config. Пользователь видит один диалог и один переключатель. Система видит один бит.

Этот бит долговечен. Он переживает перезагрузки, применяется к каждому будущему вызову подписанного бинарника и не сужается в зависимости от того, как был запущен процесс. Агент, которому во вторник нужно было прочитать одну папку проекта, в пятницу, когда его просят суммировать PDF из каталога загрузок, всё ещё обладает тем же разрешением.

Рабочие нагрузки агентов эпизодичны. У запуска есть начало, план, набор вызовов инструментов и конец. Разрыв между тем, что нужно запуску, и тем, что разрешает грант, — это поверхность риска, и в macOS этот разрыв сейчас равен всему домашнему каталогу.

Почему модель приложения не подходит

Классические приложения macOS имеют стабильный, поддающийся аудиту набор функций. Редактор фотографий читает изображения. Почтовый клиент читает хранилище почты. Проверяющие могут рассуждать о разрешении, потому что поведение ограничено назначением продукта.

Набор чтения агента определяется во время выполнения планировщиком. Один и тот же бинарник, вызванный дважды, может в одной сессии прочитать электронную таблицу, а в следующей — файл связки ключей, потому что план генерируется из промпта и окружения. Не существует статического манифеста, описывающего, к чему будет обращаться процесс.

Wide corridor with white tiled walls and floor, black wooden doors and built-in shelves

Это меняет характер отказа при инъекции промпта. В обычном приложении инъекция может привести к плохому выводу. В агенте, обладающем FDA, инъекция превращает легитимный грант в путь для эксфильтрации без какого-либо повышения привилегий: модель уже авторизована читать учётные данные, а сетевой инструмент уже авторизован отправлять байты. Злоумышленнику не нужно взламывать песочницу; ему нужно направить план.

Пользователю же предлагается рассуждать о диалоге, который говорит «доступ ко всем файлам», когда задача — «суммируй эту папку». Диалог не может выразить задачу, потому что ОС не знает задачу. Поэтому согласие является неинформированным именно в том смысле, который важен: оно не ограничено рамками решения, которое пользователь фактически принимает. Освещение ужесточения Apple этих элементов управления сосредоточилось на опыте разработчиков приложений (The Verge, TechCrunch); случай агента структурно отличается, потому что запрашивающая сторона не является фиксированным набором функций.

Альтернатива с областью задачи

Управление должно перейти от бинарного разрешения ОС к контракту возможностей с областью задачи. Грант ОС становится потолком; фреймворк агента становится точкой принудительного сужения.

Конкретный механизм: выдача ограниченного дескриптора на каждый запуск. Дескриптор — это небольшая запись с четырьмя полями.

  • Пути. Явный список разрешённых каталогов или файлов, разрешаемый во время планирования, а не во время выдачи гранта. Символические ссылки разрешаются, и проверяется именно разрешённый путь.
  • Временное окно. Истечение по настенным часам. После него дескриптор инертен, даже если процесс всё ещё жив.
  • Бюджет байтов. Совокупный лимит на чтение. Когда бюджет исчерпан, дальнейшие чтения завершаются отказом, а не молчаливым усечением.
  • Терминальное состояние. Правило отзыва при завершении. Когда запуск достигает терминального состояния (успех, ошибка, тайм-аут, отмена), дескриптор уничтожается, а запись аудита запечатывается.
handle = broker.issue(
    paths=["~/work/reports/q3"],
    ttl_seconds=600,
    byte_budget=64 * ![Close-up of buttons and control indicators on a black electronic device](/media/control-panel-buttons-macro-b39724-755d22.jpg)led"],
)

![Server racks network](/media/server-racks-network-7e7030-cc721c.jpg)

# every read goes through the handle, not the filesystem
blob = handle.read("~/work/reports/q3/summary.md")

Каждое чтение регистрируется на границе дескриптора, что делает аудиторский след привязанным к задаче, а не к бинарнику. Когда что-то идёт не так, вопрос «к чему обращался этот запуск» имеет прямой ответ вместо реконструкции из телеметрии уровня процесса.

Компромисс реален, и о нём стоит сказать прямо. Брокер, опосредующий чтения, добавляет компонент, который может отказать, а слишком жёсткий бюджет байтов прервёт легитимные длительные задания. Поэтому фреймворк должен предоставлять бюджет планировщику, чтобы агент мог запросить расширение до того, как упрётся в стену, а не обнаруживать лимит как исключение посреди запуска. Это больше движущихся частей, чем один переключатель TCC, и это цена того, чтобы разрешение что-то значило.

Что это означает для разработчиков агентов на macOS

Проектируйте для мира, в котором широкий грант не поощряется. Предпочитайте средства выбора документов, закладки с областью безопасности и разрешения для отдельных каталогов вместо единого одобрения FDA. Закладка, указывающая на одну папку, — более узкая возможность, чем чтение всего домашнего каталога, и её можно сохранять и повторно проверять при каждом запуске.

Исходите из того, что грант будет виден пользователю в уведомлении, и сделайте это уведомление осмысленным. Если система показывает «этот агент прочитал вашу базу данных Messages», агент должен быть в состоянии сказать, какая задача это вызвала и для чего были использованы данные. Уведомление, на которое пользователь не может отреагировать, приучает его отклонять уведомления, что ухудшает управление для всех остальных приложений.

Планируйте отзыв посреди запуска. Дескриптор может истечь, закладка может устареть, пользователь может отключить грант, пока агент работает. Агент должен быть возобновляемым, а не фатальным: сохраняйте контрольную точку плана, отмечайте шаг, потерявший свою возможность, и либо запрашивайте новый дескриптор с более узкой областью, либо чисто останавливайтесь с частичным результатом. Трактовка отзыва как сбоя превращает элемент управления безопасностью в инцидент надёжности, а именно так элементы управления и отключаются.

Более широкая мысль в том, что единица доверия должна соответствовать единице работы. Запуск агента — это единица работы. Время жизни бинарника — нет. Пока модель разрешений не отражает это, каждый агент на macOS находится в одной инъекции промпта от чтения большего, чем когда-либо требовала его задача.

ПоделитьсяXLinkedInПостоянная ссылка5 мин чтения

Связанное чтение

На какие вопросы это отвечает

Why is Full Disk Access a poor fit for agent workloads?

FDA is a single durable grant that applies to every future run of a signed binary and covers mail stores, browser profiles, keychains, message databases and developer credentials at once. Agent runs are episodic and their read set is decided at runtime by a planner, so the grant is almost always wider than the task.

How does prompt injection change the risk profile?

With FDA already granted, an injected instruction does not need to escalate privileges. The agent is already authorised to read credentials and to use a network tool, so steering the plan is enough to turn a legitimate grant into an exfiltration path.

What does a task-scoped handle contain?

An explicit path allowlist resolved at plan time, a wall-clock expiry, a cumulative byte budget, and a revoke-on-completion rule that destroys the handle and seals the audit record when the run reaches a terminal state.

What is the main trade-off of a capability broker?

It adds a mediating component that can fail, and a byte budget that is too tight will abort legitimate long-running jobs. The planner needs visibility into the budget so it can request an extension before hitting the limit, rather than failing mid-run.

How should agents handle revocation mid-run?

Treat it as a resumable state, not a crash. Checkpoint the plan, mark the step that lost its capability, and either request a narrower handle or stop cleanly with a partial result. Controls that cause reliability incidents tend to get disabled.