Архитектура¶
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 (Проект)¶
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 (Политика очистки)¶
Варианты установки¶
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 позволяет масштабировать сервис и пересоздавать поды без потери данных.