S2S-аутентификация
S2S-аутентификация доказывает, какой именно сервис/ворклоад делает запрос, и дает ему минимально необходимые права на ограниченное время. В отличие от пользовательских потоков, здесь нет человека — поэтому критичны короткий срок жизни учетных данных, криптографическая привязка к ворклоаду/каналу и четкая наблюдаемость.
1) Цели и принципы
Zero Trust по умолчанию: не доверять сети, только аттестации ворклоада и криптографии.
Короткоживущие креденшлы: минуты, а не дни/месяцы.
Привязка к контексту: tenant/region/licence/audience/scopes.
Централизованная выдача, децентрализованная проверка: STS/IdP + локальная верификация.
Минимальные привилегии и явное делегирование: только нужные скоупы и аудит.
Ротация «без боли»: dual-key/dual-cert окна и автоматизация.
2) Модель угроз (минимум)
Кража долговечных секретов (API-keys, long-lived RT).
Подмена сервиса внутри VPC/кластера.
Межрегионные атаки при сломанной сегментации.
Replay/подмена трафика на прокси.
Supply-chain/подмена образа контейнера.
Ошибки конфигурации (широкие правила firewall/mesh, общий JWKS для всех).
3) Базовые паттерны S2S
3.1 mTLS (взаимные сертификаты)
Кто вы: доказывает каналом.
Сертификаты короткоживущие (час-сутки) из внутренней PKI; выпуском/ротацией управляет mesh/sidecar или SPIRE-агент.
Хорош для «соседей» в одном trust-домене и для binding токенов.
3.2 Сервисные JWT (STS)
Кто вы: доказывает сообщением.
Короткий Access JWT (2–5 мин) с `aud`, `scp`, `tenant`, `region`.
Подписывает KMS/HSM, публичные ключи — через JWKS с `kid` и ротацией.
Проверка локально (без сетевого вызова IdP).
3.3 SPIFFE/SPIRE (SVID)
Универсальная идентичность ворклоадов: `spiffe://trust-domain/ns/<ns>/sa/<sa>`.
Автоматический issuance/rotation X.509/JWT-SVID, интеграция с Istio/Linkerd.
3.4 OAuth 2.1 Client Credentials / Token Exchange (RFC 8693)
Машинные клиенты получают токен от STS; для действий «от имени» пользователя — OBO (token exchange).
Комбинируем: mTLS для канала, JWT для сообщения, SPIFFE — для устойчивых идентичностей.
4) Референс-архитектура
[KMS/HSM] [Policy Store / PDP]
[STS/IdP (issuer)] ── JWKS ──[Gateway/PEP] ─────[Services/PEP]
│
SVID/JWT │ │ │ │
(SPIRE/Istio)│ mTLS/DPoP │ mTLS/DPoP
│ │ │ │
[Workload/Sidecar]─────────┴───────┴────────────┘
Issuer (STS/IdP): выпускает короткие сервисные JWT/СVID, публикует JWKS.
Gateway (PEP): термин сети, валидирует mTLS/JWT, обогащает контекстом, запрашивает PDP.
Services (PEP): повторная проверка (defense in depth), кэш решений PDP.
SPIRE/mesh: авто-сертификаты и SVID для mTLS.
5) Формат сервисного JWT (пример)
json
{
"iss": "https://sts. core",
"sub": "svc. catalog, "//service identity
"aud": ["svc. search"] ,//target service/domain
"exp": 1730390100, "iat": 1730389800,
"tenant": "brand_eu",
"region": "EE",
"scp": ["catalog:read:public","catalog:read:tenant"],
"mtls": { "bound": true, "spiffe": "spiffe://core/ns/prod/sa/catalog" }
}
Подписан ES256/EdDSA, `kid` указывает активный ключ.
Опционально binding к каналу: флаг, hash cert, SVID.
6) Политики выдачи (STS) и верификация
Выдача:- Subject берется из SVID/клиентского сертификата/регистра клиента.
- Срок жизни 2–5 мин, refresh нет — вместо этого заново просить STS.
- Скоупы/аудитории берутся из Policy Store (GitOps), а не из запроса клиента.
1. Проверить mTLS (опционально) и валидность цепочки.
2. Проверить подпись JWT по JWKS (по `kid`).
3. Сверить `exp/nbf/iss/aud`, tenant/region/licence.
4. Обогатить контекст и спросить PDP (RBAC/ABAC/ReBAC).
5. Кэшировать решение PDP (TTL 30–120 c), инвалидация по событиям.
7) Мульти-тенант и регионы (trust domains)
Разделяйте trust-domain’ы: `spiffe://eu.core`, `spiffe://latam.core`.
Раздельные JWKS/PKI по регионам; межрегион — только через доверенные шлюзы.
Включайте в клеймы `tenant/region/licence` и проверяйте соответствие ресурсу.
Логи/аудит сегментируйте по тенантам и регионам.
8) Mesh/sidecar и без-mesh режим
Istio/Linkerd: mTLS «из коробки», policy-enforcement на уровне L4/L7, интеграция со SPIRE.
Без mesh: библиотека-клиент + mutual TLS в приложении; сложнее управлять ротацией — автоматизируйте через агента.
9) Ключи, JWKS и ротация
Приватные ключи только в KMS/HSM; подпись — удаленным вызовом/аппаратом.
Rotation каждые N дней; dual-key: старый+новый принимаются, issuer подписывает новым после прогрева кешей.
Мониторинг: доля потребления по `kid`, «зависшие» клиенты на старом ключе.
yaml issuer:
jwks:
alg: ES256 rotation_days: 30 publish_cache_ttl: 60s sts:
access_ttl: 5m audience_policies:
- subject: "svc. catalog"
allow: ["svc. search","svc. wallet"]
scopes: ["catalog:read:"]
tenancy:
claims: ["tenant","region","licence"]
jwks_per_region: true
10) Привязка к каналу (DPoP/mTLS-bound)
mTLS-bound tokens: в JWT добавлять hash клиентского сертификата; на приеме сверять.
DPoP: для HTTP-клиентов без mTLS — подписывать каждый запрос DPoP-ключом, в AT помещать thumbprint DPoP.
11) Ошибки и политика возврата
Стандартизируйте коды:- `401 INVALID_TOKEN`/`EXPIRED_TOKEN`/`AUD_MISMATCH`.
- `401 MTLS_REQUIRED`/`MTLS_CERT_INVALID`.
- `403 INSUFFICIENT_SCOPE`/`POLICY_DENY`.
- `429 RATE_LIMITED`.
Ответ содержит machine-readable `error_code` и `as_of` (версия ключа/политики).
12) Наблюдаемость и аудит
Метрики:- `s2s_auth_p95_ms`, `verify_jwt_p95_ms`, `jwks_skew_ms`,
- `invalid_token_rate`, `aud_mismatch_rate`, `insufficient_scope_rate`,
- потребление по `kid`, доля mTLS-bound запросов.
- `subject`, `aud`, `tenant`, `region`, `scp`, `kid`, `sid/svid`, `decision`, `policy_version`, `trace_id`.
- Выдача токенов, ротации ключей, изменения политик, отклоненные запросы.
13) Производительность
Верификация JWT — локально, JWKS кэшируйте (TTL 30–60 с) с фоновым обновлением.
X.509-цепочки — пиннинг CA и кэш OCSP/CRL.
Вынесите дорогое валидационное I/O на gateway/sidecar.
Используйте prefetch токенов/сертификатов (за 10–20 с до истечения).
14) Тестирование
Contract/interop: разные ЯП/библиотеки, clock skew ±300 с.
Negative: просроченный/поддельный токен, неверный `aud`, не тот регион/тенант, сломанный cert-chain.
Chaos: внезапная ротация `kid`, недоступность JWKS, экспирация массово, обрыв mTLS.
Load: пик выдачи на STS, всплеск verify на gateway.
E2E: mTLS-only, JWT-only, комбинированный режим, Token Exchange (OBO).
15) Плейбуки (runbooks)
1. Компрометация ключа подписи
Немедленный revoke `kid`, выпуск нового, укороченный TTL токенов, аудит, поиск «зависших» клиентов, принудительный deny для старого `kid`.
2. Массовые `INVALID_TOKEN`
Проверить JWKS-кеш, рассинхрон часов, истоки токенов (TTL слишком короткий), временно расширить допуск skew, прогреть JWKS.
3. mTLS-отказы
Проверка цепочки CA, сроков SVID, времени хоста; emergency-перевыпуск через SPIRE/Istio, включить fallback-маршруты только внутри региона.
4. Рост `AUD_MISMATCH`
Дрейф политик audience: сравнить STS-policy с фактическими вызовами, временно добавить нужный `aud`, запланировать корректировку архитектуры вызовов.
5. STS недоступен/замедлен
Увеличить TTL уже выданных токенов (grace), включить prefetch/refresh-раньше, scale-out STS.
16) Типичные ошибки
Долгоживущие API-ключи/секреты в env/коде.
Общий JWKS/PKI «на все регионы и на все времена».
Отсутствие binding (mTLS/DPoP) → токен легко увести.
Широкие `aud=` и «админские» scopes по умолчанию.
Ротация без dual-key периода → массовые 401.
Проверка токенов только на gateway (нет defense in depth).
«Немой» отказ (нет `error_code` и `reason`) — сложно дебажить и обучать команды.
17) Мини-шаблоны конфигураций
PEP (gateway) — правила:yaml auth:
require_mtls: true jwks:
url: https://sts. core/.well-known/jwks. json cache_ttl: 60s claims:
required: ["iss","sub","aud","exp","tenant","region"]
tenant_in_header: "x-tenant"
pdp:
endpoint: "opa:8181/v1/data/policy/allow"
decision_cache_ttl: 60s
STS Policy (фрагмент):
yaml subjects:
- id: "svc. catalog"
spiffe: "spiffe://core/ns/prod/sa/catalog"
audiences: ["svc. search","svc. wallet"]
scopes: ["catalog:read:"]
ttl: "5m"
18) Чек-лист перед продом
- Короткие сервисные JWT (≤5 мин), локальная верификация, кэш JWKS.
- mTLS (или DPoP) включен; приоритетно — mTLS-bound tokens.
- SPIFFE/SPIRE или эквивалент для авто-выдачи/ротации сертификатов.
- STS с политиками audience/scope; выдача только по доверенной идентичности.
- Разделение trust-domains и JWKS по регионам; клеймы tenant/region/licence проверяются.
- PDP/PEP интегрированы, кэш решений + инвалидация по событиям.
- Dual-key окна, мониторинг потребления `kid`, алерты на invalid/aud mismatch.
- Полные логи/аудит S2S, включены метрики производительности/ошибок.
- Плейбуки на компрометацию ключа, падение STS, сбой mTLS.
- Набор contract/negative/chaos/load/E2E тестов пройден.
Заключение
S2S-аутентификация — это комбинация канал-доверия (mTLS), сообщение-доверия (короткие JWT) и устойчивой идентичности ворклоада (SPIFFE), управляемая централизованным STS и проверяемая локально. Добавьте разделение trust-доменов, строгие audience/scopes, автоматическую ротацию и наблюдаемость — и получите контур, который надежен, объясним и масштабируется вместе с платформой и ее географией.