Настройка webhooks
OSA Proxy отправляет HTTP POST-уведомления о скачивании и блокировке файлов. Webhook не участвует в обработке запроса клиента: загрузка не ждёт receiver, а ошибка доставки не изменяет ответ OSA Proxy.
Уведомления доступны для всех поддерживаемых экосистем, кроме Docker. Они создаются только для GET-запросов к маршрутам репозиториев. HEAD-запросы, служебные endpoints и обычные ошибки upstream уведомлений не создают.
События
Если подписка содержит одновременно file_downloaded и scanned_file_downloaded, для одного проверенного запроса отправляется только одно уведомление с trigger: scanned_file_downloaded.
Статус 200 или 206 означает ответ, зафиксированный OSA Proxy. Он не подтверждает, что клиент полностью получил или сохранил файл.
Формат запроса
Каждый POST содержит ровно одно событие:
Поля payload:
OSA Proxy отправляет Content-Type: application/json. При настроенном секрете также отправляется X-CodeScoring-Authentication. Подписи запроса отдельным заголовком нет.
Webhook продолжает trace исходного запроса: receiver получает trace-заголовки и тот же X-Trace-Id, который используется для upstream и CodeScoring-запросов.
Тестовый POST отличается от рабочего уведомления и проверяет только соединение:
Receiver может вернуть любой статус 2xx: OSA Proxy считает такую доставку успешной и игнорирует тело ответа.
Настройка через osa-proxy.yml
В режиме без Configuration Store добавьте подписки в корень osa-proxy.yml. В token_env укажите имя переменной окружения с токеном:
После изменения YAML перезапустите все реплики OSA Proxy. Для одинакового поведения каждая реплика должна получить одинаковый список подписок и токенов.
Параметры подписки
Каждая включённая подписка имеет собственную ограниченную очередь и один последовательный sender. Если очередь заполнена, новое уведомление удаляется. OSA Proxy раз в 30 секунд пишет суммарное количество таких потерь в warning-лог webhook notifications dropped.
На одно уведомление выполняется только одна попытка. Retry и сохранения на диск нет. Redirect не выполняется: ответ 3xx считается ошибкой доставки. Ответы не 2xx, timeout и сетевые ошибки записываются в warning-лог webhook delivery failed, но не влияют на клиентский запрос.
При переполнении очереди, остановке процесса или ошибке receiver уведомление может быть потеряно. Не используйте webhook как единственный источник аудита или как транзакционное подтверждение скачивания.
Аутентификация receiver
Создайте Secret с токеном receiver и передайте его в OSA Proxy через переменную окружения. Затем укажите имя переменной в token_env:
Не записывайте значение токена в конфигурацию или репозиторий. В managed mode передайте token_env через Admin API вместе с подпиской — добавлять тот же webhook в osa-proxy.yml не нужно. API хранит и возвращает только имя переменной, но не токен.
Если переменная не задана или пуста, подписка не активируется. После добавления или изменения Secret перезапустите все реплики OSA Proxy.
Проверка подключения через Admin API
Admin API работает на отдельном listener, по умолчанию 127.0.0.1:8081, и использует Bearer Admin Token. В Kubernetes не публикуйте admin Service наружу без TLS, аутентифицированного ingress/reverse proxy и сетевых ограничений.
Проверить ещё не сохранённую подписку можно независимо от того, включён Configuration Store или нет:
Пример успешного результата:
success: true означает только то, что тестовый POST получил 2xx. Возможные error_category: invalid_configuration, timeout, connection, http_status.
Управление подписками через Admin API
CRUD подписок доступен только при включённом Configuration Store. При выключенном хранилище эти endpoints возвращают 503 managed_storage_disabled; используйте YAML. Swagger UI доступен на /swagger/, OpenAPI — на /openapi.json admin listener.
Основные endpoints:
Все изменяющие запросы используют optimistic concurrency. Сначала получите ETag всей секции, затем передайте его без изменений в If-Match:
Скопируйте значение заголовка ETag, включая двойные кавычки:
Успешная mutation возвращает новый ETag. Использование старого ETag возвращает 409 section_conflict; повторите GET, проверьте актуальное состояние и осознанно повторите изменение. Все поля request body проверяются строго, а число подписок ограничено 100.
Проверка сохранённой подписки не создаёт новую ревизию:
Ответ содержит section_etag, по которому клиент может определить, не изменилась ли секция с момента чтения.
Диагностика
Проверьте следующие сообщения структурированных логов:
webhook deliveredна уровне debug — receiver вернул2xx;webhook delivery failedна уровне warning — сеть, timeout или ответ не2xx;webhook notifications droppedна уровне warning — очередь подписки переполнена; полеcountсодержит число потерь за интервал.
Если test endpoint успешен, а рабочее событие отсутствует, проверьте method запроса, экосистему, публичное имя repository, enabled, список events, HTTP status ответа OSA Proxy и факт классификации запроса как файла или пакета.
