*English article is available [here](https://tech.preferred.jp/en/blog/gcp-workload-identity-federation-webhook/).* 機械学習プラットフォームエンジニアの大村です。 ## TL;DR GCP(Google Cloud Platform)外のKubernetesクラスタからGoogle Cloud APIの安全な利用を可能とするAdmission Webhookの実装を公開しました![Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation)の機能を利用することにより外部KubernetesクラスタのServiceAccountに紐付くトークンで認証しています。 [https://github.com/pfnet-research/gcp-workload-identity-federation-webhook](https://github.com/pfnet-research/gcp-workload-identity-federation-webhook) このWebhookを使うことで、下記のように以前と比べて外部のKubernetesクラスタからよりセキュアにGoogle Cloud APIを利用できます。 | **これまで** | **これから** | | --- | --- | | ![](https://tech.preferred.jp/wp-content/uploads/2022/11/gcp-workload-identity-federation-webhook-previous-1.jpg) | ![](https://tech.preferred.jp/wp-content/uploads/2022/11/gcp-workload-identity-federation-webhook-after-1.jpg) | | - サービスアカウントキーを発行する必要がある - サービスアカウントキーをSecretとして管理する必要がある - Manifestで明示的にSecretをPodにマウントする必要がある - サービスアカウントキーはローテーションを行わない場合、漏洩時の影響が大きい(*最近Supply Chain攻撃などでもパブリッククラウドの認証情報は狙われている*) | - サービスアカウントキーを発行する必要がない - サービスアカウントキーをKubernetesリソースとして保存する必要がない - Kubernetes ServiceAccountを直接認証に利用できる - GCP認証情報は一時的(有効期限付き) - かつ、自動的にローテーションされるので漏洩に対してより安全 | ## Workload Identity Federationとは Workload Identity Federation(以下WIF)は一言で言うと、「GCP以外のサービスが提供する外部IDを用いて、Google Cloud APIにアクセスできる」機能です。この仕組が提供される以前は前節でも紹介したとおり、無期限のサービスアカウントキーを管理しなくてはならず(もしくはユーザ側でローテーションの仕組みを構築する必要があり)、漏洩時のリスクが大きい状態でした。この機能が提供されたことで、WIFが対応している[外部IDプロバイダ(AWS, Azure Active Directory, Okta, OIDC, SAML 2.0等)](https://cloud.google.com/iam/docs/workload-identity-federation#providers)を提供すれば、外部IDプロバイダの発行した認証情報を使って、GCPサービスアカウントの権限を一時的に借用させることができます。技術的には[OAuth 2.0 Token Exchange](https://tools.ietf.org/html/rfc8693)の仕様に従う[セキュリティトークンサービス(STS)](https://cloud.google.com/iam/docs/reference/sts/rest)を介して、外部IDプロバイダの発行した認証情報をGoogle Cloud APIの認証情報と交換します。 最近だと、[GitHub Actions からのキーなしの認証の有効化](https://cloud.google.com/blog/ja/products/identity-security/enabling-keyless-authentication-from-github-actions)で紹介されて注目を集めたのが記憶に新しい方もいると思います。Workload Identity Federationの仕組みについては詳しく説明している記事が公開されていますのでそちらもあわせて参照ください。 - [Workload Identity Federationを図で理解する – Carpe Diem](https://christina04.hatenablog.com/entry/workload-identity-federation) - [Workload Identity Federationとは / 社内IDaaS勉強会資料共有](https://www.tc3.co.jp/workload-identity-federation/) - [Workload Identity FederationをGitHub Actionsで利用する](https://zenn.dev/amazyra/articles/workloadidentityfederation) ## Kubernetesクラスタを外部IDプロバイダにする Kubernetes ServiceAccount Token([Bound Service Account Token](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/1205-bound-service-account-tokens/README.md))は、実はOIDC ID TokenとしてControl Planeが発行しており、Kubernetes API ServerはOIDC Providerに関する情報をexposeする機能([Service Account Issuer Discovery](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-issuer-discovery)と呼ばれます)を持っているので、STSがServiceAccount Tokenを検証できる範囲で、限定的なOIDC Providerとして振る舞う事ができます。Kubernetesクラスタがオンプレミスなどのプライベートネットワークにデプロイされている場合は、STSでKubernetes ServiceAccount Tokenを交換する際にTokenの検証を行うために必要な2つのエンドポイント([OIDC Dicovery](https://openid.net/specs/openid-connect-discovery-1_0.html), [OIDC JWKs](https://www.rfc-editor.org/rfc/rfc7517))をSTSからアクセス可能な状態で公開する事ができます。 あとは、GCP側でもKubernetesクラスタ(外部IDプロバイダ)に対応する、 [Workload IdentityプールとWorkload Identityプールプロバイダを構成し](https://cloud.google.com/iam/docs/configuring-workload-identity-federation)、[外部ID(Kubernetes ServiceAccount)にGCPサービスアカウントの借用権限を付与](https://cloud.google.com/iam/docs/using-workload-identity-federation#impersonate)すれば、WIFを利用できます。 詳細は[Cloud Native Security Conference 2022](https://event.cloudnativedays.jp/cnsec2022) で発表した[“Kubernetes Service Account As Multi-Cloud Identity”](https://event.cloudnativedays.jp/cnsec2022/talks/1439)([video](https://event.cloudnativedays.jp/cnsec2022/talks/1439))で解説しています。 ## [GCP Workload Identity Federation Webhook](https://github.com/pfnet-research/gcp-workload-identity-federation-webhook) Kubernetesクラスタを外部IDプロバイダとして設定できればWIFが利用できますが、クライアント(Pod側)でもいくつか設定が必要になります。具体的には、[Kubernetes ServiceAccount TokenをFederated Identityとして利用する(STSでServiceAccount Tokenを交換してからAPIアクセスする)ようにGoogle Cloud SDKの設定を行う必要](https://cloud.google.com/iam/docs/using-workload-identity-federation#generate-automatic)があります。それを自動化してくれるのがこのWebhookです。コンセプトは[Amazon EKS Pod Identity Webhook](https://github.com/aws/amazon-eks-pod-identity-webhook)([IRSA](https://www.bionconsulting.com/blog/amazon-eks-irsa)で使われているWebhook)や[Azure AD Workload Identity](https://github.com/Azure/azure-workload-identity)とほぼ同じです。 下記のようにServiceAccountに、対応するWorkload Identityプロバイダ、借用したいGCPサービスアカウントをannotationしておいて、そのServiceAccountでPodを作成するだけで、Pod内のContainerは自動的にGCPサービスアカウント権限を借用することができます。 [![](https://tech.preferred.jp/wp-content/uploads/2022/11/gcp-workload-identity-federation-webhook-yaml.png)](https://tech.preferred.jp/wp-content/uploads/2022/11/gcp-workload-identity-federation-webhook-yaml.png) 具体的にどういう情報が注入されるかは[README](https://github.com/pfnet-research/gcp-workload-identity-federation-webhook#walk-through)を御覧ください。 ## 公開した背景 メジャーなPublic Cloud(AWS, GCP, Azure)ではIdentity Federationの機能が提供されています。また、それぞれのManaged Kubernetesでは、Kubernetes ServiceAccountをそのCloud APIのIdentityとして利用できる機能が提供されています。 | | Identity Federation機能名 | Managed Kubernetesでの対応 | | --- | --- | --- | | AWS | [ID プロバイダーとフェデレーション](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_providers.html) | [IAM roles for service accounts – Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) | | GCP | [Workload Identity 連携](https://cloud.google.com/iam/docs/workload-identity-federation) | [Use Workload Identity – GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) | | Azure | [Azure AD Workload Identity](https://azure.github.io/azure-workload-identity/docs/) | [Use an Azure AD workload identities (preview) on Azure Kubernetes Service (AKS)](https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview) | ですが、他のクラウドやオンプレミスのKubernetesクラスタでは、Kubernetes ServiceAccountをFederated Identityとして利用する際に設定を注入してくれるWebhookが必要です。AWS、Azureについては公開されていますが、GCPについては公開されていません(Anthosは製品レベルで対応しているため自前でWebhookデプロイ不要)。そのため、PFNではWebhookを内製していましたが、公共性が高いと考え、今回公開しました。 | | ククラウド外のKubernetes ServiceAccountを Federated Identityとして利用するためのWebhook(OSS) | 公開元 | | --- | --- | --- | | AWS | [Amazon EKS Pod Identity Webhook](https://github.com/aws/amazon-eks-pod-identity-webhook) *※EKS Anywhereは[製品レベルで対応している](https://anywhere.eks.amazonaws.com/docs/reference/clusterspec/optional/irsa/)ため自前でWebhookデプロイ不要* | AWS(公式) | | GCP | [**GCP Workload Identity Federation Webhook**](https://github.com/pfnet-research/gcp-workload-identity-federation-webhook#walk-through)**(今回公開)** *※**Anthos*は*[製品レベルで対応している](https://cloud.google.com/anthos/fleet-management/docs/use-workload-identity)ため自前でWebhookデプロイ不要* | **PFN** | | Azure | [Azure AD Workload Identity](https://github.com/Azure/azure-workload-identity) | Azure(公式) | ## さいごに PFNのオンプレミスの機械学習プラットフォームでは、Kubernetes ServiceAccountを各種Public Cloud(AWS, GCP, Azure)のFederated Identityとして利用できる環境を構築しており、[Cloud Native Security Conference 2022](https://event.cloudnativedays.jp/cnsec2022) にて[“Kubernetes Service Account As Multi-Cloud Identity”](https://event.cloudnativedays.jp/cnsec2022/talks/1439)として成果を発表しています。今回、その際に、PFNで内製していたGCP Workload Identity Federation向けのWebhook実装として [https://github.com/pfnet-research/gcp-workload-identity-federation-webhook](https://github.com/pfnet-research/gcp-workload-identity-federation-webhook) を公開しました。是非使ってみていただいてフィードバックをいただけると嬉しいです。 ## We’re Hiring!! PFNの機械学習プラットフォームチームではエンジニアを募集しています。こうしたクラウド連携や、オンプレミスの機械学習クラスタの構築&運用に興味のある方、ご応募お待ちしています! **[Machine Learning Platform Engineer/機械学習プラットフォームエンジニア (Infrastructure)](https://apply.workable.com/preferred-networks/j/150BE9CDDC/)**