Перейти к содержанию

Архитектура

CodeScoring.Save построен на микросервисной архитектуре. Backend API и контур аутентификации / авторизации вынесены в отдельные сервисы: Save API service и cs-auth (Auth/RBAC service).

Технологический стек

  • Язык разработки: Go 1.25+.
  • Хранилище метаданных: PostgreSQL 14+ (рекомендуется для production) или SQLite 3.x.
  • Объектное хранилище: S3-совместимое (MinIO, AWS S3, Yandex Object Storage) или локальная файловая система.
  • Аутентификация: RSA-2048 JWT с JWKS, выпускаемый cs-auth и локально валидируемый Save через публичный ключ.

Архитектурная диаграмма

flowchart TB
    UI["Web UI · React"]
    PM["Пакетные менеджеры<br/>npm · mvn · docker · nuget · pypi · go"]
    LB["Load Balancer / Ingress"]

    SAVE["<b>Save API service</b><br/>stateless · pods 1..N"]
    AUTH["<b>cs-auth</b> (Auth / RBAC)<br/>stateless · pods 1..N<br/>общий RSA-ключ"]

    DB[("<b>Metadata DB</b><br/>см. примечание ниже")]
    OBJ[("<b>Object Storage</b><br/>S3-совместимое / локальная ФС")]

    UI --> LB
    PM --> LB
    LB --> SAVE
    LB -- "/v2/token (Docker auth flow)" --> AUTH

    SAVE -- "авторизация действий · JWKS · события для аудита" --> AUTH
    SAVE --> DB
    SAVE --> OBJ
    AUTH --> DB

О схеме базы данных

В развёртывании с PostgreSQL оба сервиса могут делить один экземпляр БД и одну схему; данные разделены префиксами имён таблиц. В развёртывании с SQLite у каждого сервиса свой отдельный файл базы.

Компоненты системы

Save API service

Основной backend-сервис, обрабатывающий входящие запросы к репозиториям и административному API.

Функции:

  • Обработка HTTP/HTTPS запросов от пакетных менеджеров и веб-интерфейса.
  • Валидация токенов и интеграция с выделенным Auth/RBAC service.
  • Маршрутизация запросов к storage backend.
  • Интеграция с CodeScoring.OSA через OSA Proxy для сканирования артефактов при маршрутизации загрузок через прокси.
  • Применение политик безопасности и политик очистки.
  • Структурированное логирование и экспорт метрик в Prometheus.

Технические характеристики:

  • Stateless-архитектура для горизонтального масштабирования.
  • Graceful shutdown при обновлении.
  • Health checks для Kubernetes.

Auth/RBAC service

Выделенный сервис аутентификации и авторизации, разворачиваемый отдельно от Save API service.

Функции:

  • Аутентификация пользователей и сервисных аккаунтов.
  • Выпуск и обновление JWT-токенов (RSA-2048, alg=RS256).
  • Управление ролями и разрешениями (RBAC) на уровнях global / project / repository.
  • Управление API keys, robot accounts и project membership.
  • Аудит операций, связанных с доступом и общесистемными событиями.
  • Internal API для взаимодействия с Save API service.
  • OCI Distribution Spec token endpoint для Docker / Helm / oras-клиентов.

Технические характеристики:

  • Отдельная кодовая база и отдельная точка входа.
  • Собственная схема в PostgreSQL при общем экземпляре БД, либо отдельный SQLite-файл.
  • Горизонтальное масштабирование независимо от Save API service.
  • Обязательное условие масштабирования: все реплики должны делить один и тот же RSA-ключ для подписи JWT.

Storage Backend

Подсистема хранения артефактов:

  • Metadata Store — PostgreSQL или SQLite для хранения метаданных.
  • Blob Store — объектное хранилище для артефактов: S3-совместимое или filesystem.

Операции: сохранение и извлечение артефактов, управление версиями, генерация контрольных сумм.

Background Workers

Фоновые процессы для выполнения отложенных задач:

  • Политики очистки — удаление устаревших артефактов по расписанию.
  • Фоновые операции с метаданными.
  • Асинхронная отправка аудит-событий в cs-auth.

Web UI

Веб-интерфейс для управления проектами, репозиториями, артефактами и настройками доступа. Общее описание возможностей модуля приведено на странице Функциональные характеристики.

Взаимодействие сервисов

  • Внешние клиенты (Web UI и пакетные менеджеры) обращаются только к Save API service через ingress; cs-auth напрямую снаружи кластера не доступен
  • Save API service делегирует аутентификацию, проверку ролей и выпуск токенов в Auth/RBAC service
  • Оба сервиса могут использовать отдельные или общий экземпляр PostgreSQL, но работают они в отдельных схемах/базах данных
  • Save API service напрямую работает с metadata store и object storage; cs-auth работает только с metadata store и не имеет доступа к object storage
  • Save обращается к cs-auth в нескольких случаях:
    • Проксирование части административного API — Save форвардит запросы, не обрабатывая их сам
    • Проверка учётных данных, отсутствующих в локальном кэше пода — (Basic Auth, API key, NuGet API key, NPM token, Docker token)
    • Оповещение о событиях для аудита - единый журнал событий для всех сервисов
  • Все internal-эндпоинты дополнительно защищены shared secret.
  • На горячем пути Save валидирует Bearer JWT локально, используя кэшированный публичный RSA-ключ JWKS без сетевого вызова в cs-auth.

Модель данных

Основные сущности

Project (Проект)

- ID
- Name
- Description
- Owner
- Created/Updated timestamps

Repository (Репозиторий)

- ID
- Project ID
- Name
- Type (proxy/hosted)
- Format (maven, npm, docker, nuget, pypi, go, raw)
- Configuration
- Storage Backend
- Cleanup Policies
- Created/Updated timestamps

Artifact (Артефакт)

- ID
- Repository ID
- Group/Namespace
- Name
- Version
- Format-specific metadata
- Size
- Checksums (MD5, SHA1, SHA256)
- Upload date
- Last accessed

User (Пользователь)

- ID
- Username
- DisplayName
- Email
- PasswordHash (bcrypt)
- IsActive
- AuthSource   (local / ldap / oidc)
- LastLoginAt
- Created/Updated timestamps

Role / Robot account (Роль или сервисный аккаунт)

- ID
- Name
- Description
- Permissions (global / project / repository scopes)
- IsAdmin
- IsSystem
- API keys (only for robot accounts)
- Created/Updated timestamps

APIKey (API-ключ)

- ID
- UserID            (FK на user с IsService=true)
- KeyPrefix         (первые 12 hex-символов plaintext-ключа — индекс для O(1)-поиска)
- KeyHash           (bcrypt(plaintext))
- Description
- ExpiresAt         (NULL = бессрочный)
- LastUsedAt
- CreatedAt

Полный plaintext-ключ возвращается клиенту единожды при создании.

Cleanup Policy (Политика очистки)

- ID
- Name
- Type (cleanup/security)
- Rules
- Repositories
- Enabled
- Created/Updated timestamps

Варианты установки

CodeScoring.Save поддерживает несколько профилей установки. Требования, различия между профилями и порядок развертывания описаны в разделе Варианты установки.

Безопасность

Аутентификация и авторизация

  • JWT tokens для API, выпускаемые Auth/RBAC service
  • Basic Auth / API keys для пакетных менеджеров и service accounts
  • Ролевая модель (RBAC) с тремя scope'ами (global / project / repository), управляемая выделенным Auth/RBAC service
  • Межсервисная валидация токенов через JWKS-эндпоинт

Способы аутентификации со стороны клиента подробно описаны в разделе Аутентификация.

Шифрование данных

Сами сервисы Save и cs-auth не выполняют шифрование на уровне приложения; используются возможности нижележащих компонентов:

  • Encryption at rest обеспечивается выбранным object storage (S3 server-side encryption, MinIO encryption-at-rest) и PostgreSQL (через TDE-расширения или volume-level шифрование).
  • Encryption in transit обеспечивается TLS на ingress / load balancer и в межсервисных соединениях.
  • Пароли пользователей и API-ключи robot-аккаунтов хранятся как bcrypt-хэши в cs-auth.

Аудит

  • Полное логирование всех операций — единый журнал, в который пишут оба сервиса.
  • Экспорт в машинно-читаемый формат (JSON) и HTML. Максимум 10 000 записей за один экспорт.
  • Поддерживаемые фильтры списка/экспорта: from, to, username, action, resource_type, q, user_id. В web-UI доступен только поиск по имени пользователя, типу ресурса и действию.

Производительность

Оптимизации

  • Кэширование:
  • In-process TTL-кэш credential → PermissionSet в каждом поде Save API service — устраняет round-trip в cs-auth при повторных запросах с теми же учётными данными
  • Локальная валидация Bearer JWT по публичному ключу JWKS — без сетевого вызова в cs-auth на горячем пути. JWKS обновляется в фоне периодически.

  • Connection pooling:

  • Пул соединений к БД
  • Переиспользование HTTP клиентов к upstream-репозиториям

  • Параллельная обработка:

  • Concurrent uploads / downloads через горутины.
  • Batch (bulk) operations API

  • Streaming больших файлов:

    • Артефакты передаются через MultiWriter без буферизации целиком в памяти.
    • Атомарная запись на диск через temp-file rename, чтобы избежать повреждения при конкурентной записи.

Целевые показатели

Для базовой инсталляции:

  • Latency (p95): < 100ms для cached requests
  • Throughput: 300+ requests/sec
  • Concurrent uploads: 100+
  • Max artifact size: 5 GB

Масштабирование

Горизонтальное масштабирование

  • Save API service — stateless, масштабируется добавлением реплик.
  • Auth/RBAC service — stateless, масштабируется добавлением реплик. Обязательное условие: все реплики должны использовать один и тот же RSA-ключ для подписи JWT.
  • PostgreSQL — масштабируется вертикально, при необходимости используются read-реплики.
  • Объектное хранилище — масштабируется средствами провайдера: S3 или MinIO в кластере.

Вертикальное масштабирование

  • Увеличение ресурсов подов.
  • Увеличение ресурсов PostgreSQL.
  • Расширение объектного хранилища.

Мониторинг и наблюдаемость

Метрики (Prometheus)

Save экспортирует метрики в формате OpenTelemetry с Prometheus exporter'ом.

HTTP-метрики:

  • http_requests_total{method,path,status} — счётчик HTTP-запросов.
  • http_request_duration_seconds{method,path,status} — гистограмма latency.
  • http_requests_active — gauge активных запросов.

Метрики операций:

  • storage_operations_total{operation,backend,success} — операции с хранилищем.
  • artifact_uploads_total{artifact_type,repository} — загрузки артефактов.
  • artifact_downloads_total{artifact_type,repository} — скачивания артефактов.
  • proxy_requests_total{artifact_type,repository,cache_hit,success} — proxy-запросы. Cache hit rate вычисляется как rate(proxy_requests_total{cache_hit="true"}[5m]) / rate(proxy_requests_total[5m]).
  • cleanup_operations_total{policy_type,repository,artifacts_deleted,success} — операции очистки.

Логирование

  • Структурированные логи в формате JSON (или text, по конфигурации).
  • Уровни: debug, info, warn, error.
  • Вывод: stdout, stderr или файл.
  • Совместимы с любым log-aggregator'ом (ELK, Loki, Vector), которые умеют JSON.

Доступность и устойчивость

CodeScoring.Save не реализует автоматическое переключение при отказе, восстановление на конкретный момент времени и встроенное резервное копирование самостоятельно. Эти возможности обеспечиваются стандартными средствами инфраструктуры, в которой развёрнут сервис:

  • Несколько реплик Save и cs-auth в Kubernetes за балансировщиком нагрузки обеспечивают доступность при отказе одного из подов.
  • Репликация PostgreSQL и резервное копирование базы данных настраиваются средствами PostgreSQL-оператора или managed-сервиса.
  • Снапшоты и репликация объектного хранилища выполняются средствами S3-совместимого хранилища.
  • Многоузловой Kubernetes-кластер обеспечивает устойчивость к отказу отдельного узла.

Save не теряет данные при перезапуске, потому что всё состояние хранится во внешних компонентах: метаданные — в базе данных, артефакты — в объектном хранилище. Stateless-архитектура Save позволяет масштабировать сервис и пересоздавать поды без потери данных.

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