How to Configure Google Kubernetes Engine (GKE) Workload Identity Federation with AWS IAM

Modern cloud-native architectures frequently span multiple cloud providers. A common scenario involves a microservice running in Google Kubernetes Engine (GKE) that requires programmatic access to an Amazon Web Services (AWS) resource, such as an S3 bucket or a DynamoDB table.

Historically, developers solved this by generating long-lived AWS IAM Access Keys and storing them as Kubernetes Secrets. This is a massive security anti-pattern. If a developer accidentally commits those keys to GitHub, or if the pod is compromised, the attacker gains permanent access to the AWS environment.

The secure, modern solution is Workload Identity Federation. By establishing a cryptographic OIDC (OpenID Connect) trust between Google Cloud and AWS, a GKE pod can dynamically exchange its short-lived Google service account token for a short-lived AWS STS (Security Token Service) token, entirely eliminating the need for hardcoded credentials.

This guide explains how to architect and configure OIDC federation between GKE and AWS IAM.

The Architecture of Cross-Cloud Federation

The federation workflow relies on the following OIDC exchange:

  1. The GKE cluster acts as an OIDC Identity Provider (IdP). It signs a JSON Web Token (JWT) projecting the identity of a specific Kubernetes Service Account (KSA).
  2. The pod sends this Google-signed JWT to the AWS STS API (AssumeRoleWithWebIdentity).
  3. AWS STS verifies the signature of the JWT using Google’s public OIDC endpoints.
  4. AWS validates that the specific KSA is explicitly authorized to assume an AWS IAM Role.
  5. AWS returns temporary, short-lived AWS credentials to the GKE pod.

Step 1: Enabling GKE Workload Identity

Before federation can occur, your GKE cluster must have Workload Identity enabled, which allows Kubernetes Service Accounts to act as Google Cloud IAM Service Accounts.

Update your existing GKE cluster to enable Workload Identity:

gcloud container clusters update my-gke-cluster \
    --region us-central1 \
    --workload-pool=my-gcp-project.svc.id.goog

Create a Kubernetes Service Account (KSA) in the cluster:

kubectl create serviceaccount aws-access-sa -n default

Step 2: Configuring the AWS OIDC Identity Provider

Next, you must log in to the AWS console and configure AWS to trust the Google Cloud OIDC issuer.

Google Cloud generates a unique OIDC Issuer URL for your GCP project. The URL format is:

https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/my-gcp-project.svc.id.goog/providers/my-gcp-provider

(Note: Replace PROJECT_NUMBER with your actual GCP numeric project ID).

In AWS:

  1. Navigate to the AWS IAM Console > Identity providers.
  2. Click Add provider.
  3. Select OpenID Connect.
  4. Provider URL: Enter the Google OIDC URL.
  5. Audience: Enter sts.amazonaws.com (This tells AWS that the Google tokens are explicitly intended for STS).
  6. Click Add provider.

Step 3: Creating the AWS IAM Role

Now, you must create the AWS IAM Role that the GKE pod will assume, and configure its Trust Relationship to only allow the specific Kubernetes Service Account.

  1. In the AWS IAM Console, go to Roles > Create role.
  2. Select Web identity as the trusted entity.
  3. Select the Google OIDC provider you created in Step 2.
  4. Attach the necessary AWS permissions (e.g., AmazonS3ReadOnlyAccess).
  5. Name the role GKE-S3-Reader-Role and create it.

Once created, you must strictly edit the Trust relationships JSON of the role to ensure only the aws-access-sa in your GKE cluster can assume it. Modify the Condition block:

"Condition": {
    "StringEquals": {
        "iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/my-gcp-project.svc.id.goog/providers/my-gcp-provider:sub": "system:serviceaccount:default:aws-access-sa"
    }
}

Step 4: Configuring the GKE Pod for Federation

With the trust established, you configure your GKE deployment. The pod must use the aws-access-sa Service Account.

When using the AWS SDK (e.g., Boto3 in Python, or the AWS Go SDK), the SDK automatically looks for a specific environment variable, AWS_WEB_IDENTITY_TOKEN_FILE, to perform the federation natively.

Your Kubernetes deployment YAML must project the Google OIDC token into a volume, and set the environment variables directing the AWS SDK to the token and the AWS Role ARN.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: aws-accessor-app
spec:
  template:
    spec:
      serviceAccountName: aws-access-sa
      containers:
      - name: my-app
        image: my-registry/my-app:latest
        env:
        - name: AWS_ROLE_ARN
          value: "arn:aws:iam::111122223333:role/GKE-S3-Reader-Role"
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: "/var/run/secrets/google/oidc/token"
        volumeMounts:
        - mountPath: "/var/run/secrets/google/oidc"
          name: oidc-token
      volumes:
      - name: oidc-token
        projected:
          sources:
          - serviceAccountToken:
              path: "token"
              audience: "sts.amazonaws.com"
              expirationSeconds: 3600

Conclusion

By implementing Workload Identity Federation between Google Kubernetes Engine and AWS IAM, organizations achieve true Zero Trust cross-cloud authentication. Hardcoded IAM credentials are completely eliminated, replaced by cryptographically verifiable, ephemeral OIDC tokens that rotate automatically every hour, drastically reducing the risk of a credential breach.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.