Перейти к основному содержанию
Когда правило firewall возвращает вердикт pending_approval, вызов инструмента агента удерживается вместо диспетча — теперь он ждёт человека. Эта страница — для ревьюера: как одобрить удержание вызова инструмента агента (или отклонить его) из консоли, что показывает вам очередь, и как OrcaRouter не даёт двум ревьюерам столкнуться на одном решении. Это половина-разрешение human-in-the-loop. О том, почему вызов удерживается и как удержанный агент повторно отправляет потом, см. вердикты и более глубокий справочник подтверждений. Чтобы разрешать из вашей собственной системы вместо консоли, см. вебхуки подтверждений.

1. Жизненный цикл удержанного вызова с места ревьюера

Удержанный вызов — это короткий цикл вне основного канала. Ваша работа — средний шаг:
1

Вызов удержан

Правило разрешается в pending_approval. Ретрансляция возвращает HTTP 400 с кодом firewall_approval_pending и id подтверждения; вызов никогда не достигает инструмента. Агент начинает опрашивать по этому id.
2

Вы его разрешаете

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

Агент продолжает (или останавливается)

При одобрении агент повторно отправляет оригинальный вызов с одноразовым заголовком X-OrcaRouter-Firewall-Approval, и шлюз пропускает его этот один раз. При отклонении вызов остаётся заблокированным.
Разрешение удержания ограничено Developer+ — тот же шлюз, что у ленты событий firewall. Более низкие роли могут читать политику firewall, настройки и обнаруженные инструменты, но только роли Developer-и-выше могут перечислить очередь подтверждений или одобрить/отклонить удержанный вызов инструмента. См. роли и область.

2. Перечислите очередь pending

Вкладка Approvals читает GET /api/workspace/firewall/approvals. Без фильтра она возвращает очередь pending, старейшими первыми — так что дольше-всего-ждущий вызов сидит наверху, и вы обрабатываете backlog по порядку.
GET /api/workspace/firewall/approvals?state=pending
state — единственный фильтр, который важен. Значения отображаются на жизненный цикл подтверждения:
stateВозвращаемые подтверждения
pending (по умолчанию)Удержано, ожидает решения — ваша рабочая очередь.
approvedУже пропущено.
rejectedУже заблокировано.
Это маршрут консоли на вашей сессии — настраивайте и просматривайте его из дашборда, не ретрансляционным ключом sk-orca-…. Ретрансляционные ключи — для вызовов модели /v1/*; управление firewall выполняется под вашим консольным логином.

3. Прочитайте, почему вызов был удержан

Каждая строка несёт входные данные решения, нужные ревьюеру — имя инструмента (tool_name), отпечаток аргументов (args_hash, SHA-256 канонизированных аргументов вызова — сырые значения аргументов не хранятся в подтверждении), id запроса и строку происхождения на обычном языке, которая называет политику, правило и клаузу, которая сработала:
Названная политика, которой принадлежит совпавшее правило, разрешённая в области рабочего пространства, так что устаревший id никогда не всплывёт имя политики другого тенанта.
Метка правила и однострочный дескриптор «почему» — например, command contains rm -rf или tool matches "http_fetch" для правила только-с-глобом. Это рендерит строку «Held because…» в очереди.
true, когда совпавшее правило было отредактировано в момент или после создания этого подтверждения. Живая метка и клауза тогда подавляются (они могут больше не отражать то, что реально удержало вызов), и очередь показывает заметку «rule since changed» вместо устаревшего происхождения. Имя инструмента и аргументы — реальные входные данные решения — показываются всегда.
rule_changed — намеренный сигнал честности, не ошибка. Если кто-то редактирует правило firewall, пока вызов сидит в очереди, OrcaRouter предпочёл бы скрыть возможно-неправильную причину, чем показать вам происхождение, которое больше не совпадает. Решайте по имени инструмента и имени политики (всё ещё показанным) в этом случае.

4. Одобрить или отклонить

Разрешение отправляет PATCH /api/workspace/firewall/approvals/:id с decision approved или rejected и опциональным reason. Консоль делает это за вас, когда вы кликаете кнопку; форма такая:
PATCH /api/workspace/firewall/approvals/507f1f77bcf86cd799439011
Content-Type: application/json

{ "decision": "approved", "reason": "verified target host with the on-call" }
  • approved → удержанный вызов может продолжить. Следующая повторная отправка агента, несущая одноразовый заголовок подтверждения, пропускается один раз.
  • rejected → вызов остаётся заблокированным. Агент видит отклонение и может выбрать другой путь, спросить пользователя или остановиться.
decision валидируется против закрытого набора {approved, rejected} — всё остальное отклоняется. reason записывается с решением и пишется в журнал аудита firewall вместе с актором, именем инструмента и id запроса.
Каждое разрешение пишет строку аудита рабочего пространства, называющую, кто решил, решение и причину. Консольные разрешения записывают человеческого актора; разрешения через вебхук записывают системного актора. Происхождение разрешения никогда не отбрасывается молча.

5. First-writer-wins: нет двойного разрешения

Pending-подтверждение может попасть в гонку — два ревьюера в консоли или консольный клик и вебхук-колбэк, приходящие вместе. OrcaRouter решает это единственным правилом first-writer-wins:
  • Решение — это атомарное условное обновление, которое срабатывает только пока подтверждение всё ещё pending. Первый писатель побеждает и применяет решение.
  • Каждый более поздний писатель наблюдает «уже разрешено» и трактуется как идемпотентный no-op — он получает HTTP 200 с уже-разрешённым документом, не ошибку.
Ответ говорит вам, на какой стороне вы были:
{
  "resolved": false,
  "already_resolved": true,
  "approval": { "state": "approved", "decision": "approved", "...": "..." }
}
resolved: true означает, что ваш вызов применил решение; already_resolved: true означает, что кто-то (или какой-то вебхук) добрался туда первым, и вы видите их исход. В любом случае очередь сходится к одному согласованному состоянию.
Поскольку разрешение идемпотентно, нестабильная сеть или двойной клик не могут испортить удержание или перевернуть решение. Первое одобрение/отклонение — единственное, что считается; всё после него просто считывает результат обратно.

6. Конкретный проход по очереди

Рабочее пространство с balanced-автономией удерживает вызов shell.exec агента, потому что правило совпало command contains rm -rf. Как ревьюер вы:
  1. Откройте Approvals — удержанный shell.exec сидит наверху списка pending старейшими-первыми.
  2. Прочитайте строку: инструмент shell.exec, отпечаток args_hash, id запроса и строку «Held because… command contains rm -rf» (отрендеренную из клаузы совпавшего правила). Нет флага rule_changed, так что происхождение актуально.
  3. Цель — временная директория, так что вы одобряете с причиной.
  4. Ваш PATCH возвращает resolved: true; следующий опрос агента видит approved, повторно отправляет со своим одноразовым заголовком, и команда выполняется ровно один раз.
Если бы коллега одобрил это секундой раньше, ваш клик вернул бы already_resolved: true с их решением — без вреда, без двойного запуска.

Куда двигаться дальше

Справочник подтверждений

Полный цикл HITL: удержание, опрос, повторная отправка и одноразовый заголовок.

Вебхуки подтверждений

Разрешайте удержания из вашей собственной системы подписанным HMAC колбэком.

Вердикты

Где pending_approval сидит среди шести вердиктов firewall.

Журнал событий

Подтвердите downstream-исход разрешённого вызова в ленте.
О рисках, которые эти удержания призваны поймать, см. опасные вызовы инструментов и избыточную автономию.