Как защитить ключи API в вашем приложении
Чтобы защитить ключи API, храните их как секреты или переменные окружения на хостинге, используйте только в серверном коде и никогда не вставляйте в чат, файлы кода, скриншоты или Git-репозиторий. Давайте каждому ключу минимально необходимые права, задавайте лимиты расходов у провайдера, а если ключ когда-либо утёк — перевыпускайте его: создайте новый и удалите старый, вместо того чтобы просто спрятать место, где он появился.
Ключ API — это пароль к сервису. Ваш ключ OpenAI позволяет кому-то тратить ваши деньги на ИИ; секретный ключ Stripe — оформлять возвраты; ключ почтового сервиса — отправлять письма от вашего имени. ИИ-конструкторы хорошо подключают такие ключи, но не всегда внимательно следят, куда они попадают, поэтому это руководство о том, как их защитить и как проверить.
Публичные ключи и секретные ключи
Не каждый ключ секретный. Если понимать разницу, не будешь паниковать из-за неправильного ключа и игнорировать правильный.
| Тип | Примеры | Можно ли в браузере? |
|---|---|---|
| Публикуемые / публичные ключи | Ключ Stripe pk_…, ключ карт, ограниченный вашим доменом, некоторые ID аналитики | Да — так и задумано |
| Секретные ключи | Stripe sk_…, ключи OpenAI и Anthropic, ключи почтовых сервисов, пароли к базе данных | Никогда |
| Служебные / административные ключи | Ключи, которые обходят правила доступа к хостед-базе данных | Никогда — относитесь как к самым чувствительным |
Если не уверены, к какому типу относится ключ, проверьте документацию провайдера. Если сомневаетесь — считайте ключ секретным.
Шаг 1. Храните ключи в секретах, а не в коде
Ключи должны храниться в переменных окружения или секретах вашего хостинга. Код читает их по имени во время работы (например, process.env.OPENAI_API_KEY), поэтому значение никогда не появляется в ваших файлах. О том, что такое переменные окружения и секреты, — в статье что такое переменные окружения и секреты.
Перенеси каждый ключ API из кода в переменные окружения. Перечисли каждый найденный ключ, файл, в котором он был, и имя переменной, которое ты использовал. Не показывай значения.
Затем убедитесь, что ничего не осталось:
Поищи во всём проекте, включая конфигурационные файлы и любые .env-файлы, всё, что похоже на ключ API или пароль. Укажи файл и строку, но не значение.
Шаг 2. Используйте секретные ключи только на сервере
Это самое важное правило. Всё, что получает браузер, может прочитать посетитель: исходный код страницы и JavaScript-файлы видны в инструментах разработчика.
Поэтому, если приложению нужно обратиться к OpenAI, браузер должен обращаться к вашему серверу, а сервер — к OpenAI с ключом. Ключ никогда не покидает сервер.
Функция чата вызывает OpenAI напрямую из браузера. Перенеси этот вызов в серверный API-маршрут, который читает OPENAI_API_KEY из окружения. Браузер должен обращаться только к нашему маршруту. Требуй вход в систему для этого маршрута.
Обратите внимание на одну частую ловушку во фреймворках фронтенда: переменные с публичным префиксом — VITE_ в Vite, NEXT_PUBLIC_ в Next.js — намеренно встраиваются в код браузера. Секретный ключ с таким префиксом открыт, даже если он «в переменной окружения».
Шаг 3. Проверьте, что ничего не утекает
Не полагайтесь на то, что всё сработало, — проверьте живой сайт:
- Откройте опубликованное приложение в браузере.
- Откройте инструменты разработчика, затем вкладку Sources или Network.
- Поищите по файлам первые символы каждого секретного ключа (например,
sk_илиsk-). - Проверьте сетевые запросы приложения. Запрос, который идёт прямо из браузера к платному ИИ-провайдеру, — тревожный знак.
Если нашли секретный ключ, перенесите его на сервер (шаг 2) и перевыпустите (шаг 6), потому что он уже был публичным.
Шаг 4. Ограничьте, что может делать каждый ключ
Многие провайдеры позволяют ограничить ключ:
- Ограниченные ключи с правами только на то, что нужно приложению. Stripe, например, поддерживает ограниченные ключи с конкретными разрешениями.
- Ограничения по домену или IP для ключей, которые должны быть публичными, например ключей карт.
- Отдельные ключи для каждого приложения и каждой среды, чтобы одна утечка не открыла всё, а отзыв одного не сломал остальные.
- Тестовые ключи во время разработки, а боевые — только в опубликованном приложении.
Шаг 5. Ограничьте ущерб
Даже хорошо защищённый ключ может быть использован во зло через ваше же приложение — например, если кто-то скриптом вызывает вашу функцию ИИ тысячи раз.
- Установите лимиты расходов или уведомления у каждого платного провайдера.
- Требуйте вход в систему для любой функции, которая стоит денег за каждый вызов.
- Добавьте лимит запросов на пользователя. См. что такое ограничение частоты запросов.
Добавь лимит 30 запросов к ИИ на пользователя в час для /api/chat. Возвращай понятное сообщение, когда лимит достигнут. Отклоняй запросы от пользователей, которые не вошли в систему.
Шаг 6. Перевыпускайте утёкшие ключи
Если секретный ключ появился там, где ему не место, — в сообщении чата, коммите, скриншоте, обращении в поддержку, коде браузера, — считайте его скомпрометированным.
- Создайте новый ключ у провайдера.
- Обновите секрет в настройках приложения.
- Пересоберите или опубликуйте приложение заново, чтобы живое приложение использовало новый ключ.
- Удалите старый ключ у провайдера.
- Проверьте журналы использования у провайдера на активность, которую вы не узнаёте.
Удаления сообщения в чате или коммита в Git недостаточно. История Git хранит старые версии, а всё публичное могло уже быть скопировано.
Частые ошибки
- Вставка ключа в промпт. Теперь он в истории чата. Используйте форму для секретов.
- Публичный префикс у секретной переменной.
VITE_OPENAI_API_KEYотдаёт ключ каждому посетителю. - Коммит файла
.env. Убедитесь, что он в.gitignoreдо первой отправки. - Один ключ везде. Используйте разные ключи для тестовой и боевой среды и для каждого приложения.
- Нет лимита расходов. Утёкший или злоупотребляемый ключ без ограничения может накрутить большой счёт до того, как вы заметите.
- Прятать вместо перевыпуска. Однажды открытый ключ исправляет только новый ключ.
- Ключи на скриншотах. Обрежьте или размойте страницы настроек, прежде чем показывать их ради помощи.
Чек-лист
- Каждый ключ хранится как секрет или переменная окружения, а не в коде.
- Файл
.envи ключи не закоммичены в Git. - Секретные ключи используются только в серверном коде.
- Ни одна секретная переменная не имеет публичного префикса вроде
VITE_илиNEXT_PUBLIC_. - Я искал в JavaScript живого сайта префикс каждого ключа и ничего не нашёл.
- Ключи ограничены по правам там, где провайдер это позволяет.
- Тестовые и боевые ключи разделены.
- Платные функции требуют входа и имеют лимиты на пользователя.
- У каждого платного провайдера есть лимит расходов или уведомление.
- Я знаю, как перевыпустить каждый ключ, и все ключи, которые когда-либо были открыты, перевыпущены.
Защита ключей на Mythex
Mythex держит ключи вне вашего кода и чата двумя способами:
- Карточка запроса секретов. Когда агенту нужен ключ, он показывает карточку в чате, где вы вводите значение в полях формы, а не в поле сообщения, и оно сохраняется как секрет проекта. См. Секреты в чате.
- Настройки проекта → Secrets, или
/secretsв чате, чтобы добавлять или менять ключи самостоятельно. См. Переменные окружения и секреты.
После изменения секрета у опубликованного приложения опубликуйте его снова, чтобы живое приложение его подхватило. При экспорте проекта секреты не выгружаются, поэтому добавьте их заново там, где будете запускать код дальше. Если ключ когда-либо появился в чате, перевыпустите его у провайдера.
Для остальной проверки безопасности перед запуском пройдите чек-лист безопасности для приложений, созданных с ИИ. Если добавляете функции ИИ, как использовать LLM API подробнее раскрывает ключи и расходы.
Вопросы
Безопасно ли помещать ключ API в код фронтенда?
Только если провайдер сам задумал этот ключ как публичный, например публикуемый ключ Stripe или ключ карт, ограниченный вашим доменом. Любой ключ, который может тратить деньги или читать приватные данные, должен оставаться на сервере, потому что всё, что отправлено в браузер, может прочитать кто угодно.
Что делать, если я вставил ключ API в чат или в публичный репозиторий?
Перевыпустите его: создайте новый ключ у провайдера, обновите секреты приложения, опубликуйте снова и затем удалите старый ключ. Удаления сообщения или коммита недостаточно, потому что копии уже могли появиться.
Где хранить ключи API?
В настройках переменных окружения или секретов вашего хостинга, которые читает серверный код во время работы. Их не нужно записывать в исходные файлы, коммитить в Git или показывать на скриншотах.
Как проверить, не утёк ли ключ API на моём сайте?
Откройте живой сайт, посмотрите исходный код страницы и JavaScript-файлы в инструментах разработчика браузера и поищите начало ключа. Если он там есть, ключ открыт, его нужно перенести на сервер и перевыпустить.