Ротация API-ключей SMS без остановки отправок

API-ключ SMS даёт право отправлять сообщения и расходовать бюджет. Если он годами живёт в исходном коде, общей таблице или старом сервере, компрометацию трудно заметить, а срочный отзыв может остановить все уведомления. Ротация ограничивает срок действия секрета и одновременно проверяет, умеет ли система безопасно его заменить. Общая модель защиты канала описана в материале про безопасность SMS API.
Рабочий процесс строится так, чтобы новый и старый ключ короткое время существовали параллельно, а откат не требовал возвращать отозванный секрет.
Инвентаризация
До ротации найдите всех потребителей: production и staging, фоновые workers, CRM, 1С, резервные скрипты, CI/CD, панели мониторинга. Для каждого зафиксируйте владельца, среду, разрешения и способ доставки секрета.
Один общий ключ для нескольких систем мешает понять источник трафика и увеличивает blast radius. Где возможно, создайте отдельные сервисные учётные данные по приложениям и средам.
Где хранить ключ
Секрет не должен находиться в git, Markdown-инструкции, образе контейнера или клиентском JavaScript. Приложение получает его из менеджера секретов или защищённой конфигурации среды с минимальными правами.
OWASP Secrets Management Cheat Sheet рекомендует управлять жизненным циклом секретов централизованно: выдачей, аудитом, ротацией и отзывом. Логи должны фиксировать использование и изменения, но не само значение ключа.
Схема без простоя
Если провайдер поддерживает несколько активных ключей:
- Создать новый ключ с теми же минимально необходимыми правами.
- Сохранить его как новую версию секрета.
- Переключить один экземпляр или малую долю workers.
- Проверить приём API, message ID, DLR и метрики ошибок.
- Обновить остальные экземпляры.
- Убедиться, что старый ключ больше не используется.
- Отозвать старый ключ.
- Проверить алерт на попытку его повторного использования.
Если одновременно разрешён только один ключ, нужен согласованный maintenance-процесс или временная отдельная учётная запись. Такой риск следует выяснить при выборе провайдера, а не в день инцидента.
Как приложение выбирает ключ
Сервис читает активную версию при старте либо динамически обновляет секрет с кешированием. При динамической схеме нельзя запрашивать secret manager перед каждым SMS: его временная недоступность остановит канал и создаст лишнюю нагрузку.
Кеш должен иметь понятное время жизни и безопасное поведение. Уже работающий экземпляр может некоторое время использовать старый активный ключ, но после отзыва обязан получить новый. Метрика версии ключа не должна раскрывать секрет; достаточно внутреннего идентификатора.
Проверка отсутствия старого ключа
Поиск по репозиторию важен, но недостаточен. Проверьте переменные CI/CD, конфигурацию хостинга, архивные задачи, контейнеры, локальные файлы и аварийные runbook. На стороне провайдера полезна статистика вызовов по ключам.
После переключения выдержите окно, превышающее максимальное время жизни старых процессов и заданий. Только затем отзывайте прежний секрет, если нет признаков использования.
Аварийная ротация
При подозрении на утечку приоритет меняется: старый ключ отзывают как можно быстрее, даже если возможна краткая деградация. Runbook должен содержать контакты, способ выпуска нового ключа, перечень потребителей и план проверки.
Одновременно ограничивают бюджет и скорость, анализируют необычные получатели и объёмы, сохраняют аудит. Резкий рост отправок может быть признаком SMS pumping. Простая замена ключа без выяснения места утечки оставляет новый секрет под тем же риском.
Права и лимиты
Если API позволяет, ключ отправки не должен управлять пользователями, тарифами и другими ключами. Staging получает собственную малую квоту и не видит production. IP allowlist и отдельные роли уменьшают последствия утечки, но не заменяют ротацию.
Для редких административных операций используйте отдельные учётные данные с усиленным контролем. Чем меньше повседневный ключ умеет, тем безопаснее автоматическая интеграция.
Логи без секрета
Никогда не записывайте Authorization header, URL с ключом или дамп всей конфигурации. В журнале достаточно key ID, имени сервиса, результата аутентификации и correlation ID.
Маскирование должно происходить до передачи в централизованный лог. Фильтр только в интерфейсе не защищает исходное хранилище.
Регулярная проверка
Ротация по расписанию — это упражнение восстановления. Если процесс каждый раз требует ручного редактирования десятка серверов, архитектурная проблема обнаружится до настоящей утечки. Проводите тест в контролируемое окно и измеряйте время полного переключения.
После завершения обновляйте инвентарь, дату следующей ротации и владельца. Не оставляйте бессрочный запасной ключ «на всякий случай».
Чек-лист
- каждый ключ имеет владельца, среду и назначение;
- секреты разделены по приложениям;
- значение не хранится в коде и логах;
- новый ключ проверяется на малой доле трафика;
- видна версия ключа, но не сам секрет;
- старый ключ отзывается после подтверждения переключения;
- попытка использовать отозванный ключ вызывает алерт;
- аварийный runbook проверен заранее;
- бюджеты и права минимальны.
Итог
Ротация API-ключей SMS — часть эксплуатации, а не разовая мера после утечки. Параллельный выпуск, поэтапное переключение, наблюдение и обязательный отзыв позволяют менять секрет без простоя. Регулярный процесс одновременно уменьшает риск и показывает скрытые зависимости интеграции.