Skip to content

Ops / Security / Observability Audit — SoccerPredictAI

Date: 2026-04-24 Auditor: GitHub Copilot (Claude Sonnet 4.6) Scope: K8s deployment, secrets, CORS, HA, Prometheus, Grafana, drift monitoring Method: анализ k8s/helm/ns_soccer-api/, src/app/main.py, src/app/metrics.py, src/monitoring/, src/app/config/security.py


1. Deployment и High Availability

1.1 Replicas

Компонент Replicas SPOF
FastAPI 1 ✅ SPOF
Celery worker-api 1 ✅ SPOF
Celery worker-ml 1 ✅ SPOF
RabbitMQ 1 ✅ SPOF
Redis 1 ✅ SPOF
PostgreSQL не в этом Helm chart ?
MinIO не в этом Helm chart ?

⚠️ P1: Все компоненты replicas=1. Любой pod failure → сервис недоступен. Нет настроенного кластеринга для RabbitMQ или Redis.

1.2 Autoscaling

fastapi.autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 3

HPA템플릿 существует (hpa.yaml: CPU 70%, Memory 80%), но отключён в values.yaml.

⚠️ P2: Autoscaling определён в шаблонах, но не включён.

1.3 Resource limits

Компонент Requests Limits
FastAPI 256Mi / 100m 1Gi / 500m
Celery-ML 256Mi / 100m 2Gi / 500m
Celery-API 256Mi / 100m 1Gi / 500m
RabbitMQ 1Gi storage
Redis 1Gi storage

✅ Limits определены. ML worker получает 2Gi — достаточно для sklearn модели.

1.4 Probes

# FastAPI:
livenessProbe:
  httpGet: /healthcheck/
  initialDelaySeconds: 45
  periodSeconds: 10

readinessProbe:
  httpGet: /healthcheck/
  initialDelaySeconds: 10
  periodSeconds: 5

✅ liveness и readiness probes настроены для FastAPI.

⚠️ P2: Celery workers используют тот же же deployment.yaml — нужно проверить, используют ли они celery inspect ping или аналог как liveness probe (типичная проблема).

1.5 Storage

PVC для RabbitMQ и Redis: storageClassName: manual — предполагает наличие HostPath persistent volume. На single-node окружении это приемлемо, но неустойчиво при миграции.


2. Security Audit

2.1 API Authentication

Endpoint group Аутентификация Метод
/sources/* (scraping, export) ✅ X-Token header FASTAPI_HEADER_TOKEN
/predict/* ❌ нет
/monitoring/* ❌ нет
/livescores/ ❌ нет
/healthcheck/ ❌ нет Открытый по замыслу
/metrics (Prometheus) ❌ нет Открытый по замыслу

⚠️ P1: Prediction endpoints не защищены аутентификацией. ⚠️ P1: Monitoring endpoints (/monitoring/celery/*) открыты — раскрывают внутреннюю топологию Celery.

2.2 CORS

# src/app/main.py
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # ← WILDCARD
    ...
)

⚠️ P1: CORS allow_origins=["*"] — принимает запросы с любого домена. Уместно только для публичного read-only API.

2.3 Secrets Management

Аспект Статус
SOPS + age шифрование values-dev.enc.yaml
Секреты не в открытом git
values.yaml — только заглушки (пустые строки)
Токены через env vars / pydantic-settings
.env файлы — через pydantic BaseSettings

✅ Secrets management корректен — SOPS для K8s, pydantic-settings для приложения.

2.4 Token передача в UI

# api_client.py
params = {**(params or {}), "token": self._token}

⚠️ P2: Token как query param попадает в access logs, browser history, server-side request logs.


3. Observability

3.1 Prometheus Metrics

Метрика Тип Реализована
request_count Counter
request_latency_seconds Histogram
prediction_count Counter
prediction_timeouts_total Counter
prediction_latency_seconds Histogram
inference_latency_seconds Histogram
prediction_confidence Histogram (per outcome)
model_info Gauge

✅ Хорошее покрытие метриками. Inference latency измеряется отдельно от prediction latency.

3.2 Prometheus scrape endpoints

Endpoint Port Notes
/metrics 8000 FastAPI (PrometheusMiddleware)
:9091/metrics 9091 Celery ML worker (отдельный HTTP server)

✅ Prometheus scrape настроен для обоих компонентов.

3.3 Grafana

⚠️ P1 (Planned, Not Implemented): Grafana не задеплоена. Прометей метрики собираются, но нет дашбордов.

3.4 Drift Monitoring

Аспект Статус
src/monitoring/ директория Пустая
Evidently интеграция Не реализовано
Feature drift detection Не реализовано
Prediction confidence tracking ✅ Метрика есть, но нет alerting

⚠️ P1 (Planned, Not Implemented): src/monitoring/ пуст. Drift detection не реализован.

3.5 Logging

logging (не print) во всех production модулях — соответствует стандартам.


4. Findings

ID Severity Описание
OPS-01 P1 Все компоненты replicas=1 — нет HA, любой pod failure ведёт к downtime
OPS-02 P1 /predict/* и /monitoring/* endpoints не защищены аутентификацией
OPS-03 P1 CORS allow_origins=["*"] — принимает запросы с любого домена
OPS-04 P1 Grafana не задеплоена — Prometheus метрики собираются, но нет дашбордов
OPS-05 P1 src/monitoring/ пуст — drift detection не реализован
OPS-06 P2 FastAPI autoscaling HPA определён, но отключён (enabled: false)
OPS-07 P2 Celery worker liveness probe — нужно проверить, есть ли celery inspect ping probe
OPS-08 P2 storageClassName: manual (HostPath) для RabbitMQ/Redis PVC — непереносимо