SecurityFlow Кабинет лицензий , откроется в новой вкладке

Документация / Сканирование

Свой и коммерческий сканер

Обновлено 20 октября 2026

Radar запускает любой сканер, упакованный в образ Docker, если тот пишет отчёт в файл. Подключение состоит из двух частей:

  • джоба в Radar - как запустить сканер и где взять отчёт;
  • сканер в Core с импортёром - как разобрать отчёт в уязвимости.

Связывает их переменная джобы SCAN_TYPE: её значение должно точно совпадать с названием сканера в Core.

Перед началом

  • Лицензия с доступом к Radar. Свой импортёр - платная функция, см. Лицензирование.
  • Роль в Core: "Глобальные настройки" - "Изменение" (сканер и импортёр), "Radar" - "Изменение" (последовательность).
  • Пример отчёта сканера в формате JSON.
  • Образ сканера в реестре, доступном демону Docker воркера Radar.

Требования к образу

Требование Почему
В образе есть sh команда джобы выполняется как sh -c "<Команда запуска>"
ENTRYPOINT не мешает sh -c иначе включите в джобе "Перезаписывать Энтрипоинт Контейнера"
Сканер читает код из /code это рабочий каталог джобы, туда Code Downloader клонирует репозиторий
Сканер работает от root Radar запускает контейнер с user=root независимо от USER в образе
Образ доступен демону Docker воркера образ скачивается перед каждым запуском. Закрытый реестр - "Настройки" → "Уч. Данные Docker" и поле "Учетные данные" в джобе

Требования к отчёту

Требование Почему
Файл /data/$REPORT_FILE_NAME воркер читает ровно этот путь. Файл в другом каталоге в Core не уйдёт
Имя без подкаталогов REPORT_FILE_NAME - имя файла, а не путь
Один отчёт на джобу одна джоба отправляет один файл с одним SCAN_TYPE. Несколько отчётов - несколько джоб
Текст в UTF-8 Core читает файл как текст UTF-8
Укладывается в 20 секунд отправки воркер собирает файл целиком в памяти и отправляет с таймаутом 20 секунд. Radar размер не ограничивает, nginx Core принимает запрос до 4 ГБ

Если сканер возвращает ненулевой код при найденных уязвимостях, оставьте в джобе включённым "Разрешить падение". Тогда отчёт всё равно уйдёт в Core, а пайплайн продолжится.

Подключение

1. Заведите сканер в Core

  1. Откройте "Глобальные настройки" → "Сканеры", вкладка "Свои сканеры".
  2. Нажмите "Создать сканер".
  3. Заполните поля:
Поле Что задаёт
"Название" имя сканера. Это значение SCAN_TYPE в джобе, регистр и пробелы важны
"Тип сканера" "Секреты", "SAST", "SCA", "DAST", "Инфра", "Облако" или "Не указан". Используется в метриках и фильтрах
"Теги" необязательно

API: POST /api/v1/scanners/ с полями name и scanner_type (0 - не указан, 1 - секреты, 2 - SAST, 3 - SCA, 4 - DAST, 5 - инфраструктура, 6 - облако).

2. Настройте разбор отчёта

  1. В карточке сканера откройте "Настройка логики разбора отчётов".
  2. Нажмите "Настроить свою логику разбора".
  3. Пройдите мастер: загрузите пример отчёта, укажите путь к списку уязвимостей и поля уязвимости. Для отчёта в формате SARIF мастер предложит "Применить стандартную структуру".
  4. Нажмите "Загрузить предпросмотр" и убедитесь, что уязвимости и ассеты разобраны без ошибок.
  5. Сохраните конфигурацию.

Подробно о мастере - Импорт отчётов. Предпросмотр через API: POST /api/v1/custom-importer/parse-report/ с полями report_config и report.

3. Создайте джобу в Radar

  1. В Radar откройте "Джобы" → "Создать Джобу".
  2. Заполните поля:
Поле Значение
"Имя джобы" уникальное имя, например My Scanner
"Образ" registry.example.ru/my-scanner:1.0
"Команда запуска" команда, которая пишет отчёт в /data/$REPORT_FILE_NAME
"Тип джобы" "Сканнер"
"Переменные окружения:" REPORT_FILE_NAME, SCAN_TYPE и переменные ассета, см. ниже
"Таймаут джобы (в минутах)" с запасом к обычному времени скана
"Разрешить падение" включено, если сканер возвращает ненулевой код при находках
"Учетные данные" если образ в закрытом реестре

Переменные:

Переменная Значение Свойства
REPORT_FILE_NAME my-scanner.json "Видимая"
SCAN_TYPE My Scanner - название сканера в Core "Видимая"
REPOSITORY пусто, подставит Core "Обязательна для запуска Джобы", если сканер работает с кодом
SEC_CODE_FOLDER пусто подкаталог /code для сканирования
ключи и токены сканера значения "Скрытая"

Ту же джобу можно загрузить файлом через "Импорт Джоб":

[
  {
    "name": "My Scanner",
    "docker_credentials_id": null,
    "user_settings": {
      "image": "registry.example.ru/my-scanner:1.0",
      "run_command": "my-scanner scan --source /code/$SEC_CODE_FOLDER --format json --output /data/$REPORT_FILE_NAME",
      "environment_variables_dict": "[{\"name\":\"REPORT_FILE_NAME\",\"value\":\"my-scanner.json\",\"masked\":false,\"required\":false},{\"name\":\"SCAN_TYPE\",\"value\":\"My Scanner\",\"masked\":false,\"required\":false},{\"name\":\"SEC_CODE_FOLDER\",\"value\":\"\",\"masked\":false,\"required\":false},{\"name\":\"REPOSITORY\",\"value\":\"\",\"masked\":false,\"required\":true}]",
      "use_pipeline_volume": false,
      "type": "SCANNER",
      "allow_failure": true,
      "timeout": 30,
      "overwrite_entrypoint": false
    }
  }
]

Формат импорта - Джобы и последовательности.

4. Добавьте джобу в последовательность

  1. В Core откройте "Radar" → "Последовательности" и выберите последовательность или создайте новую.
  2. Добавьте джобу: в поле "Джоб Radar" укажите имя джобы точно как в Radar.
  3. Для сканеров кода поставьте джобу после Code Downloader.

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

5. Проверьте

  1. Запустите аудит тестового ассета с этой последовательностью.
  2. В Radar откройте пайплайн и лог джобы ("Логи").
  3. В Core откройте аудит: у сканера появилась запись с числом добавленных находок, сами находки - в "Уязвимости".

При успешной доставке в логе джобы есть строки:

Accessing /data/my-scanner.json.
Got report file.
Using SCAN_TYPE: My Scanner as scanner_name
Portal response with code: 202

Коммерческий сканер

Коммерческий сканер подключается так же. Учтите:

  • лицензионный ключ и токены сервера сканера передавайте в скрытых переменных джобы. Видимые переменные печатаются в лог;
  • если скан выполняется на сервере сканера, команда джобы запускает CLI клиента: отправляет задание, ждёт результата и сохраняет отчёт в /data. Задайте "Таймаут джобы" с учётом очереди на сервере сканера;
  • откройте сетевой доступ с узлов сканирования Radar к серверу сканера;
  • один и тот же дефект, найденный коммерческим и открытым сканером, Core склеит, только если критерии дедупликации не учитывают сканер. По умолчанию критерий "Тот же сканер" включён, см. Дедупликация.

Диагностика

В логе джобы Причина Что сделать
Missing required variables: [...] пустая обязательная переменная передайте значение или снимите обязательность
Failed to access scanning results: docker.NotFound нет файла /data/$REPORT_FILE_NAME сверьте путь в команде с REPORT_FILE_NAME; проверьте, что сканер не упал до записи отчёта
Portal response with code: 400 Core не принял запрос, чаще всего SCAN_TYPE не совпадает с названием сканера сверьте SCAN_TYPE с "Глобальные настройки" → "Сканеры"
Portal response with code: 403 у пользователя, запустившего аудит, нет права "Уязвимости" - "Изменение" выдайте право или запускайте от другого пользователя
The variables required to send the report to the portal: (PORTAL_IMPORT_URL, PORTAL_TOKEN) were not provided. пайплайн запущен напрямую в Radar без переменных Core запустите аудит из Core или передайте переменные, см. Запуск напрямую в Radar
ответ 202, но находок нет импортёр не разобрал отчёт проверьте конфигурацию разбора предпросмотром на реальном отчёте
контейнер завершается сразу с ошибкой запуска команды в образе нет sh или ENTRYPOINT перехватывает команду включите "Перезаписывать Энтрипоинт Контейнера" или соберите образ с sh