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

Политики

Политики решают, может ли ZubrCode выполнить действие над указанным ресурсом. Они пишутся в policies и отличаются от разрешений: разрешения — правила по инструментам с результатами allow, deny и ask, а политики бинарны, никогда не спрашивают и только ужимают то, что иначе было бы разрешено.

Запретить провайдер везде — одной записью в opencode.jsonc:

{
"policies": [{ "action": "provider.use", "resource": "openai", "effect": "deny" }]
}

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

Поле Значения Смысл
action provider.use, tool.use, integration.use что контролируется
resource строка или маска к чему применяется запись
effect allow, deny решение при совпадении

Записи, не прошедшие проверку, отбрасываются с предупреждением в логе сервера; остальной список продолжает действовать. После правки deny проверьте лог.

Маски те же, что у разрешений: * — любое количество символов, ? — один. Маска, оканчивающаяся на *, покрывает и значение без аргументов: shell:git push * включает и git push.

Если подходит несколько записей, побеждает последняя. Правила «точнее — важнее» нет, поэтому общие записи ставьте раньше, а исключения — после. Если не подошла ни одна — действие разрешено.

{
"policies": [
{ "action": "provider.use", "resource": "*", "effect": "deny" },
{ "action": "provider.use", "resource": "zubriq", "effect": "allow" }
]
}

Доступным останется только ZuBrIQ.

provider.use управляет самой возможностью пользоваться провайдером; ресурс — id провайдера. Политика действует независимо от того, как провайдер стал известен: каталог, переменные окружения, сохранённые учётные данные или конфигурация. Вместо списков enabled_providers и disabled_providers из 1.x используйте provider.use (Переход с 1.x).

tool.use жёстко запрещает проверку разрешений; ресурс — <действие>:<значение>, он сверяется со всеми ресурсами, которые проверяет инструмент.

{
"policies": [
{ "action": "tool.use", "resource": "shell:git push *", "effect": "deny" },
{ "action": "tool.use", "resource": "edit:*.env", "effect": "deny" },
{ "action": "tool.use", "resource": "webfetch:*", "effect": "deny" }
]
}

Запрещённая проверка завершается ошибкой Blocked by configuration policy вместо вопроса. Политика применяется после правил агента и сохранённых подтверждений, поэтому перекрывает и ask, и «Разрешать всегда».

Маска Блокирует
shell:* все команды оболочки
read:*/.ssh/* чтение SSH-ключей
external_directory:* любой доступ вне проекта
subagent:general запуск одного субагента
<сервер>_<инструмент>:* один инструмент MCP
* всё, что ещё не запрещено

tool.use с allow ничего не разрешает — он только снимает более ранний широкий deny, после чего действуют обычные правила агента.

integration.use управляет загрузкой MCP-серверов, навыков и плагинов; ресурс — вид интеграции и её id:

Ресурс Применяется к
mcp:<сервер> MCP-серверу по его имени
skill:<id> навыку по id
plugin:<пакет> плагину по имени пакета или пути
{
"policies": [
{ "action": "integration.use", "resource": "mcp:*", "effect": "deny" },
{ "action": "integration.use", "resource": "mcp:github", "effect": "allow" }
]
}

Запрещённый сервер или навык убираются, запрещённый плагин не загружается — как бы он ни был настроен.

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

Авторитет Источник
1 (высший) системная конфигурация машины и управляемые настройки
2 глобальная ~/.config/zubrcode/opencode.json(c)
3 opencode.json(c) проекта; внешние каталоги важнее внутренних
4 (низший) .opencode/opencode.json(c); внешние каталоги важнее внутренних

Репозиторий не может вернуть провайдера, запрещённого в глобальной конфигурации: deny глобального файла остаётся в силе. Внутри одного файла записи сохраняют написанный порядок.