Интеграция с JFrog Artifactory

OSA Proxy поддерживает статические маршруты к репозиториям JFrog Artifactory и автоматическое обнаружение репозиториев через Artifactory inventory API. На этой странице собраны настройка discovery, формирование клиентских URL, передача repository context и особенности ответов о блокировке.

Автоматическое обнаружение репозиториев

Runtime discovery получает список репозиториев Artifactory и создаёт для подходящих записей динамические маршруты. Репозитории не нужно перечислять по одному в статических секциях npm, maven, pypi и других экосистем.

Обнаружение выполняется при запуске и затем периодически. Для каждого repository OSA Proxy определяет экосистему, строит upstream URL и применяет первое подходящее правило из repository-routing.

Изменение конфигурации

Когда Configuration Store выключен, изменения в osa-proxy.yml требуют перезапуска. При включённом Configuration Store управляемые поля discovery — enabled, repository-types, repository-routing, route-mode и интервал обновления — можно менять через Admin API без перезапуска. Credentials и base-url остаются bootstrap-параметрами и требуют перезапуска.

Требования к доступу

Создайте техническую учётную запись или access token, которым разрешены:

  • GET /artifactory/api/repositories для получения inventory;
  • просмотр репозиториев, которые должны попасть в ответ API.

В следующих командах ARTIFACTORY_BASE_URL — platform URL без /artifactory, например https://jfrog.example.com.

Проверка Basic auth:

curl --fail --user "$ARTIFACTORY_USERNAME:$ARTIFACTORY_PASSWORD" \
  "$ARTIFACTORY_BASE_URL/artifactory/api/repositories"

Проверка access token:

curl --fail \
  --header "Authorization: Bearer $ARTIFACTORY_ACCESS_TOKEN" \
  "$ARTIFACTORY_BASE_URL/artifactory/api/repositories"

Credentials discovery-клиента используются только для inventory API. OSA Proxy не добавляет их автоматически в запросы пакетов к найденным upstream-репозиториям. Доступ к приватным пакетам настройте отдельно, например через входящие credentials клиента, anonymous read или доверенный reverse proxy.

Конфигурация discovery

artifactory:
  enabled: true
  base-url: https://jfrog.example.com
  username: ${ARTIFACTORY_USERNAME:}
  password: ${ARTIFACTORY_PASSWORD:}
  access-token: ${ARTIFACTORY_ACCESS_TOKEN:}
  route-mode: native
  repository-types:
    - remote
    - virtual
  refresh:
    interval: 1m
  repository-routing:
    - name: npm-consumers
      package-type: npm
      name-regex: '^npm-.*$'
      scan-manifest: true
      scan-package: true
      remove-blocked-versions: true
      work-mode: strict_wait
      url-encoded-config: true
      file-type-filter: {}
    - name: swift-consumers
      package-type: swift
      name-regex: '^swift-.*$'
      scan-manifest: true
      scan-package: true
      work-mode: strict_wait
    - name: cran-consumers
      package-type: r
      name-regex: '^cran-.*$'
      scan-package: true
      work-mode: strict_wait

Выберите ровно один способ аутентификации:

  • Basic auth — заполнены и username, и password, а access-token пуст;
  • Bearer token — заполнен access-token, а username и password пусты.

base-url задаётся без произвольного path. Значения https://jfrog.example.com и https://jfrog.example.com/artifactory нормализуются к Artifactory root.

Допустимые classes в repository-types: local, remote, virtual, federated.

Выбор репозиториев

Для каждого package type требуется отдельное правило. Wildcard в package-type не поддерживается.

Чтобы подключить все репозитории одного типа, опустите name-regex:

repository-routing:
  - name: all-npm
    package-type: npm
    scan-manifest: true
    scan-package: true

Для фильтрации по key используется Go regexp (RE2), а не glob. Рекомендуется ставить якоря ^ и $:

repository-routing:
  - name: team-a-npm
    package-type: npm
    name-regex: '^team-a-npm-(remote|virtual)$'

Правила одного package type проверяются сверху вниз. Если repository соответствует нескольким правилам, применяется первое. Узкие regexp размещайте выше общего fallback-правила.

Поля scan-manifest, scan-package, remove-blocked-versions, work-mode, url-encoded-config, distro и file-type-filter имеют тот же смысл, что и в статической конфигурации экосистемы. Неподдерживаемая комбинация приводит к ошибке конфигурации или отклонению discovery snapshot.

Поддерживаемые форматы

Artifactory discovery поддерживает:

npm, maven, nuget, pypi, composer, cocoapods, swift, ruby, r, conan, go, hex, debian, alpine, rpm.

Форматы inventory gems, yum и CRAN нормализуются в ruby, rpm и r. Docker и неизвестные package types автоматически не подключаются.

Для Hex с scan-manifest: true задайте общий RSA-ключ OSA Proxy через hex.signing-private-key или hex.signing-private-key-file:

hex:
  signing-private-key: ${HEX_SIGNING_PRIVATE_KEY:}

artifactory:
  repository-routing:
    - name: hex-consumers
      package-type: hex
      name-regex: '^hex-.*$'
      scan-manifest: true
      scan-package: true

OSA Proxy получает публичный ключ Artifactory по upstream URL с суффиксом /public_key, проверяет upstream-подпись, применяет политики и подписывает изменённый manifest своим RSA-ключом. Публичную часть ключа OSA Proxy клиент получает по /{dynamic-route}/public_key. При выключенном scan-manifest подписанные metadata проксируются без изменения. Способы передачи ключа и приоритет переменных описаны в настройке Hex.

Клиентские маршруты

При route-mode: native клиентский путь повторяет Artifactory URL:

  • /artifactory/{key} для Maven, R, Debian, Alpine и RPM;
  • /artifactory/api/npm/{key}, /artifactory/api/pypi/{key}, /artifactory/api/swift/{key} и аналогичные API paths для остальных форматов.

Например, найденный npm repository с key npm-remote доступен через:

https://osa-proxy.example.com/artifactory/api/npm/npm-remote/

Клиенту или reverse proxy достаточно заменить host Artifactory на host OSA Proxy, сохранив path.

При route-mode: flat используется legacy-маршрут /{key}. Поле route-prefix в отдельном routing rule имеет приоритет над route-mode; итоговый путь имеет вид /{route-prefix}/{key}.

Статические маршруты из секций экосистем имеют наивысший приоритет. Если путь найденного repository конфликтует со статическим маршрутом, динамический маршрут пропускается, а остальные найденные репозитории продолжают работать.

Repository context в URL

Параметр url-encoded-config: true разрешает передать в запросе URL-safe Base64 metadata с адресом repository manager, именем repository и пользователем. Это нужно для применения политик CodeScoring, привязанных к конкретному Artifactory repository context.

Для native route encoded-сегмент размещается после полного repository path:

/artifactory/api/npm/npm-remote/{base64-context}/{package-path}

Формат объекта и примеры кодирования описаны в разделе Настройка Base64 URL.

Ответы о блокировке

Запросы с заголовком Origin-Artifactory или X-Artifactory-Originated получают JFrog Curation-compatible JSON, необходимые curation headers и HTTP 403. Значение заголовка не анализируется — режим включается по наличию заголовка.

Artifactory возвращает клиенту свой стандартный ответ и не передаёт пользовательский HTTP status line от OSA Proxy. Поэтому codescoring.enable-status-line не следует использовать как способ показать причину блокировки пользователю Artifactory.

Обновление и диагностика

Первый inventory sync выполняется при старте. Последующие sync запускаются через refresh.interval с jitter до 10%. Новые и удалённые репозитории подхватываются без перезапуска.

При ошибке HTTP, декодирования или построения маршрутов OSA Proxy сохраняет последний успешный snapshot. Успешный пустой inventory удаляет все динамические маршруты Artifactory. Snapshot хранится только в памяти; после рестарта при недоступном Artifactory доступны только статические маршруты.

Endpoint /healthz проверяет процесс OSA Proxy, но не состояние discovery. Используйте метрики:

  • artifactory_discovery_syncs_total;
  • artifactory_discovery_sync_duration_seconds;
  • artifactory_discovery_last_success_timestamp_seconds;
  • artifactory_discovery_active_repositories;
  • artifactory_discovery_repository_changes_total.
curl --fail http://localhost:8080/metrics \
  | grep '^artifactory_discovery_'

Настройка второго поддерживаемого manager описана в разделе Интеграция с Nexus Repository.

Страница была полезна?