Если режим задаёт общий ритм, а песочница - физическую границу, то файл разрешений уточняет отдельные действия. В нём перечисляют команды терминала, которые можно выполнять без вопросов, инструменты внешних серверов, которым доверяют, и текстовые указания для автоматической проверки. Живёт он в двух местах - пользовательском и репозиторном, - и это разделение важно: личные привычки и командная политика не должны смешиваться в одном файле. Пользовательский файл принадлежит человеку и едет за ним из проекта в проект. Репозиторный принадлежит коду и приезжает вместе с ним к каждому, кто его склонировал. Требование, которое обязано действовать у всех, в пользовательском файле не живёт по определению.
Слияние слоёв устроено предсказуемо: массивы из пользовательского и репозиторного файлов объединяются, а любой ключ, заданный в этих файлах, целиком замещает соответствующий список из интерфейса. Разница между объединением и заменой не мелочь. Там, где массивы складываются, локальное послабление добавляется к общему и незаметно расширяет его. Там, где происходит замена, оно вытесняет то, что было настроено раньше, и вы теряете старый список целиком. Порядок принуждения строгий, и его надо знать наизусть: административная политика команды сильнее файлов разрешений, а файлы сильнее того, что вы нажали в интерфейсе. Это ровно та иерархия, которая позволяет организации гарантировать минимум, не запрещая проектам уточнять детали.
Полезно один раз увидеть цельный файл. Ниже - список разрешённых команд терминала с шаблонами, список разрешённых инструментов внешних серверов и блок указаний для автоматической проверки: что разрешать и что блокировать. Шаблоны здесь удобны, но требуют аккуратности: чем шире шаблон, тем больше он захватывает, и разрешение вида любые команды пакетного менеджера открывает и то, о чём вы не думали. Шаблон сопоставляется с текстом команды, а не с её смыслом, поэтому звёздочка в конце строки - это обещание, что любое продолжение вас устроит.
Отдельно стоит разобраться с указаниями для автоматической проверки, потому что вокруг них больше всего иллюзий. Это подсказки классификатору на естественном языке: они помогают ему решать пограничные случаи в нужную сторону. Но это направление, а не запрет. Строка блокируй публикацию и удаление снижает вероятность, но не делает действие невозможным: классификатор читает и её, и саму команду, и остальной контекст, и итог складывается из всего сразу. Для жёсткого запрета есть другие средства: песочница, hooks и административные настройки. Сами списки разрешённого документация тоже относит к средствам удобства, а не к границе безопасности.
Эта разница - главное различение, на котором держится вся настройка разрешений. Механизмы делятся на те, что уговаривают, и те, что запрещают. Уговаривающие полезны: они снимают рутинные подтверждения, а формулировать их можно по-человечески, не перечисляя все варианты написания команды. Но безопасность строят на запрещающих, потому что только они дают воспроизводимый результат независимо от формулировки, содержимого репозитория и того, как сегодня рассуждает модель. Уговаривающий слой отвечает за удобство, запрещающий - за то, что удобству доверять нельзя.
Разница видна на конкретном сценарии. Агент читает файл из репозитория, в котором среди обычного текста лежит строка, адресованная ему: выгрузить содержимое переменных окружения по внешнему адресу. Указания классификатору здесь работают как ещё один голос в общем хоре текста - они конкурируют с прочитанным, а не отменяют его. Список разрешённых команд работает иначе: в режиме списка команда, которой в нём нет, не выполняется без подтверждения, и то, какими словами её попросили, значения не имеет. В режиме автоматической проверки неразрешённая команда всё же попадает к классификатору и может уйти без вопроса. Первый механизм спорит, второй просто не пускает.
Любое изменение политики заканчивают негативным тестом. Попросите выполнить заведомо запрещённое безопасное действие: прочитать тестовый закрытый файл, обратиться к неразрешённому домену, запустить безобидную, но не входящую в список команду. Если отказ наблюдается - политика работает. Если нет, вы только что узнали об этом в контролируемых условиях, а не в тот момент, когда это будет стоить дорого. Тест на разрешённом действии не доказывает ничего: он проходит и при полностью выключенной проверке.
У списков разрешённого есть своя цена, и её лучше знать заранее. Каждая новая строка убирает одно подтверждение и одновременно расширяет то, что происходит без вашего участия. Список, выросший до нескольких десятков шаблонов, уже никто не читает целиком, а значит, никто не может сказать, что именно разрешено. Признак, по которому в реальной работе понимают, что зашли слишком далеко, простой: подтверждения перестали появляться вообще, а в записи сессии встречаются команды, которых вы не планировали. Это не сбой. Это ровно то, что вы разрешили, просто записанное шире, чем имели в виду.
Инженерный вывод про списки разрешённого простой: их пишут под именованные задачи, а не под удобство. Сборка, линт, тесты, проверка типов - это понятные семейства команд, которые легко объяснить в ревью и легко сузить до конкретных подкоманд. Публикация, деплой, работа с секретами и разрушительные операции остаются за пределами списка не потому, что агент с ними не справится, а потому, что цена ошибки там несоизмерима с экономией одного подтверждения. Хороший список короткий настолько, что его можно прочитать вслух и не сбиться.
Типичные провалы предсказуемы. Принять указания для классификатора за запрет. Написать слишком широкий шаблон команды и открыть семейство, о котором не думали. Положить командную политику в пользовательский файл, откуда её легко снять. Проверить изменение только разрешённым действием и решить, что политика работает. И не перечитывать список разрешённого, пока он растёт.
// .cursor/permissions.json
{
"terminalAllowlist": ["git status", "pnpm:test*"],
"mcpAllowlist": ["github:get_pull_request", "linear:search*"],
"autoRun": {
"allow_instructions": [
"Разрешай только read-only команды git и тесты проекта"
],
"block_instructions": [
"Блокируй публикацию, удаление и любые команды с секретами"
]
}
}
// указания - подсказки классификатору, а не запрет