Workload Identity

This page explains the recommended way for your GKE applications to consume services provided by Google APIs. You accomplish this by configuring a Kubernetes service account to act as a Google service account. Any Pods running as the Kubernetes service account then use the Google service account to authenticate to cloud services.

Overview

Workload Identity is the recommended way to access Google Cloud services from within GKE due to its improved security properties and manageability. To learn more, refer to the alternatives below.

Workloads running on GKE must authenticate to use Google Cloud APIs such as the Compute APIs, Storage and Database APIs, or Machine Learning APIs. Once you configure the relationship between a Kubernetes service account and a Google service account, any workload running as the Kubernetes service account automatically authenticates as the Google service account when accessing Google Cloud APIs.

For information on authorizing Google service account to access Cloud APIs, see understanding service accounts.

Terminology

This document distinguishes between Kubernetes service accounts (KSAs) and Google service accounts (GSAs). KSAs are Kubernetes resources, while GSAs are specific to Google Cloud Platform. Other GCP documentation refers to GSAs as "service accounts".

Cross-Cluster identity

The relationship between GSAs and KSAs is defined by the Identity Namespace associated with your project. All Kubernetes service accounts that share a name, Namespace name, and Identity Namespace share access to GSAs. This can be useful if multiple clusters contain the same identities, but potentially dangerous if Kubernetes service account names and Namespaces are not carefully managed.

For example, the following command grants the same access to all Kubernetes workloads in any cluster in the project that use the default service account and Namespace, and have Workload Identity enabled on the cluster. To prevent clusters from sharing permissions, the clusters must be in separate projects or they must use distinct Kubernetes namespace names. As a specific example: users with permissive "dev" and locked down "prod" clusters should consider separating those clusters into separate projects to get separate Identity Namespaces.

gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:[PROJECT_NAME].svc.id.goog[default/default]" \
  [GSA_NAME]@[PROJECT_NAME].iam.gserviceaccount.com

Limitations

  • Workload Identity is available for clusters running GKE version 1.12 and higher.

  • During the Workload Identity beta, a GCP project can have a maximum of 20 clusters with Workload Identity enabled.

  • Workload Identity replaces the need to use Metadata Concealment and as such, the two approaches are incompatible. The sensitive metadata protected by Metadata Concealment is also protected by Workload Identity.

  • When Workload Identity is enabled, you can no longer use the Compute Engine default service account. To learn more, refer to the alternatives section below.

  • Workload Identity can't be used with Pods running in the host network.

  • GKE infrastructure pods such as Stackdriver and Heapster will continue to use the Node's Service Account.

Before you begin

To prepare for this task, perform the following steps:

  • Ensure that you have enabled the Google Kubernetes Engine API.
  • Enable Google Kubernetes Engine API
  • Ensure that you have installed the Cloud SDK.
  • Set your default project ID:
    gcloud config set project [PROJECT_ID]
  • If you are working with zonal clusters, set your default compute zone:
    gcloud config set compute/zone [COMPUTE_ZONE]
  • If you are working with regional clusters, set your default compute region:
    gcloud config set compute/region [COMPUTE_REGION]
  • Update gcloud to the latest version:
    gcloud components update

Enable Workload Identity on a new cluster

This section explains how to create a cluster with Workload Identity enabled, and how to start a Pod with a Google Service Account (GSA) identity.

  1. Ensure that you have enabled the IAM Credentials API.

    Enable IAM Credentials API

  2. Create a cluster with Workload Identity enabled, replacing [CLUSTER_NAME] with the name of your cluster and [PROJECT_NAME] with the name of your GCP project:

    gcloud beta container clusters create [CLUSTER_NAME] \
      --cluster-version=1.12 \
      --identity-namespace=[PROJECT_NAME].svc.id.goog
    

    Creating the cluster takes several minutes.

    This action requires container.clusters.create permission on the project.

    Perform the remainder of the steps with a less privileged role, in accordance with the principle of least privilege. Each step notes the permissions that are required.

  3. Configure kubectl to communicate with the cluster:

    gcloud container clusters get-credentials [CLUSTER_NAME]
    

    where [CLUSTER_NAME] is the name of the cluster you created in the previous step.

    This action requires container.clusters.get permission on the project.

  4. Create the Google service account, replacing [GSA_NAME] with the name you choose for the service account. If you have an existing service account you can use it instead of creating a new service account.

    gcloud iam service-accounts create [GSA_NAME]
    

    This action requires iam.serviceAccounts.create permission on the project.

  5. Like most other resources, Kubernetes service accounts live in a Namespace. Create the Namespace to use for the Kubernetes service account.

    kubectl create namespace [K8S_NAMESPACE]
    

    This action requires Create Namespace RBAC permission within the cluster.

  6. Create the Kubernetes service account. Use the Namespace you created in the previous step for the --namespace option. Replace [KSA_NAME] with the name you would like to use for the service account.

    kubectl create serviceaccount \
     --namespace [K8S_NAMESPACE] \
     [KSA_NAME]
    

    This action requires create serviceaccounts RBAC permission within the Namespace

    Alternatively, you can use the default Namespace or the default Kubernetes service account in any Namespace.

  7. Allow the Kubernetes service account to use the Google service account by creating an Cloud IAM policy binding between the two. This binding allows the Kubernetes Service account to act as the Google service account.

    gcloud iam service-accounts add-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:[PROJECT_NAME].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]]" \
      [GSA_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
    

    This action requires iam.serviceAccounts.setIamPolicy permission on the Google service account.

  8. Add the iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_NAME] annotation to the Kubernetes service account, using the email address of the Google service account:

    kubectl annotate serviceaccount \
      --namespace [K8S_NAMESPACE] \
      [KSA_NAME] \
      iam.gke.io/gcp-service-account=[GSA_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
    

    This action requires RBAC edit permissions on the Kubernetes service account.

  9. Verify the service accounts are configured correctly by creating a Pod with the Kubernetes service account that runs the cloud-sdk container image, and connecting to it with an interactive session.

    kubectl run -it \
      --generator=run-pod/v1 \
      --image google/cloud-sdk \
      --serviceaccount [KSA_NAME] \
      --namespace [K8S_NAMESPACE] \
      workload-identity-test
    

    The google/cloud-sdk image includes the gcloud command-line tool which is a convenient way to consume Google Cloud Platform APIs. It may take some time to download the image.

    This action requires create pods RBAC permission within the Namespace.

    You are now connected to an interactive shell within the created Pod. Run the following command:

    gcloud auth list
    

    If the service accounts are correctly configured, the Google service account email address is listed as the active (and only) identity. This demonstrates that by default, the Pod uses the Google service account's authority when calling Google Cloud APIs.

Cleaning up

  1. Revoke access to the Google service account:

    gcloud iam service-accounts remove-iam-policy-binding \
      --role roles/iam.workloadIdentityUser \
      --member "serviceAccount:[PROJECT_NAME].svc.id.goog[[K8S_NAMESPACE]/[KSA_NAME]]" \
      [GSA_NAME]@[PROJECT_NAME].iam.gserviceaccount.com
    

    This action requires iam.serviceAccounts.setIamPolicy permissions on the service account.

    It can take up to 30 minutes for cached tokens to expire. You can check whether the cached tokens have expired with this command:

    gcloud auth list
    

    The cached tokens have exprired ff the output of that command no longer includes [GSA_NAME]@[PROJECT_NAME].iam.gserviceaccount.com.

  2. Disable Workload Identity in the cluster:

    gcloud beta container clusters update [CLUSTER_NAME] \
      --disable-workload-identity
    

    This action requires container.clusters.update permissions on the cluster.

Enable Workload Identity on an existing cluster

  1. Modify the cluster to enable Workload Identity. Existing Node pools are unaffected. New Node pools default to --workload-metadata-from-node=GKE_METADATA_SERVER

    gcloud beta container clusters update [CLUSTER_NAME] \
      --identity-namespace=[PROJECT_NAME].svc.id.goog
    

This action requires container.clusters.update permissions on the cluster.

Migrate workloads to Workload Identity

Select the migration strategy that is ideal for your environment. Node pools can be migrated in place or you can create new Node pools with Workload Identity enabled. We recommend creating new node pools if you also need to modify your application to be compatible with this feature.

Option 1: Node pool modification

Modify existing Node pool to enable GKE_METADATA_SERVER. This update succeeds only if Workload Identity is enabled on the cluster. It immediately enables Workload Identity for workloads deployed to the Node pool.

gcloud beta container node-pools update [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

This action requires container.nodes.update permissions on the project.

Option 2: Node pool creation with Workload Identity

Add a new Node pool to the cluster with Workload Identity enabled and manually migrate workloads to that pool. This succeeds only if Workload Identity is enabled on the cluster.

gcloud beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=GKE_METADATA_SERVER

If a cluster has Workload Identity enabled, you can selectively disable it on a specific Node pool by explicitly specifying --workload-metadata-from-node=EXPOSED or --workload-metadata-from-node=SECURE. See Protecting cluster metadata for more information.

gcloud beta container node-pools create [NODEPOOL_NAME] \
  --cluster=[CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE

This action requires container.nodes.create permissions on the project.

Cleaning Up

  1. Modify existing Node pools to disable Workload Identity:

    gcloud beta container node-pools update [NODEPOOL_NAME] \
      --cluster=[CLUSTER_NAME] \
      --workload-metadata-from-node=EXPOSED
    

    This action requires container.nodes.update permissions on the project.

  2. Modify the cluster to disable Workload Identity. Existing Node pools are unaffected (but the modification is blocked if any Node pools are using GKE_METADATA_SERVER). In node pools created after disabling Workload Identity, Pods running in the node pool have access to their node's underlying Compute Engine metadata server.

    gcloud beta container clusters update [CLUSTER_NAME] \
      --disable-workload-identity
    

    This action requires container.clusters.update permissions on the cluster.

Alternatives

There are two alternative methods to access Cloud APIs from GKE. With the release of Workload Identity we no longer recommend these approaches because of the compromises they require.

  1. Export service account keys and store them as Kubernetes Secrets Google service account keys expire after 10 years and are rotated manually. This has the potential to expand the scope of a security breach if it goes undetected.

  2. Use the Compute Engine default service account on your nodes. The Compute Engine default service account is shared by all workloads deployed on that node. This can result in over-provisioning of permissions.

What's next

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Kubernetes Engine Documentation