RussiaAPI

Практическое руководство для разработчиков

Права API key в OpenAI-совместимом API: принцип минимального доступа

Права API key в OpenAI-совместимом API — это не только переключатель «ключ работает или нет». Один общий секрет в браузере, CI и трёх сервисах не позволяет понять, кто вызвал модель, ограничить дорогой маршрут или быстро отключить один интеграционный модуль. Практичный подход строит границу в вашем backend: внешний ключ RussiaAPI остаётся только там, а приложения получают собственные ограниченные учётные данные. Так команда управляет моделями, бюджетом и журналом без раскрытия секрета gateway.

Граница сервиса. RussiaAPI — независимый сторонний API gateway, а не официальный сервис OpenAI, Anthropic, Google или производителя модели. OpenAI-совместимый формат описывает контракт отдельных запросов, но не обещает одинаковые модели, цены, хранение данных, webhook или права ключей. Используйте только собственный RUSSIAAPI_API_KEY на сервере; не передавайте внешние ключи, cookie, пароли, коды подтверждения или лишние персональные данные.

Сначала разделите два вида ключей

Есть ключ, которым ваш сервер обращается к gateway, и есть учётные данные, которыми внутренние сервисы или пользователи обращаются к вашему backend. Это разные границы. RUSSIAAPI_API_KEY хранится только в серверном secret store или переменной окружения процесса. Он не попадает в JavaScript браузера, мобильное приложение, публичный репозиторий, скриншот панели или тикет поддержки. Внутренний токен может идентифицировать конкретный сервис, tenant или среду, но не должен автоматически давать полный доступ к ключу gateway.

Не предполагаете, что каждый OpenAI-совместимый endpoint или модель поддерживает одни и те же механизмы прав. Если в консоли RussiaAPI есть роли, ограничения ключа или бюджет, сверяйте их с текущей документацией и договором перед включением. Если такой возможности нет, ограничения всё равно можно применить в собственном серверном proxy: разрешать только нужные модели, размер запроса и назначение маршрута. Это не делает gateway официальным сервисом производителя и не отменяет правила вашего продукта.

Опишите разрешения как короткую политику

Политика должна отвечать на четыре вопроса: кто вызывает маршрут, какие model ID разрешены, какой максимум запроса допустим и сколько операций или расхода разрешено за период. Для чат-бота поддержки достаточно одного текстового маршрута и небольшой allowlist; сервис генерации видео может требовать отдельного server-side маршрута, очереди и другого бюджета. Не выдавайте «на всякий случай» доступ ко всем моделям. Новая модель, инструмент или видео-операция — отдельное решение с владельцем и тестом.

Собирайте policy по идентификатору приложения, а не по значению, которое присылает браузер. Клиент может попросить model ID, но сервер сверяет его с разрешённым списком и при необходимости выбирает безопасное значение сам. Логируйте имя policy, tenant, модель, HTTP-класс и агрегированный расход; не пишите Authorization, полный prompt, ответ модели или личные файлы. Такой журнал помогает ответить, почему запрос отклонён, и дополняет разделение ключей в команде.

Поставьте proxy между приложением и gateway

Server-side proxy — место, где проверяются пользовательская сессия, внутренний токен, лимит, бюджет и допустимый payload. Только после этой проверки он добавляет заголовок авторизации RussiaAPI. Не проксируйте произвольный URL и не принимайте от клиента заголовок Authorization: иначе приложение сможет использовать чужой или вышестоящий ключ. Вместо этого сформируйте разрешённый запрос сами и верните нейтральную ошибку без технических деталей поставщика.

Ниже минимальный пример для Node.js 18+. Он намеренно использует демонстрационный внутренний токен из переменной окружения и статическую policy; для production замените его базой или системой идентификации, храните только хэш токена и добавьте устойчивый счётчик бюджета. Код не утверждает, что RussiaAPI предоставляет scopes ключей: scopes здесь применяет ваше приложение. Перед запуском задайте INTERNAL_BOT_TOKEN, RUSSIAAPI_API_KEY и существующий в вашем каталоге RUSSIAAPI_TEXT_MODEL.

import { createServer } from 'node:http';

const policy = {
  token: process.env.INTERNAL_BOT_TOKEN,
  allowedModels: new Set([process.env.RUSSIAAPI_TEXT_MODEL]),
  maxChars: 4_000
};

createServer(async (req, res) => {
  if (req.method !== 'POST' || req.url !== '/assistant') return res.writeHead(404).end();
  const chunks = []; for await (const chunk of req) chunks.push(chunk);
  const input = JSON.parse(Buffer.concat(chunks).toString('utf8'));
  if (req.headers['x-internal-token'] !== policy.token ||
      !policy.allowedModels.has(input.model) || typeof input.message !== 'string' || input.message.length > policy.maxChars) {
    return res.writeHead(403, { 'content-type': 'application/json' }).end(JSON.stringify({ error: 'policy_denied' }));
  }
  const upstream = await fetch('https://russiaapi.com/v1/chat/completions', {
    method: 'POST', headers: { authorization: `Bearer ${process.env.RUSSIAAPI_API_KEY}`, 'content-type': 'application/json' },
    body: JSON.stringify({ model: input.model, messages: [{ role: 'user', content: input.message }] }), signal: AbortSignal.timeout(12_000)
  });
  if (!upstream.ok) return res.writeHead(503).end(JSON.stringify({ error: 'assistant_unavailable' }));
  const data = await upstream.json();
  res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify({ text: data.choices?.[0]?.message?.content ?? '' }));
}).listen(3000);

Пример проверяет вход до исходящего вызова и не возвращает тело ошибки gateway. В реальном сервисе добавьте аутентификацию пользователя, rate limit по tenant, ограничение длины сообщения, аудит изменения policy и отдельную очередь для длительных задач. Ограничение ключа не заменяет проверку бизнес-прав: доступ к одному model ID не означает право читать чужой проект или скачивать чужой результат.

Ротация без остановки всех интеграций

Ротация начинается с инвентаря: владелец, назначение, среда, дата выдачи и путь отзыва. Один глобальный ключ для всех сервисов делает ротацию аварией, поэтому полезно разделять внутренние токены по приложениям даже тогда, когда gateway-key один. При утечке вы отключаете конкретный внутренний токен, находите затронутые операции по безопасному ID и меняете секрет gateway по вашему процессу. Не пытайтесь «проверить» секрет, отправляя его в чат, форму или сторонний диагностический сервис.

Плановая замена обычно имеет короткий переходный период: backend умеет читать новую активную запись и, при необходимости, предыдущую только для верификации внутренних токенов; затем старая запись отзывается. Для ключа gateway используйте процедуру, которую поддерживает ваша консоль, и протестируйте замену синтетическим запросом до отключения старого значения. Практика безопасного хранения разобрана в руководстве по API key.

Проверяйте границы регулярно

Каждый релиз policy должен иметь тесты: неразрешённая модель даёт контролируемый отказ, слишком длинный ввод не доходит до gateway, токен одного tenant не читает расход другого, а журнал не содержит секрет. Периодически просматривайте неиспользуемые токены и устаревшие allowlist. Нельзя считать ключ «безопасным навсегда» только потому, что он лежит в переменной окружения: важны доступ к окружению, журналы, CI, резервные копии и процесс отзыва.

  1. Внешний ключ RussiaAPI существует только на сервере и никогда не передаётся клиенту.
  2. У каждого внутреннего клиента есть назначение, владелец и минимальная policy.
  3. Backend применяет allowlist моделей, лимит размера и бюджет до запроса.
  4. Логи содержат безопасные метаданные, но не ключ, prompt, cookie или полный ответ.
  5. Есть проверенный путь отзыва и синтетический тест после ротации.

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

Проверьте сценарий в RussiaAPI

Создайте собственный тестовый ключ в консоли, проверьте текущий каталог моделей и контракт callback, затем выполните минимальный server-side тест на синтетических данных. Расширяйте доступ и нагрузку только после измеримой проверки.

Открыть консоль RussiaAPI

FAQ

Можно ли положить ключ RussiaAPI в frontend?

Нет. Любой ключ в браузере или мобильном приложении может быть извлечён и использован вне вашей policy. Клиент обращается к вашему backend, а сервер хранит ключ gateway и применяет ограничения.

Поддерживает ли RussiaAPI права ключей?

Проверяйте текущую консоль, документацию и ваш договор. Статья описывает безопасный application-level proxy, который полезен независимо от того, есть ли у gateway отдельные scopes.

Нужен ли отдельный ключ для каждого пользователя?

Не всегда. Начните с разделения по сервису, tenant и среде. Если пользователю требуется индивидуальная квота или отзыв, связывайте её с вашей аутентификацией и внутренней policy, не выдавая ему ключ gateway.

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