Продвинутый

Kairos — открытая платформа для оценки рисков

Алексей Кузнецов
Алексей Кузнецов
Системный администратор4 ноября 2026 г.12 мин чтения

Обзор Kairos — открытой платформы для оценки рисков и предотвращения мошенничества. Разбор архитектуры, развёртывание через Docker Compose и интеграция.

Kairos — открытая платформа для оценки рисков

Обзор Kairos — открытой платформы для оценки рисков и предотвращения мошенничества. Разбор архитектуры, развёртывание через Docker Compose и интеграция.

Зачем нужна открытая платформа для оценки рисков

Когда речь заходит о предотвращении мошенничества, большинство команд смотрят в сторону коммерческих платформ вроде Sift или Sardine. Проблема не в цене — проблема в том, что вы покупаете чёрный ящик с чужими правилами и чужими данными. Открытая платформа вроде Kairos даёт другое: вы видите код, контролируете обучение модели и храните данные на своём оборудовании. Для инженера это значит предсказуемость конфигураций и возможность аудита каждого решения, которое принимает система.

Недостаток размеченных данных в коммерческих решениях

Коммерческие платформы обучаются на агрегированных данных тысяч клиентов. Это звучит как преимущество, но на практике означает, что модель не знает специфики вашего бизнеса. Если вы работаете с нишевым рынком — например, продаёте цифровые подписки или предоставляете B2B-доступ к API — паттерны мошенничества у вас будут отличаться от типичных кейсов интернет-магазинов. Коммерческое решение может пропустить атаку, которая для вашей команды очевидна, или заблокировать легитимного пользователя из-за незнакомого паттерна.

Ещё один момент: размеченные данные, которые вы накапливаете вручную (подтверждённые мошеннические транзакции, ошибки модерации, апелляции пользователей), остаются внутри коммерческой платформы. Вы не можете выгрузить их и переобучить модель под себя. Вы платите за доступ к API, а не за владение данными.

Пример события в формате JSON:

json
{
  "event_id": "evt_7f3a9b2c",
  "timestamp": "2024-01-15T14:22:01Z",
  "user_id": "usr_12345",
  "action": "payment_attempt",
  "amount": 4500,
  "currency": "RUB",
  "ip": "185.220.101.44",
  "device_fingerprint": "a1b2c3d4e5f6",
  "label": "fraud",
  "source": "manual_review"
}

Без доступа к таким данным в открытом виде вы не сможете проверить, почему система приняла то или иное решение. В открытой платформе код и данные находятся под вашим контролем, и вы можете добавить собственные признаки в модель без согласия поставщика.

Если вы ещё не работали с Docker Compose, стоит ознакомиться с циклом статей про инструменты инженера: Инструменты инженера: от Docker до Kubernetes.

Отличие от Sift, Sardine и аналогов

Sift, Sardine и подобные сервисы построены по модели SaaS: вы отправляете события через API, получаете оценку риска и не знаете, как она вычислена. Модель закрыта, правила обновляются без вашего участия, а данные хранятся на серверах поставщика. Это удобно для быстрого старта, но становится проблемой, когда нужна прозрачность или соответствие внутренним требованиям безопасности.

Открытая платформа вроде Kairos работает иначе. Код открыт, вы разворачиваете сервисы на своём оборудовании и управляете конфигурацией сами. Ниже пример того, как может выглядеть файл развёртывания для такого стека:

yaml
version: "3.8"

services:
  db:
    image: postgres:15-alpine
    volumes:
      - ./data/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: kairos
      POSTGRES_USER: kairos
      POSTGRES_PASSWORD: ${DB_PASSWORD}

  redis:
    image: redis:7-alpine
    volumes:
      - ./data/redis:/data

  api:
    image: kairos/api:latest
    depends_on:
      - db
      - redis
    environment:
      DATABASE_URL: postgres://kairos:${DB_PASSWORD}@db:5432/kairos
      REDIS_URL: redis://redis:6379
    ports:
      - "8080:8080"

  worker:
    image: kairos/worker:latest
    depends_on:
      - db
      - redis
    environment:
      DATABASE_URL: postgres://kairos:${DB_PASSWORD}@db:5432/kairos
      REDIS_URL: redis://redis:6379

Это пример, а не готовый конфиг Kairos — структура сервисов может отличаться. Главное отличие в подходе: вы не зависите от внешнего API, можете аудитировать код и вносить изменения в логику оценки рисков.

С практической точки зрения, открытая платформа даёт три преимущества перед коммерческими аналогами:

  • Полный контроль над данными — события не уходят за периметр вашей инфраструктуры.
  • Возможность дообучения модели на своих размеченных данных без ограничений поставщика.
  • Прозрачность правил — вы видите, как вычисляется оценка риска, и можете изменить веса признаков.

Если нужно быстро поднять тестовое окружение и посмотреть, как работает контейнеризация в контексте инженерных задач, полезным будет руководство по настройке окружения: Настройка окружения для реальных инженеров: Skills for Real Engineers.

Архитектура Kairos и требования к серверу

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

Компоненты платформы и их взаимодействие

В основе Kairos лежат шесть компонентов. API-шлюз принимает входящие запросы, проверяет токены и маршрутизирует их дальше. Сервис оценки рисков считает скор на основе правил и входящих событий. Сервис приёма событий собирает вебхуки и логи от внешних систем. Брокер сообщений буферизирует трафик между сервисами. Воркер забирает задачи из очереди и пересчитывает риски в фоне. База данных хранит профили пользователей, историю событий и результаты оценки.

Взаимодействие выглядит так:

text
Клиент → API-шлюз → Сервис рисков → PostgreSQL
                  ↓
           Брокер сообщений → Воркер → Redis

С практической точки зрения, такая схема даёт предсказуемость: если один компонент перегружен, остальные продолжают работать, а сообщения остаются в очереди. Во-первых, это упрощает масштабирование — можно добавить ещё один воркер, не трогая API. Во-вторых, упрощает отладку — каждый сервис пишет свои логи, и их можно собирать отдельно.

Если мы посмотрим на взаимодействие ближе, то увидим, что API-шлюз не должен знать о внутренней структуре базы. Он только передаёт запрос сервису рисков и ждёт ответа. Сервис рисков, в свою очередь, обращается к PostgreSQL за данными о пользователе и к Redis за кэшированными оценками.

Минимальная конфигурация для развёртывания

Для старта достаточно одного сервера с четырьмя ядрами и восемью гигабайтами оперативной памяти. На меньшем объёме памяти контейнеры начнут вытеснять друг друга, и платформа будет работать нестабильно. Диск — не менее пятидесяти гигабайт на SSD, так как база и логи быстро растут.

Операционная система — любой современный Linux. Я обычно использую Debian, потому что он стабилен и не требует постоянного внимания. Docker и Docker Compose должны быть установлены заранее. Если ещё не настроены, рекомендую ознакомиться с руководством по настройке окружения: Настройка окружения для реальных инженеров: Skills for Real Engineers.

Пример docker-compose.yml для минимального развёртывания:

yaml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: kairos
      POSTGRES_USER: kairos
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - kairos-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kairos -d kairos"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes:
      - kairos-redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  rabbitmq:
    image: rabbitmq:3-management-alpine
    environment:
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
    volumes:
      - kairos-rabbitmq:/var/lib/rabbitmq

  api:
    image: kairos/api:latest
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
      rabbitmq:
        condition: service_started
    environment:
      DATABASE_URL: postgres://kairos:${DB_PASSWORD}@postgres:5432/kairos
      REDIS_URL: redis://redis:6379/0
      RABBITMQ_URL: amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672/
    ports:
      - "8000:8000"

  risk-engine:
    image: kairos/risk-engine:latest
    depends_on:
      - api
      - redis
    environment:
      DATABASE_URL: postgres://kairos:${DB_PASSWORD}@postgres:5432/kairos
      REDIS_URL: redis://redis:6379/0

  worker:
    image: kairos/worker:latest
    depends_on:
      - rabbitmq
      - redis
    environment:
      RABBITMQ_URL: amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672/
      REDIS_URL: redis://redis:6379/0

volumes:
  kairos-db:
  kairos-redis:
  kairos-rabbitmq:

Перед запуском убедитесь, что нужные порты не заняты:

bash
ss -tlnp | grep -E ':8000|:5432|:6379|:5672'

Если всё свободно, поднимаем стек:

bash
docker compose up -d

После запуска проверьте состояние контейнеров:

bash
docker compose ps

Все сервисы должны быть в статусе running или healthy. Если какой-то контейнер переходит в restarting, смотрите логи:

bash
docker compose logs -f risk-engine

Для автозапуска после перезагрузки сервера я добавляю systemd-юнит. Это не обязательно, но даёт предсказуемость: сервер перезагрузился, а платформа поднялась сама.

ini
[Unit]
Description=Kairos platform
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/kairos
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target

Положите файл в /etc/systemd/system/kairos.service, выполните systemctl daemon-reload, systemctl enable --now kairos.service.

Если вы планируете позже перенести часть нагрузки на Kubernetes, стоит заранее разделить конфигурацию по сервисам, как сделано выше. Подробнее про контейнеризацию и оркестрацию можно почитать здесь: Инструменты инженера: от Docker до Kubernetes.

Развёртывание Kairos через Docker Compose

Подготовка хоста и сети

Перед тем как поднимать контейнеры, убедитесь, что на хосте установлены Docker и Docker Compose. Я обычно проверяю это одной командой:

bash
docker --version && docker compose version

Если что-то отсутствует — ставите сначала. На Debian/Ubuntu это пакеты docker-ce и docker-compose-plugin, на Alpine — docker и docker-compose. Разница в версиях редко бывает критичной, но для Kairos я рекомендую Compose не старше v2.20.

Следующий шаг — отдельная сеть для платформы. Это изолирует сервисы Kairos от остальных контейнеров на хосте и упрощает взаимодействие между ними по внутренним DNS-именам.

bash
docker network create kairos-net

Подготовьте директории для конфигурации и постоянных данных. Я держу их под /opt, чтобы не разбрасываться по файловой системе:

bash
mkdir -p /opt/kairos/{config,data,logs}
chmod 750 /opt/kairos

Если планируете открыть веб-интерфейс или API наружу, настройте брандмауэр. На хосте с UFW это выглядит так:

bash
ufw allow 8000/tcp
ufw allow 443/tcp
ufw reload

Порт 8000 — пример для внутреннего API Kairos, 443 — если вы поставите перед ним Caddy или Nginx. С практической точки зрения, лучше не открывать лишнее: если доступ нужен только из локальной сети, ограничьте правило подсетью.

bash
ufw allow from 192.168.1.0/24 to any port 8000

Запуск сервисов и проверка работоспособности

В корне проекта создайте docker-compose.yml. Ниже — примерный состав, который я использовал для развёртывания на своём сервере: API, веб-интерфейс, PostgreSQL, Redis и фоновый обработчик задач.

yaml
version: "3.8"

services:
  kairos-db:
    image: postgres:15-alpine
    container_name: kairos-db
    networks:
      - kairos-net
    volumes:
      - /opt/kairos/data/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: kairos
      POSTGRES_USER: kairos
      POSTGRES_PASSWORD_FILE: /run/secrets/kairos_db_password
    secrets:
      - kairos_db_password

  kairos-redis:
    image: redis:7-alpine
    container_name: kairos-redis
    networks:
      - kairos-net
    volumes:
      - /opt/kairos/data/redis:/data

  kairos-api:
    image: kairos/api:latest
    container_name: kairos-api
    networks:
      - kairos-net
    depends_on:
      - kairos-db
      - kairos-redis
    environment:
      DATABASE_URL: postgresql://kairos:${KAIROS_DB_PASSWORD}@kairos-db:5432/kairos
      REDIS_URL: redis://kairos-redis:6379/0
      LOG_LEVEL: info
    ports:
      - "127.0.0.1:8000:8000"
    secrets:
      - kairos_db_password

  kairos-worker:
    image: kairos/worker:latest
    container_name: kairos-worker
    networks:
      - kairos-net
    depends_on:
      - kairos-api
    environment:
      DATABASE_URL: postgresql://kairos:${KAIROS_DB_PASSWORD}@kairos-db:5432/kairos
      REDIS_URL: redis://kairos-redis:6379/0
    secrets:
      - kairos_db_password

  kairos-web:
    image: kairos/web:latest
    container_name: kairos-web
    networks:
      - kairos-net
    depends_on:
      - kairos-api
    ports:
      - "127.0.0.1:8080:80"

networks:
  kairos-net:
    external: true

secrets:
  kairos_db_password:
    file: ./secrets/kairos_db_password

Секрет для базы создайте отдельно:

bash
mkdir -p secrets
echo -n "сложный_пароль_из_32_символов" > secrets/kairos_db_password
chmod 600 secrets/kairos_db_password

Запустите стек:

bash
docker compose up -d

Проверьте, что контейнеры поднялись и не перезапускаются в цикле:

bash
docker compose ps

Ожидаемый результат — все сервисы в статусе Up. Если какой-то контейнер constantly restarting, смотрите логи:

bash
docker compose logs kairos-api

Когда API доступен, проверьте эндпоинт здоровья. Я обычно делаю это curl'ом прямо с хоста:

bash
curl -s http://127.0.0.1:8000/health | jq .

Ответ должен содержать статус сервисов и время ответа базы. Если видите 200 OK и корректный JSON — платформа поднялась.

Веб-интерфейс доступен на http://127.0.0.1:8080. Если вы выносите его за пределы localhost, поставьте перед ним Caddy или Nginx с TLS — об этом можно почитать в материале про инструменты инженера Инструменты инженера: от Docker до Kubernetes.

С практической точки зрения, после первого запуска стоит проверить, что фоновый обработчик задач действительно подключился к Redis и не висит в ошибках:

bash
docker compose logs kairos-worker | tail -n 30

Предсказуемость конфигурации — это то, ради чего я пишу конфиги руками, а не через GUI. Когда через полгода придётся восстанавливать стек из бэкапа, вы будете знать точно, какой порт слушает API и где лежат данные PostgreSQL.

Интеграция с приложениями и мониторинг

Подключение клиентских приложений

Клиентское приложение должно отправлять события в Kairos — обычно это REST-запросы к API платформы. Главное правило: оценка рисков не должна ломать основной поток приложения. Если Kairos недоступен, сервис продолжает работать, а событие просто теряется или пишется в локальную очередь.

Пример на Python с requests. Таймаут в пять секунд — достаточно, чтобы не подвесить пользовательский запрос, но не так мало, чтобы отсечь легитимные задержки сети.

python
import requests
from datetime import datetime, timezone

KAIROS_API = "http://kairos:8080/api/v1/events"

def send_risk_event(user_id: str, action: str, metadata: dict):
    payload = {
        "user_id": user_id,
        "action": action,
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "metadata": metadata,
    }
    try:
        response = requests.post(KAIROS_API, json=payload, timeout=5)
        response.raise_for_status()
    except requests.RequestException as exc:
        # Не падаем вместе с Kairos. Пишем в локальный лог и идём дальше.
        print(f"Kairos event delivery failed: {exc}")

Если приложение на Go, логика та же — отдельная горутина с буферизованным каналом, чтобы не блокировать HTTP-хендлер. Во-первых, это предсказуемость: вы точно знаете, когда и куда ушло событие. Во-вторых, вы не делаете бизнес-логику зависимой от доступности стороннего сервиса.

Логирование и алерты

Kairos пишет в stdout, поэтому в Docker-среде логи забирает драйвер json-file или системный journald, если контейнер запущен через systemd. Для долговременного хранения и поиска лучше подключить Loki или Prometheus с Grafana — это уже отработанный стек, который я использую на своих нодах.

Пример сервиса в docker-compose.yml с ограничением ротации логов. Без этого json-file разрастётся и съест весь диск, особенно если Kairos пишет отладочный уровень на продакшене.

yaml
version: "3.8"
services:
  kairos:
    image: kairos/platform:latest
    ports:
      - "8080:8080"
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    restart: unless-stopped

Для мониторинга доступности добавляем правило в Prometheus. Если цель не отвечает в течение минуты — срабатывает алерт критического уровня.

yaml
groups:
  - name: kairos_alerts
    rules:
      - alert: KairosDown
        expr: up{job="kairos"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Kairos не отвечает"
          description: "Платформа оценки рисков недоступна более минуты."

Алерты отправляются через Alertmanager в Telegram или по почте — выбирайте канал, который вы действительно читаете. Бесполезный алерт, который игнорируют, хуже отсутствия алерта.

Если хотите углубиться в инструменты инженера, от Docker до Kubernetes, есть отдельный материал: Инструменты инженера: от Docker до Kubernetes. А для настройки окружения под такие задачи полезен гид: Настройка окружения для реальных инженеров: Skills for Real Engineers.

Часто задаваемые вопросы

Чем Kairos отличается от коммерческих платформ вроде Sift или Sardine?

Коммерческие решения — это чёрный ящик: вы не видите правила, по которым система принимает решение, и не можете повлиять на обучение модели. Kairos даёт открытый код, поэтому вы контролируете, какие признаки используются для оценки риска, и храните все данные на своих серверах. С практической точки зрения это значит, что платформа подстраивается под специфику вашего бизнеса, а не заставляет вас подстраиваться под чужой опыт тысяч других компаний, и даёт предсказуемость конфигураций.

Нужны ли свои размеченные данные, чтобы начать использовать Kairos?

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

Как интегрировать Kairos с существующей инфраструктурой?

Kairos принимает события через HTTP API, поэтому достаточно отправить JSON с полями event_id, timestamp, user_id и другими данными о действии пользователя. Развёртывание через Docker Compose поднимает API, базу и воркер обработки событий на одной ноде, что упрощает подключение к уже работающему бэкенду. С моей точки зрения, проще всего начать с одного сервиса — например, платежей — и постепенно подключать остальные точки входа.

Безопасно ли хранить данные о мошенничестве на своём оборудовании?

Отвечаю как системный инженер: безопасность зависит не от того, где лежат данные, а от того, как вы настраиваете доступ и бэкапы. Хранение на своих серверах даёт полный контроль над шифрованием, резервным копированием и аудитом доступа, чего нет в коммерческом облаке. Во-первых, настройте отдельную сеть для базы данных; во-вторых, включите journald и Prometheus для мониторинга доступа к API.

Нужно ли быть специалистом по машинному обучению, чтобы пользоваться Kairos?

Не обязательно. Для начала достаточно понимать, какие события вашего бизнеса считаются подозрительными, и уметь формировать JSON-события для API. Настройка правил и порогов не требует глубоких знаний ML, а обучение модели можно отложить до накопления достаточного объёма размеченных данных.

Поделиться:TelegramX / TwitterVK

Читайте также