Продвинутый

Kairos: развёртывание открытой платформы антифрода

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

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

Kairos: развёртывание открытой платформы антифрода

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

Что такое Kairos и зачем оно инженеру

Что такое Kairos и зачем оно инженеру

Kairos — открытая платформа для принятия решений по рискам и мошенничеству. Если в вашем приложении нужно оценивать действия пользователя в реальном времени — вход, оплату, создание аккаунта или вызов API — вам приходится либо писать собственную систему scoring с нуля, либо подключаться к коммерческому сервису. Kairos занимает промежуточную нишу: вы разворачиваете платформу у себя, управляете правилами через отдельный слой и не отдаёте данные третьим сторонам. Подробнее про концепцию можно прочитать в материале Kairos — открытая платформа для оценки рисков.

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

Основные компоненты платформы

Pлатформа собирается через Docker Compose и состоит из нескольких сервисов. Я предпочитаю писать конфиги вручную, даже когда есть графический интерфейс — так проще понимать, что именно запущено и почему. Пример файла docker-compose.yml для тестового развёртывания:

yaml
version: "3.8"
services:
  kairos-api:
    image: kairos/api:latest
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgres://kairos:kairos@db:5432/kairos
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache
  kairos-worker:
    image: kairos/worker:latest
    environment:
      - QUEUE_NAME=default
    depends_on:
      - kairos-api
  db:
    image: postgres:15-alpine
    volumes:
      - kairos-db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=kairos
      - POSTGRES_USER=kairos
      - POSTGRES_PASSWORD=kairos
  cache:
    image: redis:7-alpine
volumes:
  kairos-db:

После запуска доступны три основных компонента:

  1. API-сервис — принимает события от приложения и возвращает решение: разрешить, заблокировать или запросить дополнительную проверку.
  2. Worker — обрабатывает события в фоне, пересчитывает рисковые счета и обновляет модели.
  3. База данных и кэш — PostgreSQL для хранения правил и историй событий, Redis для быстрого доступа к сессиям и временным данным.

С практической точки зрения, самое важное здесь — разделение на API и worker. Если приложение присылает десять тысяч событий в секунду, API не должен ждать окончания расчёта риска. Он принимает событие, кладёт в очередь и сразу отвечает клиенту. Worker забирает задачу и работает в своём темпе. Такой подход напоминает работу с очередями сообщений, о которых я писал в материале Инструменты инженера: от Docker до Kubernetes.

Отличие от коммерческих аналогов

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

Во-первых, вы контролируете данные. События не уходят на сторонние серверы, что важно для проектов с жёсткими требованиями к конфиденциальности.

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

В-третьих, предсказуемость конфигурации. Когда всё описано в коде и развёрнуто через Docker Compose, вы знаете, какая версия сервиса работает, какие переменные окружения заданы и как повторить развёртывание на другой среде.

Пример правила в формате YAML:

yaml
name: "Подозрительный вход"
description: "Блокируем вход с нового устройства и необычной геолокации"
conditions:
  - field: "device_id"
    operator: "not_in"
    value: "{{user.trusted_devices}}"
  - field: "ip_country"
    operator: "not_in"
    value: "{{user.countries}}"
actions:
  - type: "challenge"
    method: "email"
  - type: "alert"
    channel: "slack"

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

В следующем разделе разберём развёртывание через Docker Compose и интеграцию с приложением.

Развёртывание Kairos на собственном оборудовании

Требования к серверу и Docker Compose

Kairos состоит из нескольких сервисов: API, обработчик событий, база данных и брокер сообщений. С практической точки зрения, это классический стек, который удобно описывать одним файлом docker-compose.yml.

Во-первых, определитесь с железом. Для тестового инстанса хватит двух ядер, четырёх гигабайт оперативной памяти и двадцати гигабайт на диске. Если планируете обрабатывать поток событий в реальном времени, закладывайте не менее восьми гигабайт памяти и SSD — PostgreSQL с интенсивной записью не любит медленные диски.

Убедитесь, что на сервере установлен Docker и Docker Compose. Проверка занимает минуту:

bash
docker --version
docker compose version

Если команда docker compose не найдена, а есть только старый docker-compose, замените в дальнейшем вызовах соответствующим образом.

Ниже пример минимального docker-compose.yml. Я обычно пишу конфиги вручную — GUI для тех, кто не знает, где лежит конфиг.

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

  kairos-api:
    image: kairos/api:latest
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      DATABASE_URL: postgresql://kairos:${DB_PASSWORD}@postgres:5432/kairos
      REDIS_URL: redis://redis:6379/0
      API_PORT: 8000
    ports:
      - "8000:8000"
    restart: unless-stopped

  kairos-worker:
    image: kairos/worker:latest
    depends_on:
      kairos-api:
        condition: service_started
    environment:
      DATABASE_URL: postgresql://kairos:${DB_PASSWORD}@postgres:5432/kairos
      REDIS_URL: redis://redis:6379/0
    restart: unless-stopped

volumes:
  kairos_db:
  kairos_redis:

Перед запуском создайте файл .env в той же директории и укажите надёжный пароль для базы:

bash
DB_PASSWORD=сложный_пароль_не менее_16_символов

С паролями не экспериментируйте. Если база будет доступна извне, слабый пароль — это вопрос времени, а не вероятности.

Первый запуск и проверка работоспособности

Сначала поднимите инфраструктуру — базу и Redis:

bash
docker compose up -d postgres redis

Подождите, пока контейнеры перейдут в состояние healthy. Посмотреть статус можно так:

bash
docker compose ps

Если статус healthy, запустите остальные сервисы:

bash
docker compose up -d

Теперь проверьте, что API отвечает. Сначала убедитесь, что порт 8000 не занят другим процессом:

bash
ss -tlnp | grep 8000

Если порт свободен и контейнер запущен, выполните запрос к эндпоинту проверки работоспособности:

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

Ожидаемый ответ — JSON со статусом ok или healthy. Если curl возвращает ошибку соединения, загляните в логи:

bash
docker compose logs --tail=50 kairos-api

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

Когда API отвечает, попробуйте отправить тестовое событие на оценку риска. Структура запроса зависит от версии API, поэтому смотрите актуальную спецификацию в репозитории проекта. В общем виде это POST-запрос с телом события и заголовком авторизации, если он настроен.

Если всё работает, следующим шагом будет вынос конфига из .env в отдельный файл секретов и настройка обратного прокси — например, Nginx или Caddy — чтобы не открывать порт 8000 напрямую в интернет. Об этом и о настройке правил антифрода читайте в следующих разделах.

Для повторения основ Docker перед работой с compose-файлами полезно заглянуть в Инструменты инженера: от Docker до Kubernetes, а общая концепция платформы описана в Kairos — открытая платформа для оценки рисков.

Настройка правил принятия решений

Настройка правил принятия решений

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

Я настраивал подобные системы раньше, и главная ошибка — пытаться описать все возможные сценарии сразу. Начинайте с двух-трёх источников данных и одной политики, отработайте её на реальном трафике, а потом масштабируйте.

Подключение источников данных

Источник данных — это точка, откуда Kairos забирает информацию о клиенте, транзакции или устройстве. На практике это чаще всего реляционная база, ключ-значение для кэша, внешнее API или логи веб-сервера.

Настройка правил без понимания источников данных — это как сборка мебели без инструкции: вроде всё есть, но ничего не hält. Во-первых, определите, какие данные нужны для принятия решения. Для антифрода обычно достаточно трёх категорий: профиль пользователя, история транзакций и метаданные устройства (IP, User-Agent, отпечаток браузера).

С практической точки зрения, подключение источника в Kairos выглядит как описание в docker-compose.yml. Ниже пример, где платформа тянет данные из PostgreSQL и Redis, которые уже развёрнуты в том же стеке.

yaml
services:
  kairos:
    image: kairos/platform:latest
    environment:
      - DATA_SOURCE__PG__HOST=db
      - DATA_SOURCE__PG__PORT=5432
      - DATA_SOURCE__PG__USER=kairos
      - DATA_SOURCE__PG__PASSWORD=${PG_PASSWORD}
      - DATA_SOURCE__PG__DATABASE=fraud_events
      - CACHE__REDIS__HOST=cache
      - CACHE__REDIS__PORT=6379
    volumes:
      - ./rules:/etc/kairos/rules
    depends_on:
      - db
      - cache

Сначала убедитесь, что переменная PG_PASSWORD определена в .env, иначе контейнер не стартует. Я предпочитаю хранить пароли отдельно, а не в репозитории — это базовая гигиена, которой часто пренебрегают.

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

Создание политик рисков

Политика — это набор правил, каждое из которых состоит из условия и действия. Условие проверяет данные из источников, действие определяет, что делать с транзакцией: одобрить, отклонить или отправить на ручную проверку.

Если мы посмотрим на типичный сценарий, политика выглядит так: сумма транзакции превышает порог, и страна IP не совпадает со страной выпуска карты. В этом случае риск высокий, и решение принимает оператор, а не алгоритм.

Пример описания политики в YAML:

yaml
policies:
  - name: high_value_foreign_transaction
    priority: 10
    conditions:
      - field: transaction.amount
        operator: gt
        value: 50000
      - field: transaction.country
        operator: ne
        value: "{{ user.card_country }}"
    action: manual_review
    reason: "Сумма выше порога и страна транзакции не совпадает со страной выпуска карты"

Здесь priority определяет порядок проверки: чем выше число, тем раньше срабатывает правило. Если несколько правил подходят, применяется то, у которого приоритет выше.

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

После создания политики проверьте её на тестовых данных. Kairos предоставляет эндпоинт для симуляции решения без влияния на реальный трафик:

bash
curl -X POST http://localhost:8080/v1/simulate \
  -H "Content-Type: application/json" \
  -d '{"transaction_id": "test-001", "amount": 75000, "country": "US", "user_id": "user-42"}'

Ответ содержит применённую политику и итоговое действие. Если что-то пошло не так, смотрите логи контейнера kairos — обычно проблема в несоответствии имён полей в условии и реальных данных.

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

Мониторинг и логирование событий

Мониторинг и логирование событий

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

С практической точки зрения, мониторинг делится на две части: то, что произошло (логи), и то, что требует реакции прямо сейчас (алерты). Для Kairos я использую стек, который уже описан в материале про инструменты инженера от Docker до Kubernetes — Loki для логов и Alertmanager для уведомлений. Если вы только начинаете знакомство с платформой, рекомендую сначала прочитать обзор Kairos — открытая платформа для оценки рисков.

Сбор логов в Loki

Loki выбираю потому, что он лёгкий, не требует тяжёлой индексации и хорошо дружит с Docker. Для сбора логов из контейнеров Kairos использую Promtail — агент, который читает логи из /var/lib/docker/containers и отправляет их в Loki.

Фрагмент docker-compose.yml:

yaml
services:
  loki:
    image: grafana/loki:2.9.0
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:2.9.0
    volumes:
      - ./promtail-config.yaml:/etc/promtail/config.yaml
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/log:/var/log:ro
    command: -config.file=/etc/promtail/config.yaml
    depends_on:
      - loki

Конфиг Promtail для сбора логов Kairos:

yaml
scrape_configs:
  - job_name: kairos
    static_configs:
      - targets:
          - localhost
        labels:
          job: kairos
          __path__: /var/lib/docker/containers/*/*-json.log
    pipeline_stages:
      - docker: {}
      - regex:
          expression: '(?P<level>\w+)\s+(?P<message>.*)'
      - labels:
          level:

Как проверить, что логи идут:

bash
curl -s 'http://localhost:3100/loki/api/v1/query?query={job="kairos"}' | jq .

Если видите JSON с потоками логов — сбор работает. Если нет — проверьте права на /var/lib/docker/containers и имя контейнера Kairos.

С практической точки зрения, не стоит пытаться индексировать всё подряд. Loki не Elasticsearch, и попытка сделать из него полнотекстовый поиск по всем полям приведёт к раздуванию хранилища. Собирайте логи приложения, ошибки и системные события контейнеров. Достаточно.

Алерты в Alertmanager

Логи показывают, что случилось. Алерты говорят, что нужно сделать прямо сейчас. Для Kairos я настраиваю алерты на основе метрик, которые платформа уже отдаёт, и на основе состояния контейнеров.

Alertmanager — стандарт в экосистеме Prometheus. Он получает сигналы от Prometheus, группирует их, убирает дубли и рассылает уведомления. Ниже пример минимального конфига.

alertmanager.yml:

yaml
global:
  smtp_smarthost: 'smtp.example.com:587'
  smtp_from: 'alerts@your-domain.ru'

route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'team-email'

receivers:
  - name: 'team-email'
    email_configs:
      - to: 'infra-team@your-domain.ru'

Правила алертинга для Prometheus (prometheus.rules.yml):

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

      - alert: KairosHighErrorRate
        expr: rate(kairos_requests_total{status=~"5.."}[5m]) > 0.1
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Высокий уровень ошибок в Kairos"
          description: "За последние 5 минут более 10 % запросов завершились ошибкой 5xx."

Подключение в docker-compose.yml:

yaml
services:
  prometheus:
    image: prom/prometheus:2.47.0
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./prometheus.rules.yml:/etc/prometheus/rules/kairos.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    ports:
      - "9090:9090"

  alertmanager:
    image: prom/alertmanager:0.25.0
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
    ports:
      - "9093:9093"

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

Проверка алертов без инцидента:

bash
curl -s 'http://localhost:9093/api/v2/alerts'

Должен вернуться пустой массив или список текущих активных алертов.

Мониторинг Kairos не должен быть сложным. Начните с сбора логов в Loki и пары критических алертов в Alertmanager — достаточно, чтобы видеть падения и ошибки. По мере роста нагрузки добавляйте метрики и дашборды, но не гонитесь за сложностью ради сложности. Предсказуемость конфигурации важнее количества датчиков.

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

Нужно ли использовать Docker Compose, или можно развернуть вручную?

Docker Compose — рекомендуемый способ старта, но не обязательный. Все компоненты — обычные контейнеры, их можно поднять через systemd или Kubernetes, если инфраструктура требует. С практической точки зрения Compose проще для теста, а в продакшене я обычно выношу каждый сервис в отдельный манифест, чтобы управлять ресурсами точнее.

Можно ли менять правила антифрода без перезапуска сервиса?

Да, правила хранятся отдельно от кода приложения и подгружаются через API платформы. Изменения вступают в силу сразу после сохранения, перезапуск контейнера не требуется. Это удобно, когда бизнес просит ужесточить проверку платежей из нового региона в середине рабочего дня.

Какая база данных нужна для Kairos и можно ли использовать свою PostgreSQL?

Kairos работает с PostgreSQL и Redis, оба сервиса уже входят в docker-compose.yml. Если у вас есть своя база, достаточно изменить переменные DATABASE_URL и REDIS_URL в конфиге API и воркера. Я не рекомендую совмещать production-базу с тестовой средой Kairos — лучше выделить отдельную схему или инстанс.

Как интегрировать Kairos с собственным приложением?

Платформа предоставляет HTTP API, куда приложение отправляет событие — вход, оплату или создание аккаунта — и получает оценку риска. В ответе приходит решение: разрешить, заблокировать или запросить дополнительную проверку. Интеграция сводится к одному вызову из бэкенда, логику принятия решения выносите в правила Kairos, а не в код приложения.

На какую нагрузку рассчитана платформа?

Зависит от конфигурации железа и сложности правил. На трёх нодах Proxmox с 8 ядрами и 32 ГБ оперативной памяти я держу несколько тысяч событий в минуту без задержек. Если правил становится больше пятидесяти, стоит добавить отдельный инстанс воркера и мониторить очередь через Prometheus.

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

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