Недавно беседовали с коллегой про Workload Identity Federation в GKE и выяснилось, что не все знают, как metadata-proxy получает JWT токен от имени пода.
А вы знаете, как это работает под капотом?
Что такое WIF?
Простая идея: токен пода обменивается на cloud token для доступа к облачным API. Никаких статических ключей!
Два подхода к безопасности:
❌ Небезопасный подход (как в эмуляторе):
rules:
- apiGroups: [""]
resources: [serviceaccounts/token]
verbs: [create]
Критическая уязвимость! Такая роль позволяет получить JWT токен от ЛЮБОГО ServiceAccount в кластере!
✅ Элегантное решение GKE:
1. Использует kubeconfig от kubelet (у него есть права только на поды своей ноды)
2. Запрашивает токен с указанием реально существующего объекта в кубере, который к тому же привязан к конкренной ноде:
kubectl create token azalio-meta-sa \
--namespace azalio-meta \
--bound-object-kind Pod \
--bound-object-name test-pod \
--bound-object-uid 5094d128-8f9b-463d
Почему это безопасно?
- metadata-proxy может получить токен только для подов на своей ноде
- Токен привязан к конкретному поду через UID
- Нет доступа к ServiceAccount подов других нод
**Как работает весь процесс:**
(картинка в комментариях)
1. Pod → metadata-proxy: GET /computeMetadata/.../token
2. proxy → K8s API: create token (ограничен нодой + Pod UID)
3. proxy → Google STS: обмен JWT → Access Token
4. STS → proxy → Pod: Access Token
5. Pod → Google API: работа с нужными сервисами
Полезные ссылки:
- Официальная документация GKE Workload Identity
- Детальный разбор безопасности WIF
- Пример настройки WI в GKE
- Bound service account tokens.
Что запомнить:
Прав выдаваемых kubeconfig'у kubelet хватает чтобы выписать токен от имени SA пода запущенного на ноде.
Вопрос: у какого российского облачного провайдера есть WIF? 😉
#kubernetes #security #gke #workloadidentity #cloudsecurity