Перейти к основному содержанию
Когда правило firewall возвращает pending_approval, вызов инструмента удерживается, и ваш агент ждёт. По умолчанию ревьюер снимает это удержание из консоли. Вебхук подтверждений firewall подключает тот же шлюз в вашу систему: шлюз POST’ит подписанное уведомление на ваш эндпоинт в тот момент, когда вызов удержан, а ваша система POST’ит подписанное HMAC решение обратно, чтобы его освободить — без места в консоли, без опроса человека. Это асинхронная (callback) половина human-in-the-loop. Удержанный вызов, вердикт и путь разрешения в консоли покрыты в Разрешении подтверждений и справочнике Firewall; эта страница — только проводка вебхука.
Вебхук — это быстрое уведомление, не система записи. Long-poll ретрансляции на удержанном вызове — авторитетный шлюз — если уведомление потеряно или ваш приёмник лежит, удержание всё равно стоит, и ревьюер может снять его из консоли. Настройка вебхука лишь добавляет программный способ его разрешить.

1. Когда использовать вебхук подтверждений firewall

Тянитесь за ним, когда шлюз human-in-the-loop firewall должен быть разрешён чем-то иным, чем человек, кликающий кнопку:

Маршрутизация в ваш собственный UI подтверждений

Проталкивайте удержанные вызовы инструментов в Slack, PagerDuty или внутреннюю очередь разбора и разрешайте их там, где ваша команда уже работает.

Программная политика

Авто-одобрить удержанный db.query против read-реплики, авто-отклонить против prod — ваш код решает, шлюз применяет.

2. Настройте его в консоли

Обе половины живут на одной настройке рабочего пространства. Откройте Firewall → Settings и заполните два поля (действие Developer+ — запись настроек ограничена ролью):
https:// эндпоинт, на который мы POST’им, когда вызов удержан. HTTP отвергается, и URL прогоняется через SSRF-preflight при сохранении, так что loopback, приватный диапазон или назначение cloud-metadata отклоняется до того, как может быть сохранено. Оставьте пустым, чтобы полностью отключить асинхронный путь.
Секрет HMAC только-на-запись (до 255 символов). Он подписывает наше исходящее уведомление и аутентифицирует ваш входящий колбэк. Консоль никогда не отдаёт его обратно — после сохранения вы видите только, что секрет задан; ротируйте, записав новое значение.
Эндпоинт колбэка — только HMAC. Пока общий секрет не задан, шлюз не будет доставлять уведомления и отклоняет каждый колбэк — шлюз можно снять только из консоли. Задайте секрет, чтобы включить асинхронный путь.
Предпочитаете REST API? Те же поля обновляются через консольный маршрут настроек (UserAuth, Developer+):
curl -X PUT https://api.orcarouter.ai/api/workspace/firewall/settings \
  -H "Authorization: Bearer $ORCA_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "approval_webhook_url": "https://hooks.example.com/orca/firewall",
        "approval_webhook_secret": "whsec_your_shared_secret"
      }'

3. Уведомление, которое мы вам отправляем

Когда вызов удержан, мы POST’им подписанный JSON-конверт на ваш URL:
POST /orca/firewall HTTP/1.1
Content-Type: application/json
X-Orca-Event: firewall.approval.pending
X-Orca-Signature: sha256=<hex>
{
  "event": "firewall.approval.pending",
  "workspace_id": 42,
  "occurred_at": "2026-06-09T17:04:11.482Z",
  "data": {
    "approval_id": "665f1b...",
    "tool_name": "db.query",
    "request_id": "req_9f2c...",
    "conversation_id": "conv_77a1...",
    "policy_id": 7,
    "rule_id": 31
  }
}
Конверт — это сигнал маршрутизации, не полный контекст — он несёт approval_id, который вам нужен для разрешения, и идентификаторы для корреляции, никогда аргументы инструмента. Детали аргументов живут в очереди Approvals и журнале событий firewall.
Проверьте исходящую подпись, прежде чем доверять полезной нагрузке: X-Orca-Signature — это sha256= + hex HMAC-SHA256(secret, raw_body) над точными байтами, которые вы получили. Сравнивайте за постоянное время. Доставка at-least-once и повторяется при переходных сбоях, так что сделайте свой обработчик идемпотентным по approval_id.

4. Колбэк, который вы POST’ите обратно

Чтобы освободить (или отклонить) удержание, POST’ните своё решение на эндпоинт колбэка с approval_id из уведомления:
POST /api/v1/firewall/approvals/665f1b.../callback
X-Orca-Signature: sha256=<hex>
Content-Type: application/json

{ "decision": "approved", "reason": "read-replica query, auto-approved" }
decision — это approved или rejected — никакое другое значение не принимается. reason опционален и появляется в аудит-трейле разрешённого подтверждения.
Подпись колбэка привязана к id подтверждения, так что захваченную подпись нельзя воспроизвести против другого удержанного вызова. Подпишите строку <approval_id> + литеральный перевод строки (\n) + сырое тело запроса:
X-Orca-Signature = "sha256=" + HMAC_SHA256(secret, approval_id + "\n" + body)
Это отличается от исходящего уведомления, которое подписывает тело само по себе. Колбэк, чья подпись не проверяется, получает 401 — и отсутствующий, несовпадающий или несуществующий id подтверждения возвращает тот же 401, так что эндпоинт никогда не подтверждает, существует ли id.
Колбэк first-decision-wins и идемпотентен: кто разрешает первым — ваш вебхук или консольный ревьюер — задаёт исход, а повторный колбэк для уже-разрешённого подтверждения возвращает 200, так что ваша система перестаёт повторять.

5. Освобождение удержанного вызова

Разрешение подтверждения не воспроизводит вызов инструмента за вас — оно поднимает шлюз, так что ваш агент может его повторно выпустить. Рантайм агента:
  1. Опрашивает состояние удержания на GET /api/v1/firewall/approvals/:id (ключ с областью firewall-gateway, не ваш ретрансляционный ключ или консольная сессия), пока оно не покинет pending.
  2. При approved повторно отправляет оригинальный вызов инструмента, неся одноразовый заголовок X-OrcaRouter-Firewall-Approval — шлюз пропускает этот один вызов, и токен потрачен.
Если нижележащее правило было отредактировано после того, как вызов был удержан, очередь Approvals флагирует, что правило с тех пор изменилось, и подавляет теперь-устаревшую клаузу «held because…», так что консольный ревьюер не действует на происхождение, которое больше не совпадает с тем, что удержало вызов.

6. Проверьте проводку

Быстрая end-to-end проверка, прежде чем полагаться на неё:
ШагЧто сделатьОжидается
Удержать вызовСработать правилом с вердиктом pending_approval400 firewall_approval_pending
УведомлениеНаблюдать за вашим эндпоинтомПриходит подписанный POST firewall.approval.pending
КолбэкPOST’нуть подписанный { "decision": "approved" }200 с разрешённым состоянием
Защита от повтораPOST’нуть колбэк снова200, уже разрешено (нет двойного применения)
Если уведомление никогда не приходит, подтвердите, что секрет задан (без него шлюз не доставит) и что URL прошёл проверки HTTPS + SSRF при сохранении.

7. Куда это вписывается

Разрешение подтверждений

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

Вердикты

Откуда берётся pending_approval и как он компонуется с другими вердиктами.

Ключи шлюза

Создайте ключ с областью firewall-gateway, нужный потоку опрос + повтор.

Избыточная автономия

Угроза, которую построены сдерживать шлюзы human-in-the-loop.
О модели вердиктов, поверхностях применения и остальном firewall см. справочник Firewall.