Аутентификация

Bearer-токены, ротация ключей и общедоступный каталог без аутентификации.

Основы

Для API шлюз использует bearer-токены, а небольшой набор каталоговых endpoints оставляет общедоступным.

Bearer-токены

Общедоступные маршруты поиска моделей /v1/models, /v1/catalog и /v1/catalog/* не требуют API key. Защищённые маршруты, например /v1/chat/completions, /v1/embeddings и /v1/quota, требуют bearer-токен с префиксом gw_. Ключ создаётся в кабинете; передавайте его в заголовке Authorization.

Authorization: Bearer gw_<your-key>

Если заголовка нет либо ключ имеет неверный формат, отозван или отклонён, API возвращает 401 в стандартной оболочке ошибки:

{
  "error": {
    "message": "Invalid API key",
    "type": "authentication_error",
    "code": null
  }
}

У ошибок аутентификации сейчас нет отдельного значения error.code. Ветвитесь по HTTP-статусу 401 или type: "authentication_error", а не по invalid_api_key.

Хранение ключа

Обращайтесь с ключом как с секретом:

  • Не добавляйте его в репозиторий. Используйте переменные окружения (process.env.GATEWAY_KEY) или менеджер секретов.
  • Не вставляйте его в чат. Если ключ мог утечь, отзовите его в клиентском кабинете с активной сессией или попросите об этом контактное лицо шлюза.
  • Не используйте один ключ для разных команд. Отдельный ключ на потребителя позволяет применять rate limit и баланс AI-кредитов к одной нагрузке, а не ко всем сразу.

CI-скрипт в этом репозитории ищет в публичной документации и коде админки строки, похожие на настоящие ключи gw_…, и останавливает сборку при обнаружении. В примерах всегда используйте placeholder, а не реальное значение.

Ротация

Ключи меняются по схеме «выпустить новый, затем отозвать старый»:

  1. Создайте новый личный ключ в клиентском кабинете с активной сессией или запросите его у контактного лица шлюза.
  2. Разверните его через переменную окружения, менеджер секретов или используемый вами механизм доставки конфигурации.
  3. Убедитесь, что трафик уже идёт с новым ключом.
  4. Отзовите старый ключ в клиентском кабинете или попросите об этом контактное лицо шлюза.

По умолчанию у ключей нет срока действия. Периодичность ротации выбираете вы: для production-ключей обычно достаточно квартальной ротации, а для чувствительных сценариев — чаще.

Лимит запросов на ключ

Для каждого ключа контактное лицо шлюза настраивает собственный request rate limit. При превышении API возвращает HTTP 429 с type: "rate_limit_exceeded" и code: null:

{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_exceeded",
    "code": null
  }
}

Ветвитесь по HTTP-статусу 429 или полю type, а не по error.code. Повторяйте запросы с экспоненциальной задержкой и jitter. Если лимит достигается регулярно, попросите его увеличить либо используйте отдельный ключ для шумной нагрузки. Полная стратегия повторов приведена в разделе «Лимиты и квоты».

Общедоступный поиск моделей

Endpoints /v1/models, /v1/catalog и /v1/catalog/* доступны без аутентификации. Любой клиент может вызвать их без заголовка Authorization и получить список моделей шлюза — например, для выбора модели, dashboard или документации. Защищённые inference- и quota-маршруты по-прежнему требуют bearer-токен gw_.

bash
curl https://api.toygate.store/v1/catalog
bash
curl https://api.toygate.store/v1/catalog/gpt-5.5

Для защиты от шума discovery endpoints ограничены по IP: 60 запросов в минуту с восстановлением 1 запроса в секунду. Ответы хорошо кешируются, поэтому их можно недорого встраивать в интерфейсы.

Самостоятельное управление ключами

Клиентский кабинет с активной сессией позволяет создавать и отзывать собственные ключи пользователя. Он использует защищённые сессионной cookie маршруты POST /client/keys и DELETE /client/keys/:id. Это self-scoped endpoints кабинета, а не общедоступный OpenAI-compatible API; bearer-ключи gw_ для них не подходят.

Что недоступно

  • Нельзя использовать ключ gw_ для /admin/* или /client/*. Эти маршруты используют session-cookie аутентификацию соответствующих SPA.
  • Нельзя вызывать /v1/* с сервера с помощью session cookie. Используйте ключ gw_.
  • Нельзя считать /client/keys общедоступным API управления ключами. Создание и отзыв требуют активной пользовательской сессии и ограничены собственными ключами этого пользователя.