Перейти к основному содержанию
Назвать инструмент и отклонить его — грубо: это убивает инструмент для каждого вызова. Чаще всего инструмент в порядке, а проблема — одна форма вызова: shell.exec в порядке, пока команда не rm -rf, db.query в порядке, пока он не попадает на prod. Это различие выражает клауза аргумента: предикат jsonpath для аргумента инструмента, который совпадает по значениям, которые передаёт агент, так что вердикт срабатывает только на опасном вызове и оставляет остальные в покое. Эта страница — кулинарная книга — горстка готовых рецептов args_match_json для случаев, которые встречаются чаще всего. О полной грамматике клауз, таблице операторов и семантике fail-closed см. Проверку аргументов и справочник Схемы правил.

1. Как работает клауза jsonpath для аргумента инструмента

args_match_json правила — это JSON-кодированная строка, несущая набор клауз, все объединённые по AND. Декодированное значение — объект, {"clauses": [ … ]}, где каждая клауза — тройка { path, op, value }:
  • path — маленькое подмножество JSONPath над объектом аргументов инструмента: $.command, $.foo.bar, $.items[0] или $ для всего объекта. Нет wildcard’ов, фильтров, срезов или рекурсивного спуска.
  • op — один из закрытого набора: eq, contains, regex, in, cidr_match, gt, lt.
  • value — литерал для сравнения (строка, число, bool или — для in — JSON-массив).
Клауза объединяется по AND с tool_name_glob правила: правило срабатывает только когда имя инструмента совпадает и каждая клауза держится. Опустите args_match_json целиком (или оставьте его пустым "{}") — и правило совпадает по глобу в одиночку.
Клаузы fail closed — правило, а не запрос. Если путь не разрешается, аргументы некорректны или значение неправильного типа, клауза вычисляется в false, и правило просто не срабатывает — вызов проваливается к следующему правилу или default-вердикту. Сломанная клауза никогда не авто-отклоняет. Пишите свой жёсткий backstop как обычный глоб deny, а не как клаузу, на которую вы полагаетесь, что она провалится определённым образом.

2. Рецепт: заблокировать одну деструктивную команду

Канонический случай. Разрешить shell.exec в целом, отклонить его только когда команда выглядит деструктивной. Клауза regex на $.command делает это:
{
  "label": "block destructive shell commands",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|mkfs|dd if=\"}]}"
}
Regex’ы — это Go RE2 — линейное время, без обратных ссылок, без катастрофического backtracking — так что их безопасно запускать на каждом вызове инструмента. Нестроковый $.command (или отсутствующий) никогда не совпадает, так что некорректный вызов проваливается, а не блокируется ошибочно.
Предпочитайте contains вместо regex, когда вы совпадаете с фиксированной подстрокой — его проще читать, и его нельзя сбить неэкранированным метасимволом. Тянитесь за regex только когда вам действительно нужна альтернация или якоря.

3. Рецепт: отклонить инструмент против названного окружения

Пусть db.query выполняется, но только против безопасных подключений — отклоните его, когда цель — prod или replica. Оператор in совпадает с разрешённым значением против любого элемента JSON-массива:
{
  "label": "no agent queries against prod",
  "tool_name_glob": "db.query",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.connection\",\"op\":\"in\",\"value\":[\"prod\",\"replica\"]}]}"
}
Значение in должно быть JSON-массивом — не-массив отклоняется, когда вы сохраняете правило. Элементы сравниваются скалярным равенством, так что числа и строки каждое совпадает со своим типом.

4. Рецепт: отклонить назначение с приватным IP или metadata

Когда инструмент принимает целевой IP как аргумент, cidr_match проверяет, попадает ли он внутрь CIDR — SSRF-форма «агент извлекает 10.x или адрес cloud metadata»:
{
  "label": "deny tool calls aimed at RFC-1918",
  "tool_name_glob": "*",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.target_ip\",\"op\":\"cidr_match\",\"value\":\"10.0.0.0/8\"}]}"
}
Значение аргумента должно парситься как IP-литерал, который сидит внутри CIDR; имя хоста или не-IP строка никогда не совпадает.
cidr_match инспектирует только значение, которое уже в аргументах инструмента. Для управления назначением, которого инструмент реально достигает на сетевом уровне — host/CIDR allow и deny списки — используйте выделенное egress-правило на поверхности egress вместо этого. Эти два взаимодополняющие: инспекция аргумента на входе, контроль egress на выходе.

5. Рецепт: ограничить числовой аргумент

gt и lt сравнивают числа. Используйте их, чтобы отказать в абсурдном размере пакета, чрезмерном лимите или любом убегающем счётчике — здесь отклоните bulk-удаление, которое нацелено более чем на 100 строк:
{
  "label": "block large bulk deletes",
  "tool_name_glob": "*.bulk_delete",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.count\",\"op\":\"gt\",\"value\":100}]}"
}
Обе стороны должны быть числами — числовидная строка вроде "500" — это несовпадение типов и не совпадает, так что правило не сработает на строково-типизированном аргументе. Держите аргумент числовым или нормализуйте его, прежде чем инструмент его увидит.

6. Рецепт: сочетать клаузы (AND)

Все клаузы в одном правиле объединяются по AND, так что вы можете сузить вердикт до очень конкретного вызова — например, отклонить shell.exec только когда это деструктивная команда и она нацелена на prod-хост:
{
  "label": "destructive shell on a prod host",
  "tool_name_glob": "*.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|drop table\"},{\"path\":\"$.host\",\"op\":\"in\",\"value\":[\"db-prod-1\",\"db-prod-2\"]}]}"
}
Нужен OR вместо этого? Нет OR внутри одного args_match_json — создайте два правила (или два глоба) на разных приоритетах. Движок проходит правила в порядке приоритета, и побеждает первое совпадение, так что ставьте узкие правила первыми. См. Приоритет правил.

7. Выберите вердикт для совпавшей формы

Клауза решает, какие вызовы совпадают; verdict правила решает, что происходит. deny — дефолт кулинарной книги, но та же клауза может нести более мягкий вердикт:
Когда совпавший аргумент несёт секрет или PII, а не опасную инструкцию, sanitize редактирует совпавшие подстроки из аргументов инструмента и пересылает очищенный вызов. Редактирует только аргументы — никогда содержимое, которое возвращает инструмент. См. Очистку ответов.
Удержите ровно рискованную форму для разбора вместо прямой блокировки: ревьюер одобряет или отклоняет вне основного канала, и агент повторно отправляет одобренный вызов один раз. См. Подтверждения.
Установите вердикт в audit, чтобы записать совпавший вызов без блокировки, пока вы настраиваете клаузу. Сочетайте с shadow-режимом, чтобы измерить deny против живого трафика, прежде чем он что-либо изменит.

8. Протестируйте клаузу, прежде чем полагаться на неё

Вкладка Test в консоли прогоняет политику вхолостую против образца вызова инструмента и возвращает вердикт, совпавшее правило и причину — ничего не диспетчеризуется, ничего не сохраняется. Вставьте реалистичный объект аргументов и подтвердите, что клауза срабатывает на вызовах, которые вы имеете в виду, и только на них, поскольку клауза, которая не может разрешить значение, молча не срабатывает. См. Тестирование правил.
Клаузы валидируются строго при сохранении — неизвестные операторы, плохие пути, не-массивное значение in, некомпилируемый regex и недействительные CIDR все отклоняются, так что некорректная клауза не может быть сохранена в принципе.

9. Кто может создавать клаузы аргументов

Всё это выполняется в консоли под вашей сессией (/api/workspace/firewall/*):
ДействиеРоль
Чтение политик, пресетов, обнаруженных инструментовMember
Создание / редактирование / удаление правилDeveloper+
Песочница Test (прогон политики вхолостую)Developer+
Чтение событий и свёрток прогоновDeveloper+
Создание или изменение клаузы аргумента — запись Developer+. Песочница Test тоже Developer+ — она может предпросматривать против черновой политики, а её трассировка вердикта выставляет имена политик и метки правил, так что она сидит на стороне записи, а не чтения.

Связанное

Проверять аргументы

Use-case сопоставления аргументов целиком.

Блокировать инструменты

Отклонить целый инструмент по имени — клауза не нужна.

Контроль egress

Управлять исходящими host / IP / CIDR назначениями.

Схема правил

Каждое поле, которое может нести правило.

Приоритет правил

Побеждает первое совпадение — упорядочьте узкое перед широким.

Опасные вызовы инструментов

Угроза, которую решают эти рецепты.