Сценарии использования

Защита от опустошения бюджета и отказа в обслуживании

Иерархические бюджеты, предварительная оценка стоимости каждого запроса и rate limits на стороне шлюза гарантируют, что баг в коде или внешняя атака не превратятся в катастрофический счёт от провайдера.

Проблема

LLM-расходы — один из крупнейших новых статей расхода начиная с 2025го года. Бесконечный цикл вызовов модели в коде, утечка ключа в публичный репозиторий или внешняя нагрузка на ваш API за ночь могут израсходовать месячный бюджет проекта или компании. Особенность LLM в том, что стоимость одного запроса масштабируется с длиной контекста и количеством токенов — один «безобидный» вызов с гигантским промптом может стоить десятки долларов.

Стандартные защиты на уровне инфраструктуры — WAF, rate limit на API gateway — не учитывают стоимость запроса, только их количество. Тысяча дешёвых запросов и тысяча дорогих формально неотличимы, но первая обойдётся в копейки, а вторая — в тысячи долларов.

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

Решение

  • Гарантированный потолок расхода. Иерархия Customer → Team → VK применяется на каждом запросе; превышение на любом уровне блокирует запрос.
  • Отказ в обслуживании не превращается в отказ биллинга. Предварительная оценка отвергает запросы если они превышают бюджет еще до вызова провайдера — стоимость атаки для провайдера равна нулю.
  • Изоляция инцидентов между командами. Перерасход или ошибка одной команды не съедают бюджет другой; иерархия эксклюзивна.
  • Быстрое тушение инцидентов. Одна операция (is_active: false) мгновенно отключает доступ для одного VK, остальные продолжают работать.
  • Наблюдаемость рисков. Метрики Prometheus (meridian_governance_rejections_total, бюджетные счётчики) позволяют настроить алерты до того, как бюджет будет исчерпан.

Что предлагает Meridian

Meridian реализует три слоя защиты, работающие совместно:

  1. Иерархические бюджеты — Customer → Team → Virtual Key → Provider Config. На каждом уровне свой потолок и период сброса; превышение на любом уровне блокирует запрос. В кластерной редакции согласованность бюджетов обеспечивается через Raft, без race conditions при отказе узлов.
  2. Предварительная оценка запроса — до отправки запроса в LLM Meridian оценивает его стоимость на основе количества входных токенов и тарифа модели. Если бюджет уже исчерпан или предполагаемая стоимость превысит лимит, запрос отвергается без обращения к upstream-провайдеру. Стоимость DoS-атаки для вашего биллинга — ноль.
  3. Rate limits — независимые ограничения по запросам/минуту и токенам/минуту на каждый VK. Останавливают взрывной рост вызовов от ошибки в коде или вредоносного клиента ещё до того, как они приблизятся к бюджетному потолку.

нет

да

нет

да

нет

да

Входящий запрос

VK активен?

401 Unauthorized

Rate limit
не превышен?

429 Too Many Requests

Pre-LLM cost
estimation

Хватит на всех
уровнях иерархии?
VK / Team / Customer

402 Budget Exceeded
upstream НЕ вызывается

Вызов upstream LLM

Post-LLM reconciliation
фактическая стоимость списывается

Сценарий

Команда alpha запустила в эксплуатацию сервис автогенерации краткого содержимого. По ошибке retry-логика на стороне приложения попадает в бесконечный цикл — вместо одного запроса к LLM сервис делает 600 вызовов в минуту с большими промптами.

  1. Первые ~60 запросов проходят. Meridian оценивает каждый pre-LLM и списывает фактическую стоимость post-LLM.
  2. На 61-м запросе срабатывает rate limit (request_max_limit: 60, request_reset_duration: "1m") — Meridian возвращает 429 Too Many Requests, upstream OpenAI не вызывается.
  3. Параллельно срабатывает token rate limit (token_max_limit: 100000, token_reset_duration: "1m") — даже если приложение перейдёт на крупные запросы вместо частых, оно упрётся в потолок токенов.
  4. SRE получает алерт из Prometheus (метрика meridian_governance_rejections_total растёт), идёт в логи Meridian, находит проблемный VK за секунды и отключает его (is_active: false).
  5. Финансовые потери: фактическая стоимость 60 запросов, а не 60 × N минут × 600 RPS. Бюджет команды не пострадал; бюджеты других команд не затронуты.

Альтернативный сценарий — утечка виртуального ключа (VK) во внешний репозиторий. Атакующий пытается потратить платные запросы:

  1. Внешний клиент начинает массовые вызовы с украденным VK.
  2. Предварительная оценка на каждом запросе складывается с накопленным расходом — лимит VK ($100/день) достигается за минуты/часы.
  3. Каждый последующий запрос возвращает 402 Budget Exceeded мгновенно, без обращения к OpenAI. Ущерб от инцидента или ошибки контролируемо минимальный.

Конфигурация

Шаг 1. Включите принудительную аутентификацию на inference.

  1. Откройте Config → Governance.
  2. Включите Enforce auth on inference (enforce_auth_on_inference: true).
Принудительная аутентификация на inference

Шаг 2. Создайте Virtual Key с тремя уровнями защиты.

  1. В Virtual Keys → Add Virtual Key задайте:
    • Max Limit: 100 (USD), Reset Duration: 1d — дневной бюджет.
    • Token Limit: 100000, Reset Duration: 1m — token rate limit.
    • Request Limit: 60, Reset Duration: 1m — request rate limit.
  2. Привяжите VK к Team и Customer с месячными бюджетами на верхних уровнях.
Бюджет и rate limits в форме VK

Шаг 3. Настройте алерты на превышение.

  1. В Observability → Metrics убедитесь, что Prometheus включён.
  2. В системе мониторинга настройте алерт на метрику bifrost_governance_rejections_total (рост на VK = индикатор инцидента).

Создание VK с защитой по бюджету и rate limits:

curl -X POST http://localhost:8080/api/governance/virtual-keys \
  -H "Content-Type: application/json" \
  -d '{
    "name": "alpha-prod",
    "description": "Production VK with strict limits",
    "team_id": "team-alpha",
    "provider_configs": [
      {
        "provider": "openai",
        "weight": 1.0,
        "allowed_models": ["gpt-4o-mini"]
      }
    ],
    "budget": {
      "max_limit": 100.00,
      "reset_duration": "1d"
    },
    "rate_limit": {
      "request_max_limit": 60,
      "request_reset_duration": "1m",
      "token_max_limit": 100000,
      "token_reset_duration": "1m"
    },
    "is_active": true
  }'

Экстренное отключение VK при инциденте:

curl -X PUT http://localhost:8080/api/governance/virtual-keys/{vk_id} \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'

Ожидаемые HTTP-коды при срабатывании защиты:

КодПричинаЧто делать
401VK отсутствует или неактивенПроверить заголовок и статус VK
402Бюджет исчерпан на одном из уровней (VK/Team/Customer)Увеличить бюджет или дождаться сброса
429Превышен request_max_limit или token_max_limitУменьшить нагрузку, пересмотреть rate limits

Полная иерархия с защитой на каждом уровне:

{
  "client": {
    "enforce_auth_on_inference": true
  },
  "governance": {
    "customers": [
      { "id": "customer-rnd", "name": "rnd", "budget_id": "budget-rnd" }
    ],
    "teams": [
      {
        "id": "team-alpha",
        "name": "alpha",
        "customer_id": "customer-rnd",
        "budget_id": "budget-alpha"
      }
    ],
    "virtual_keys": [
      {
        "id": "vk-alpha-prod",
        "name": "alpha-prod",
        "value": "sk-bf-alpha-prod",
        "is_active": true,
        "team_id": "team-alpha",
        "budget_id": "budget-vk-prod",
        "rate_limit_id": "rate-vk-prod",
        "provider_configs": [
          {
            "provider": "openai",
            "weight": 1.0,
            "allowed_models": ["gpt-4o-mini"]
          }
        ]
      }
    ],
    "budgets": [
      { "id": "budget-rnd",     "max_limit": 10000.0, "reset_duration": "1M" },
      { "id": "budget-alpha",   "max_limit": 4000.0,  "reset_duration": "1M" },
      { "id": "budget-vk-prod", "max_limit": 100.0,   "reset_duration": "1d" }
    ],
    "rate_limits": [
      {
        "id": "rate-vk-prod",
        "request_max_limit": 60,
        "request_reset_duration": "1m",
        "token_max_limit": 100000,
        "token_reset_duration": "1m"
      }
    ]
  }
}
ПолеЧто ограничивает
budget.max_limit + reset_durationДенежный потолок за период
rate_limit.request_max_limitЗапросов за период
rate_limit.token_max_limitТокенов (input+output) за период
client.enforce_auth_on_inferenceЗапретить inference без VK

В кластерной (Enterprise) редакции списания и резервы по бюджетам реплицируются через Raft. Это гарантирует, что отказ одного узла не приведёт к двойному списанию или потере спена при сетевых разрывах. Подробнее — на странице Кластеризация.

Ограничения

  • *Точность оценки запроса зависит от модели и provider-specific сигналов. Реальная стоимость может незначительно отличаться от оценки; post-LLM reconciliation выравнивает счёт по факту.
  • Direct Key Bypass. Заголовки Authorization, x-api-key, x-goog-api-key поддерживают прямые ключи провайдера. Такие запросы не учитываются в иерархии бюджетов — это сознательный отказоустойчивый сценарий для доверенных интеграций. См. Управление ключами провайдеров.
  • Прямые вызовы провайдера в обход Meridian не покрываются. Защищайте upstream-ключи провайдера организационно: они должны храниться только в Meridian и специальных сервисах управления секретами.
  • Calendar-aligned сброс vs скользящее окно. По умолчанию reset_duration работает как скользящее окно; для жёстких календарных границ (день UTC, месяц UTC) включите calendar_aligned: true в бюджете — детали в Бюджеты и лимиты.

Связанные материалы

Содержание