For years, multi-cloud architectures suffered from a critical security flaw: service account key management. If an application running in Amazon Web Services (AWS) needed to access a BigQuery dataset in Google Cloud Platform (GCP), developers would generate a long-lived JSON service account key in GCP, download it, and store it as a secret in AWS.
These long-lived keys are the primary vector for cloud breaches. If a developer accidentally commits the JSON file to a public GitHub repository, an attacker can drain the GCP environment within minutes.
Google Cloud solved this permanently with Workload Identity Federation. This architecture eliminates long-lived service account keys entirely. Instead, it establishes a cryptographic trust relationship using the OpenID Connect (OIDC) protocol. The AWS application generates a short-lived, cryptographically signed identity token (JWT) from the AWS Security Token Service (STS) and presents it to GCP. GCP validates the AWS signature, maps the AWS IAM role to a GCP Service Account, and dynamically generates a temporary, short-lived OAuth 2.0 access token.
This guide explains how to configure Workload Identity Federation to securely connect AWS workloads to Google Cloud resources without ever downloading a JSON key.
Understanding the Federation Architecture
The architecture relies on three primary Google Cloud components:
- Workload Identity Pool: A logical boundary within GCP that represents an external trust domain (e.g., “AWS-Production”).
- Workload Identity Provider: The specific configuration within the Pool that tells GCP exactly how to validate the external tokens. For AWS, GCP uses the AWS STS API to validate the tokens.
- Service Account Impersonation (Binding): An IAM policy that says, “If the AWS token proves the caller is the AWS IAM Role
Data-Processor-Role, allow them to act as the GCP Service Account[email protected].”
Step 1: Creating the Workload Identity Pool and Provider
First, you must create the trust boundary in Google Cloud using the gcloud CLI.
Create the Identity Pool:
gcloud iam workload-identity-pools create aws-prod-pool \
--location="global" \
--description="Pool for AWS Production Workloads" \
--display-name="AWS Prod Pool"
Next, attach the AWS Provider to the Pool. You must specify your AWS Account ID so GCP knows which AWS environment to trust.
gcloud iam workload-identity-pools providers create-aws aws-prod-provider \
--location="global" \
--workload-identity-pool="aws-prod-pool" \
--account-id="123456789012" \
--display-name="AWS Prod Provider"
Step 2: Creating the GCP Service Account
The external AWS workload cannot be granted IAM permissions directly. It must impersonate a GCP Service Account. Create the service account and grant it the necessary permissions (e.g., BigQuery Data Viewer).
gcloud iam service-accounts create bq-reader-sa \
--display-name="BigQuery Reader for AWS"
gcloud projects add-iam-policy-binding my-gcp-project \
--member="serviceAccount:[email protected]" \
--role="roles/bigquery.dataViewer"
Step 3: Binding the AWS Role to the GCP Service Account
This is the critical security step. You must explicitly bind the AWS IAM Role (e.g., arn:aws:iam::123456789012:role/Data-Processor-Role) to the GCP Service Account via the roles/iam.workloadIdentityUser IAM role.
This tells GCP: “Only allow the specific AWS Data-Processor-Role to impersonate this GCP service account.”
gcloud iam service-accounts add-iam-policy-binding [email protected] \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/YOUR_GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/aws-prod-pool/attribute.aws_role/arn:aws:sts::123456789012:assumed-role/Data-Processor-Role"
(Note: You must use the GCP Project Number, not the Project ID, in the Principal Set string).
Step 4: Generating the Client Configuration File
To tell the Google Cloud SDK (running inside AWS) how to perform the token exchange, you generate a Client Configuration JSON file. This file is NOT a secret. It contains no passwords or private keys; it simply contains the routing information for the STS-to-GCP token exchange.
gcloud iam workload-identity-pools create-cred-config \
projects/YOUR_GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/aws-prod-pool/providers/aws-prod-provider \
--service-account="[email protected]" \
--aws \
--output-file="gcp-federation.json"
Step 5: Executing the Workload in AWS
Copy the gcp-federation.json file to your AWS EC2 instance (which must be running with the Data-Processor-Role attached via the EC2 Instance Profile).
Set the environment variable instructing the Google Cloud SDK to use the federation file:
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/gcp-federation.json"
Now, run any standard Google Cloud command or Python script (e.g., bq query "SELECT * FROM my_dataset.my_table").
Behind the scenes, the Google SDK transparently queries the AWS metadata server, grabs an AWS STS JWT, sends it to the GCP Workload Identity endpoint, receives a 1-hour GCP OAuth token, and executes the BigQuery query—all in milliseconds, with absolutely zero long-lived secrets to manage.
Conclusion
Hardcoding service account keys in multi-cloud architectures is a catastrophic security anti-pattern. By deploying Google Cloud Workload Identity Federation, cloud architects can establish dynamic, cryptographically robust OIDC trust boundaries, ensuring that workloads securely traverse cloud providers using ephemeral, time-bound tokens.