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:
- 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).
- The pod sends this Google-signed JWT to the AWS STS API (
AssumeRoleWithWebIdentity). - AWS STS verifies the signature of the JWT using Google’s public OIDC endpoints.
- AWS validates that the specific KSA is explicitly authorized to assume an AWS IAM Role.
- 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:
- Navigate to the AWS IAM Console > Identity providers.
- Click Add provider.
- Select OpenID Connect.
- Provider URL: Enter the Google OIDC URL.
- Audience: Enter
sts.amazonaws.com(This tells AWS that the Google tokens are explicitly intended for STS). - 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.
- In the AWS IAM Console, go to Roles > Create role.
- Select Web identity as the trusted entity.
- Select the Google OIDC provider you created in Step 2.
- Attach the necessary AWS permissions (e.g.,
AmazonS3ReadOnlyAccess). - Name the role
GKE-S3-Reader-Roleand 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.