Однажды создали и забыли. Как правильно хранить и менять API-ключи? Ротация токенов и защита от утечек

36
Однажды создали и забыли. Как правильно хранить и менять API-ключи? Ротация токенов и защита от утечек

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

Масштаб проблемы хорошо показало расследование Microsoft от 5 ноября 2026 года. Злоумышленники использовали ИИ-агентов для поиска открытых credentials на GitHub. В одном случае автоматизированная атака прошла путь от обнаружения секретов до кражи данных из Azure Key Vault всего за пять минут.

На следующий день Cloudflare добавила в AI Gateway сведения о последнем использовании сохранённых ключей ИИ-провайдеров. Интерфейс помогает выявлять забытые credentials и выделяет ключи с активностью старше 90 дней. Правда, сбор статистики начался только в ноябре 2026 года, поэтому отсутствие записей пока нельзя считать доказательством неиспользования.

Чем API-ключ отличается от пароля и токена

API key представляет собой секретную строку, по которой сервис распознаёт приложение и разрешает запросы. В отличие от обычного пароля, такой ключ часто работает без дополнительного подтверждения. Если злоумышленник получит действующий API key, ему может хватить одного HTTP-запроса, чтобы воспользоваться чужими полномочиями.

Access token обычно выдаётся на ограниченный срок и подтверждает право выполнять определённые действия. Refresh token позволяет получить новый access token без повторного входа. Сервисная учётная запись, или service account, служит отдельной идентичностью приложения, а для аутентификации может применять ключ, сертификат или временный токен.

Разница напрямую влияет на безопасность. Краткоживущий access token самостоятельно утратит силу после истечения срока действия. Бессрочный API-ключ останется действительным, пока владелец не отзовёт его. Поэтому хорошая архитектура по возможности использует временные credentials вместо постоянных секретов.

Где искать забытые API-ключи и другие секреты

Самые очевидные места поиска далеко не всегда самые опасные. Разработчик может удалить ключ из исходного кода, но оставить его в истории Git. Администратор способен перенести секрет в защищённое хранилище, сохранив старую копию в контейнере или резервной конфигурации.

Начать стоит с инвентаризации всех сервисов, которые выпускают credentials. Для каждого ключа нужно определить владельца, назначение, полномочия, дату создания, срок действия и приложения, которые обращаются к сервису.

  1. Проверить панели облачных провайдеров, платных API, сервисных учётных записей и OAuth-приложений.
  2. Просканировать исходный код и всю историю Git с помощью Gitleaks, TruffleHog или GitHub Secret Scanning.
  3. Проверить конфигурации CI/CD, переменные окружения, файлы .env и журналы сборки.
  4. Изучить Docker-образы, слои контейнеров, Helm-чарты и манифесты Kubernetes.
  5. Сопоставить найденные ключи с журналами обращений и фактическими зависимостями приложений.

Для локальной проверки Git подходит открытый Gitleaks. Команда gitleaks git . сканирует историю текущего репозитория. Результаты могут содержать настоящие секреты, поэтому отчёты нельзя отправлять в общедоступные сервисы или сохранять в открытые артефакты сборки.

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

Где безопасно хранить API-ключи

Главное правило простое. Секреты не должны попадать в исходный код, публичный JavaScript, мобильные приложения или постоянные слои Docker-образов. Файл .env удобен при локальной разработке, но его необходимо исключить из Git и защитить от постороннего доступа.

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

Например, Azure Key Vault, AWS Secrets Manager и Google Cloud Secret Manager поддерживают централизованное управление секретами и разграничение доступа. Приложение получает нужное значение во время работы через защищённый механизм, а не извлекает его из опубликованного репозитория.

Для dev, staging и production нужны отдельные credentials. Каждый ключ должен иметь минимально необходимые полномочия, понятного владельца и ограниченный срок действия. По возможности лучше применять workload identity и временные токены, чтобы вообще не хранить постоянный API-ключ в приложении.

Как менять API-ключи без простоя и действовать при утечке

Плановая ротация должна учитывать зависимости между сервисами. Если провайдер позволяет одновременно держать несколько действующих ключей, приложения можно переводить постепенно. В рекомендациях OpenAI также предусмотрены сроки действия API-ключей и регулярная замена credentials до их истечения.

  1. Создать новый ключ с минимальными разрешениями и заданным сроком действия.
  2. Поместить новый секрет в защищённое хранилище, не копируя значение в код.
  3. Обновить приложения и CI/CD, перезапустить процессы или обновить кеши, где необходимо.
  4. Проверить успешные запросы, ошибки авторизации и обращения к старому ключу.
  5. После подтверждения перехода отозвать прежний ключ и убедиться, что сервисы продолжают работать.

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

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

Что утекло Первое действие Что проверить затем
Пароль Сменить пароль, завершить чужие сеансы Историю входов, MFA, другие учётные записи
API key Отозвать ключ у провайдера Запросы, расходы, доступ к данным
OAuth token Отозвать токен или разрешение приложения Refresh tokens, сеансы, выданные права
Private key Заменить ключевую пару и исключить доверие к старой Зависимые сертификаты, подписи, авторизованные ключи

Если API-ключ попал в GitHub, удаление строки новым коммитом ничего не исправит. Секрет сохранится в истории, клонах и, возможно, форках. GitHub рекомендует сначала отозвать или заменить credential. Историю при необходимости можно переписать через git-filter-repo, но операция требует согласования с командой и не гарантирует удаления всех внешних копий.

После инцидента полезно включить secret scanning и push protection, запретить публикацию секретов в CI-логах, установить оповещения об аномальных запросах и ограничить расходы на платные API. Надёжная система строится не вокруг одного безопасного хранилища, а вокруг полного жизненного цикла ключа от создания до окончательного отзыва.

Однажды создали и забыли. Как правильно хранить и менять API-ключи? Ротация токенов и защита от утечек

FAQ: часто задаваемые вопросы

Как часто нужно менять API-ключи?

Частота зависит от риска, полномочий ключа и требований провайдера. Для долгоживущих секретов задают ограниченный срок действия и плановую ротацию. При подозрении на утечку ключ отзывают немедленно.

Можно ли хранить API-ключи в файле .env?

Для локальной разработки допустимо, если файл защищён и исключён из репозитория. Для production предпочтительнее использовать Secret Manager или аналогичное хранилище.

Как узнать, используется ли старый API-ключ?

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

Что делать, если API-ключ случайно попал в GitHub?

Немедленно отозвать ключ, выпустить новый, проверить подозрительные обращения и удалить секрет из кода. При необходимости очистить историю Git, учитывая существующие клоны и форки.

Можно ли заменить API-ключ без остановки приложения?

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

API GitHub DevOps облачная безопасность токены управление секретами утечки данных
Alt text
Обращаем внимание, что все материалы в этом блоге представляют личное мнение их авторов. Редакция SecurityLab.ru не несет ответственности за точность, полноту и достоверность опубликованных данных. Вся информация предоставлена «как есть» и может не соответствовать официальной позиции компании.
Вебинар12.11 | 11:00 Гарда WAF 3.3Геораспределенная защита и отказоустойчивость веб-сервисов: прямой эфир с экспертами Гарды 12 ноября в 11:00Принять участие▸ Реклама. ООО «Гарда Технологии», ИНН 5260443081. 16+

Дэни Хайперосов

Блог об OSINT, электронике, играх и различных хакерских инструментах