суббота, 9 мая 2026 г.

API-ключ без срока жизни: почему ваша процедура увольнения ничего не значит

В пятницу вечером вы уволили разработчика. Заблокировали учётку в Yandex Cloud. Удалили из организации в VK Cloud. Отчитались перед HR — всё по регламенту. Молодцы.

В понедельник утром объектное хранилище тихо отдаёт терабайт ваших данных. Никакого взлома. Никакого фишинга. Просто у уволенного был API-ключ сервисного аккаунта, созданный полгода назад для автоматического деплоя. Ключ жив. Он никогда не умирает сам по себе. HR об этом не знает. Регламент увольнения соблюден.

Я занимаюсь информационной безопасностью больше двадцати лет. Эту историю слышал в разных вариациях десятки раз. Каждый раз компании удивляются. Потому что на бумаге всё было сделано правильно. А у уволенного сотрудника доступ к авторизованной когда-то ранее сессии в Контур.Толк еще остался.

Сначала — история, которую вы уже знаете

В 2011 году Бенджамин Делпи выпустил Mimikatz. Инструмент умеет вытаскивать NTLM-хеш пользователя из памяти процесса lsass.exe. Хеш не пароль. Но для протокола NTLM разницы нет: атакующий предъявляет хеш напрямую и ходит по домену без брутфорса, без словарей, без следов взлома. Pass-the-Hash. MITRE ATT&CK T1550.002. Работает до сих пор.

Теперь смотрите на соответствие. AWS-совместимый API-ключ в Yandex Cloud или VK Cloud — это тот же NTLM-хеш, только для облака. Вы его создали, положили в конфиг CI/CD или переменную окружения, и забыли. Атакующий нашёл и ходит по вашей инфраструктуре. Без пароля. Без MFA. Без следов взлома в привычных логах SIEM.

Есть нюанс, который часто путают. NTLM-хеш — производное от пароля, эквивалент пароля. IAM-токен в Yandex Cloud, который живёт 12 часов, — аналог Kerberos Ticket, выданная сессия. Статический API-ключ опаснее обоих: он не протухает, не зависит от активной сессии пользователя и работает из любой точки планеты через обычный HTTPS.

В Active Directory скомпрометированный хеш работал внутри периметра домена. API-ключ российского облака работает из Берлина, Дубая и Бангкока одинаково хорошо. Это качественный скачок в радиусе поражения.

Реальный пример: Snowflake, 165 жертв, 2024 год

В мае 2024 года группа ShinyHunters получила доступ к аккаунтам 165 компаний в облачном хранилище Snowflake. Среди жертв: Ticketmaster (560 миллионов записей покупателей), банк Santander (30 миллионов клиентских аккаунтов), телеком-гигант AT&T.

Компания Mandiant расследовала инцидент. Вывод оказался неудобным: никакой уязвимости в самом Snowflake не было. Все пострадавшие аккаунты работали без многофакторной аутентификации. Учётные данные были украдены инфостилерами у сотрудников и подрядчиков — в ряде случаев эти данные не менялись несколько лет. Группировка UNC5537 просто взяла то, что давно утекло, и авторизовалась.

Это не взлом в привычном смысле. Это авторизованный вход с чужими реквизитами. Именно такую картину SIEM показывает как «норму».

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

Главная болезнь: «сиротские» ключи

В облаке у API-ключа обычно нет поля «Владелец». Есть поле «Создатель» — технический атрибут, дата и ID сервисного аккаунта. Когда IAM-инженер выгружает список из 500 ключей, он не видит, кто это создал, зачем и что сломается при удалении.

Именно поэтому ключи боятся удалять. «А вдруг упадёт деплой в продакшне?» Так появляются «сиротские» ключи: технически живые, практически бесхозные, потенциально опасные.

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

Три истории, которые вы узнаете

История первая. Забытый скрипт. Лид DevOps уволился по-хорошему, без конфликтов. Через полгода финансовый отдел заметил аномальный счёт за исходящий трафик. Расследование показало: его API-ключ работал в скрипте, который каждое воскресенье зеркалировал базу транзакций во внешнее хранилище. Скрипт никто не трогал — он просто работал. Ключ никто не отзывал — он просто жил. Обнаружили только по счёту. Сколько воскресений прошло до обнаружения — посчитайте сами.

История вторая. Публичный снапшот. Разработчик сделал публичный образ диска в облаке, чтобы передать коллеге тестовую среду. Забыл, что в образе лежит файл .aws/credentials с ключами доступа к объектному хранилищу. После его увольнения образ остался публичным. Боты-сканеры, которые непрерывно индексируют публичные облачные ресурсы, нашли ключи через два часа. Такие инструменты работают в реальном времени, и подобные инциденты фиксируются постоянно.

История третья. Матрёшка Terraform. Terraform хранит состояние инфраструктуры в файле terraform.tfstate. Этот файл обычно лежит в S3-совместимом объектном хранилище — в том же бакете, доступ к которому прописан в коде проекта. В самом файле в открытом виде лежат все секреты, которые Terraform когда-либо передавал разворачиваемым сервисам: пароли баз данных, ключи API, токены. Один забытый ключ к этому бакету открывает всё.

Здесь есть ещё один конфликт интересов, который часто игнорируют: доступ к состоянию инфраструктуры и право на изменение инфраструктуры — принципиально разные уровни привилегий. На практике они часто достаются одному человеку. Когда он уходит, об этом разграничении никто не вспоминает.

Российские облака: что я нашёл в документации

Yandex Cloud. Документация прямо говорит: IAM-токены живут 12 часов. Разумно. Но API-ключи, авторизованные ключи и статические ключи, совместимые с AWS API, не имеют срока действия. Вендор рекомендует ротацию раз в 90 дней по стандарту PCI DSS. Рекомендует, не требует. Принудительного TTL нет. Я не видел ни одной российской организации, у которой была бы автоматизированная ротация статических ключей Yandex Cloud.

VK Cloud. В октябре 2024 года запущен Cloud Audit — мониторинг событий безопасности в реальном времени. Полезный инструмент. Автоматического отзыва API-ключей при деактивации пользователя-создателя в публичной документации нет. Рекомендация простая: запросите у службы поддержки письменно — «Что происходит с ключами сервисных аккаунтов при блокировке пользователя?» Ответ зафиксируйте в регламентах. Если вендор не описывает поведение системы при увольнении сотрудника, вы не можете на это поведение полагаться.

Selectel. Один из старейших российских провайдеров с большой базой клиентов на классических API-ключах. Ключи создаются на уровне проекта, и после увольнения сотрудника связь «чей это ключ» теряется быстро: проект продолжает жить, ключи продолжают работать.

MTS Web Services. Активно развивает гранулярный IAM. Если ваша организация использует интеграцию с внешним IdP через SAML или AD FS, проверьте задержку синхронизации групп. Синхронизация с задержкой в несколько часов превращает окно между увольнением и реальной блокировкой доступа в открытую дверь.

Cloud.ru. Документация по управлению жизненным циклом ключей в открытом доступе минимальна. Это само по себе риск: если вендор не описывает поведение системы при отзыве доступа, строить на этом регламенты нельзя.

Конфликт IAM и SOC, о котором не принято говорить

В большинстве компаний IAM и SOC живут отдельно и разговаривают редко. IAM считает своей задачей выдать доступ. SOC считает, что IAM отвечает за идентичность. В результате никто не отвечает за жизненный цикл ключа после того, как его создатель уволился.

IAM-инженер создал ключ — его задача выполнена. SOC мониторит события — легитимный API-вызов с корректным ключом не триггерит алерт. Процесс мёртв. Ключ жив.

Большинство компаний измеряет Mean Time to Detect — время обнаружения атаки. Почти никто не измеряет другое: сколько времени инфраструктура продолжает доверять уже уволенному человеку через его забытые ключи. Первая метрика говорит, как быстро вы увидели проблему. Вторая — как долго проблема работала после того, как вы её увидели.

Исправляется это организационно. Введите роль Token Lifecycle Owner. Обычно это IAM-архитектор, но отчитывается он перед CISO. Его задача: раз в квартал инвентаризировать ключи, сверять создателей с HR-списком уволенных, удалять осиротевшие. Внесите в регламент увольнения отдельный пункт: «Сотрудник ИБ проверяет и документирует факт отзыва всех API-ключей сервисных аккаунтов, которыми пользовался уволенный. Без подписи — процедура не закрыта».

И один юридический момент, который дисциплинирует даже добросовестных людей. В соглашении о расторжении или в NDA пропишите явно: использование технических доступов после даты увольнения квалифицируется как неправомерный доступ к компьютерной информации по статье 272 УК РФ. Это не угроза — это напоминание. Человек, который «просто оставил скрипт работать», должен понимать юридические последствия.

Что сделать в понедельник до обеда

Yandex Cloud — инвентаризация через CLI. Команды работают для одного сервисного аккаунта; для полного охвата папки повторите для каждого SA из списка или используйте цикл в bash:

# Список всех сервисных аккаунтов в папке
yc iam service-account list --folder-id <folder-id>

# API-ключи конкретного сервисного аккаунта
yc iam api-key list --service-account-id <sa-id>

# Авторизованные ключи
yc iam key list --service-account-id <sa-id>

Выгрузите результат. Найдите ключи старше 90 дней. Сверьте создателей с HR-списком уволенных за этот период. Ключи, которые боитесь удалять — сначала проверьте: если сервис работает без ключа, он давно не используется.

Тест скорости отзыва. Создайте тестовый сервисный аккаунт и сгенерируйте именно API-ключ командой yc iam api-key create, не авторизованный ключ — это разные объекты с разным кешированием. Выполните тестовый запрос, убедитесь, что он проходит. Удалите ключ в консоли. Засеките время до появления ошибки 403 при повторном запросе. У ряда провайдеров кеширование даёт до 15 минут задержки. Это ваше окно атаки — зафиксируйте цифру для руководства.

VK Cloud. Включите Cloud Audit. Настройте нотификацию на событие создания нового API-ключа. Любой новый ключ должен попадать в SIEM или хотя бы на почту IAM-команды. Это 20 минут работы.

SOC. Добавьте правило: массовое скачивание из объектного хранилища от сервисного аккаунта, нетипичное для его исторического поведения — триггер для расследования. Не ждите алерта на «подозрительный IP». Смотрите на аномалию внутри сессии.

GitHub-репозитории уволенных. Попросите HR включить в чек-лист увольнения пункт: проверить публичные репозитории сотрудника на GitHub и GitLab за последние 30 дней активности. Люди, которые уходят и хотят «сохранить наработки», часто в последние дни пушат конфиги со всем, что там лежало. Инструменты типа truffleHog и gitleaks автоматизируют поиск секретов в публичных репозиториях по имени пользователя.

Terraform-бакеты. Проверьте, кто имеет доступ к бакету с файлами terraform.tfstate. Права на чтение этого файла и права на изменение инфраструктуры — это разные уровни привилегий, которые не должны принадлежать одному человеку и уж точно не должны оставаться у уволенного.

Почему автоматическую ротацию нужно строить сейчас

Количество сервисных аккаунтов в инфраструктуре растёт само по себе. Каждый новый CI/CD пайплайн, каждая межсервисная интеграция, каждый микросервис требует своих ключей. Через год их будет в три раза больше, чем сейчас. Ручная квартальная инвентаризация перестанет работать физически.

HashiCorp Vault или облачный Secret Manager с коротким TTL решают проблему архитектурно: ключ живёт 24 часа, ротируется автоматически, никогда не попадает в Git и не задерживается в памяти CI/CD дольше нужного. Если этого нет сейчас — внесите в roadmap на ближайший квартал. Иначе через год вы будете проводить инвентаризацию тысячи ключей вместо сотни.

Новые метрики, которых нет на вашем дашборде

Старые KPI придуманы под периметровую защиту. Для работы с облачными ключами нужны другие.

Percentage of Non-Rotated Keys — доля ключей без ротации более 90 дней. Orphaned Key Count — ключи, чьи создатели уволились. Dormant Service Account Exposure — сервисные аккаунты, неактивные более 30 дней, с живыми ключами. Time to Key Revocation — время от блокировки пользователя до удаления его ключей. tfstate Exposure Rate — процент Terraform-бакетов с широким или публичным доступом.

Если ни одна из этих метрик не измеряется — вы не знаете реального состояния своей облачной идентичности.

Итог

Pass-the-Hash двадцать лет назад показал простую вещь: не нужно знать пароль, если у тебя есть то, чему система доверяет так же, как паролю. API-ключ без срока жизни — та же история. Другой протокол, другой интерфейс, тот же принцип.

Snowflake потерял данные 165 компаний не потому что был взломан. Потому что учётные данные клиентов годами не менялись. В российских облаках та же картина — только публичных отчётов об инцидентах нет. Это не означает, что инцидентов нет.

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