Ротация ключей и токенов
1) Зачем нужна ротация
Ключи и токены неизбежно «стареют»: экспозиция в логах/бэкапах, инсайдерские риски, уязвимости библиотек, утечки у партнеров. Ротация снижает «время жизни риска» и дает управляемость при инцидентах. Цель — построить предсказуемые циклы ротации и механизмы быстрого отзыва без простоя.
2) Область: что именно ротируем
Ключи подписи/шифрования: JWT (JWS/JWE), OAuth/OIDC, SAML, вебхуки (HMAC), лицензии.
Секреты интеграций: API-ключи, client secret, пароли тех. пользователей.
TLS/mTLS: серверные/клиентские сертификаты, корневые/промежуточные CA.
Ключи данных: KEK/CMK в KMS/HSM, DEK (envelope encryption).
Токены: access/refresh, service-to-service (mTLS, HMAC), short-lived session.
3) Хранение, версии, метки
KMS/HSM/Vault как источник правды. Запрещено хранить приватные ключи в git/ENV/файлах образов.
Версионирование: `key_id`/`version` + метки: `purpose=jwt-sign`, `env=prod`, `alg=ES256`, `created_at`, `rotates_at`.
Политики доступа: принцип минимально необходимых прав (least privilege), разделение обязанностей (SoD).
Аудит: кто создал/читал/подписывал; неизменяемые журналы.
4) Базовые паттерны ротации
4.1 Перекрывающиеся окна (graceful rollover)
Новый ключ → публикуем в JWKS/распространяем сертификат.
Окно перекрытия: валидация старыми и новыми ключами, подпись — только новым.
После истечения grace-периода — удаляем старый из доверенного набора.
4.2 Двойной выпуск (dual-run)
Короткий период, когда часть инстансов подписывает старым, часть — новым (для крупных флитов).
Требует строго синхронизированного JWKS и мониторинга доли валидаций по `kid`.
4.3 Rotate-on-schedule vs rotate-on-use
По расписанию: раз в N дней/недель (ключи подписи, TLS).
При использовании: refresh-токены — одноразовые, на каждый обмен выпуск нового («скользящая» ротация).
5) JWT/JWKS: практика
5.1 Заголовки и идентификаторы
Используйте `kid` в JWS-заголовке для выбора ключа верификации.
Минимум клаймов, короткое `exp`, корректные `aud/iss/nbf`.
json
{ "alg": "ES256", "kid": "jwt-2025-10", "typ": "JWT" }
5.2 Публикация JWKS
JWKS должен содержать все активные ключи проверки (старый + новый в окно grace).
Кэширование JWKS у клиентов: короткий TTL (например, 5–15 мин).
При компрометации — удалить скомпрометированный ключ из JWKS (резко), форс-инвалидация кэша.
json
{
"keys": [
{ "kty":"EC","crv":"P-256","kid":"jwt-2025-10","use":"sig","alg":"ES256","x":"...","y":"..." },
{ "kty":"EC","crv":"P-256","kid":"jwt-2025-07","use":"sig","alg":"ES256","x":"...","y":"..." }
]
}
5.3 Каденс и сроки
Подпись JWT: ротация ключа каждые 3–6 мес (или чаще для high-risk).
`exp` access-токена: 5–30 мин; refresh — 7–30 дней (с «rotate-on-use»).
Принудительное «склеивание» с PoP/DPoP (см. §8) для снижения риска угона.
6) Ротация HMAC (вебхуки/подписи)
Храните активный и канареечный секреты; принимайте подписи обоими.
Заголовки: `X-Signature` + `X-Timestamp`; ограничение окна ±300с.
Полное отключение старого — после того, как отправитель подтвержденно переключился.
Для партнеров: публикуйте дату-время переключения и endpoint проверки.
7) TLS/mTLS и цепочки доверия
ACME/auto-renew для публичных серверных сертификатов (Let’s Encrypt или корпоративный CA).
mTLS: короткие клиентские сертификаты (7–30 дней), автоматическая ротация по каналам (SPIFFE/SPIRE/mesh).
Ротация промежуточного/корневого CA — только через перекрывающиеся якоря доверия (trust bundle) и длительный canary.
Следите за OCSP/CRL и clock-skew. В логи — причины отказа валидации.
8) PoP/DPoP и связка токен↔ключ клиента
DPoP (Demonstration of Proof-of-Possession): токен привязан к public-key клиента; снижает риск replay.
Ротация ключа клиента = выпуск нового DPoP-ключа, токенов — на короткий срок.
Для сервис-к-сервису предпочтителен mTLS (устройство/воркер «несет» ключ в HSM/TPM).
9) Refresh-токены: rotate-on-use
Одноразовые refresh-токены: каждый обмен → новый refresh + access.
Список отозванных `jti`/`sid` хранить с TTL = срок жизни refresh.
Детект повторного использования (ре-плей): немедленный отзыв сессии/устройства, алерт.
10) Отзыв и списки блокировки
JWT без интроспекции: используйте короткий `exp` + «черные списки» `jti` для критичных кейсов (локально/в Redis, шардирование по хешу).
OAuth introspection: централизованный сервер статусов; кэшируйте «active=false/true» с коротким TTL.
API-ключи: храните хэш ключа (как пароли), метки владельца/тенанта, scope, дата создания/последнего доступа; отзыв — мгновенно.
11) Ключи данных: envelope-шифрование
CMK/KEK (KMS/HSM) защищает DEK; ротация CMK происходит без перераскрытия данных: пере-wrap DEK.
DEK для каждого объекта/тенанта/партиции; KDF/HKDF для производных ключей.
Политики уничтожения (crypto-shredding): удаление KEK = нечитабельность данных при компрометации.
12) Процедуры инцидентов (компрометация)
1. Заморозить: отключить выпуск токенов на скомпрометированном ключе, перевести выдачу на новый.
2. Отозвать: удалить `kid` из JWKS, отозвать сертификаты (OCSP/CRL), заблокировать API-ключи по списку.
3. Сократить TTL: временно уменьшить `exp` токенов, усилить проверку PoP/DPoP.
4. Принудительный logout: инвалидировать сессии (revoke `sid`/`jti`).
5. Форензика и отчетность: таймлайны, охват, кто/что пострадал; обновить плейбуки.
13) Пайплайн и rollout
13.1 Генерация и публикация
Генерируйте ключи в HSM/KMS; экспорт приватного ключа — запрещен.
Автоматическая публикация JWKS/сертификатов с верификацией и тестами.
Канареечный релиз: 1–5% клиентов → 100%.
13.2 Контроль здоровья
Метрики: доля валидаций по `kid`, ошибки подписи/сертификата, дрейф часов.
Алерты: всплеск 401/403 из-за подписи, OCSP/CRL недоступен, истекающие сертификаты (T-30/T-7/T-1).
14) Конфиги и примеры
14.1 Пример политики Vault/KMS (псевдо)
hcl path "transit/keys/jwt-prod" {
capabilities = ["read," "update," "list"] # signature/rotation
}
path "transit/keys/jwt-prod/rotate" {
capabilities = ["update"]
}
14.2 Пример плана ротации JWT
T0: create a new version of the key (kid = jwt-2025-10), add to JWKS
T0 + 15m: start signing with a new kid; validate with old and new
T0 + 7d: remove old kid from JWKS
T0 + 30d: delete old private key from KMS (schedule purge)
14.3 Envoy: принудительное обновление JWKS (псевдо)
yaml jwt_authn:
providers:
oidc:
issuer: https://auth. example. com/
remote_jwks:
http_uri:
uri: https://auth. example. com/.well-known/jwks. json cluster: jwks_cluster timeout: 2s cache_duration: 300s # короткий TTL
15) Наблюдаемость и аудит
Метрики: `jwt_verify_fail_total{reason}`, `jwks_refresh_total`, `jwks_kid_share{kid}`, `token_revoked_total`, `refresh_rotations_total`, `dpop_fail_total`.
Логи: `kid`, `jti`, `sid`, `reason`, `client_id`, `tenant`, `trace_id` (без PII).
Дашборды: карта долей `kid`, истекающие сертификаты, частота отзыва, невалидные подписи по регионам.
16) Антипаттерны
Долгоживущие JWT без отзыва и без короткого `exp`.
Отсутствие `kid` и «ручной» подбор ключа проверки.
Хранение секретов в ENV/k8s-Secret без KMS и без шифрования на уровне etcd.
Неротационные refresh-токены; повторное использование refresh без детекта.
Единый глобальный API-ключ «на всех».
«Тихий» выпуск новых ключей без публикации JWKS и мониторинга.
Нулевые окна перекрытия (мгновенная замена) → массовые 401/403.
17) Специфика iGaming/финансов
Регуляторы и аудит: неизменяемые логи ротаций/отзывов; доказуемость времени и акторов.
Партнерские PSP/KYC: отдельные ключи на партнера/юрисдикцию; быстрый отзыв при нарушениях SLA/безопасности.
Многоарендность: per-tenant API-ключи со scope; изоляция ключей брендов/регионов.
Высокий риск: PoP/DPoP для критичных операций, короткие `exp`, mTLS между внутренними сервисами.
Backoffice: SSO/OIDC, короткие сессии, аппаратные токены (FIDO2), повсеместный rotate-on-schedule.
18) Чек-лист prod-готовности
- Все приватные ключи в KMS/HSM/Vault; запрещен экспорт.
- JWKS публикуется и кэшируется с коротким TTL; в заголовках JWT есть `kid`.
- План ротации с перекрывающимся окном и автоматическим rollout.
- Refresh-токены одноразовые; список отозванных `jti` с TTL.
- HMAC-секреты: активный+канареечный; прием обеими; объявлено T-время переключения.
- TLS/mTLS: auto-renew, алерты T-30/T-7/T-1, trust bundle для смены CA.
- Envelope-шифрование: KEK/CMK ротируются без простоя, DEK per-объект/тенант.
- Метрики/алерты по подписи, JWKS, отзывам; дашборды `kid`-долей.
- Плейбук инцидентов (компрометация) и регулярные учения.
- Тесты canary и реплей валидаций с новыми ключами/CA.
19) TL;DR
Держите ключи в KMS/HSM, подписывайте JWT с `kid` и публикуйте JWKS. Ротируйте ключи и сертификаты с перекрытием, следите за долями валидаций по `kid`. Refresh — rotate-on-use и короткие `exp`; для критичных операций — PoP/DPoP и mTLS. Для данных используйте envelope-шифрование с ротацией KEK без простоя. Внедрите метрики/алерты, плейбуки инцидентов и регулярные канареечные ротации.