AWS ECS → Vertex AI (Workload Identity Federation)
Secure, keyless authentication from AWS ECS to Google Vertex AI using Workload Identity Federation (WIF).
- No service account keys or long-lived secrets
- Short-lived, auto-rotating tokens
- IAM-based, auditable access
Overview
Components (in order of the authentication flow)
-
AWS ECS Task — Starts the container with an attached IAM role.
-
WIF Config File — Configuration that defines the token exchange path: pool, provider, and target service account.
-
Google SDK — Reads the config file and orchestrates the full authentication flow.
-
AWS STS — Provides temporary AWS credentials when called by the SDK (via boto3).
-
GCP Workload Identity Pool — Receives the AWS identity and initiates validation.
-
AWS Identity Provider — Validates the AWS account and role against allowed values.
-
IAM Credentials API — Exchanges the federated token for a short-lived service account token.
-
GCP Service Account (vertex-caller-sa) — The impersonated identity with
roles/aiplatform.userpermission. -
Vertex AI — Receives API calls authenticated with the service account token.
How It Works
AWS IAM Role → WIF Pool → AWS Identity Provider → GCP Service Account → Vertex AI
Security Requirements
To authenticate, an ECS task must:
- Come from an allowed AWS account.
- Use an approved IAM role.
- Be accepted by the AWS Identity Provider in GCP.
- Be allowed to impersonate the target GC vertex-caller-sa service account.
The GCP vertex-caller-sa service account must have roles/aiplatform.user.
AWS Configuration
Each ECS task must set:
| Variable | Description |
|---|---|
VERTEX_PROJECT_NAME | Target GCP project |
GOOGLE_APPLICATION_CREDENTIALS | External account (WIF) config file |
Config files (configs/gcp_binding_prod.json, configs/gcp_binding_dev.json) contain no secrets.
Why We Patch google-auth
The Problem
The google-auth library expects AWS credentials from the EC2 metadata service (169.254.169.254). This works on EC2 instances but fails on ECS/Fargate — where credentials are provided via a different mechanism (task role credentials endpoint).
The Solution
At app startup, we monkey-patch google-auth to fetch AWS credentials using boto3 instead. boto3 automatically detects the correct credential source for any AWS environment (EC2, ECS, Lambda, etc.).
When the Patch Applies
| Environment | Patch Applied | Reason |
|---|---|---|
| Local dev | No | Uses local GCP credentials or service account key |
| GCP (Cloud Run) | No | Uses native GCP metadata service |
| AWS ECS/Fargate | Yes | Fixes credential fetching for WIF |
Setting Up the Credential File (for replacement if needed)
1. Download from GCP Console
- Go to IAM & Admin → Workload Identity Federation
- Select your identity pool
- Click Grant Access (or select an existing connected service account)
- Choose Download Config and select the AWS provider
- Save the file to
configs/gcp_binding_prod.jsonorconfigs/gcp_binding_dev.json
2. Add to Code
Add the config file to your repository and make sure the GOOGLE_APPLICATION_CREDENTIALS point to it based on the desired env:
Credential File Format
{
"type": "external_account",
"audience": "//iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{POOL_ID}/providers/aws-provider",
"subject_token_type": "urn:ietf:params:aws:token-type:aws4_request",
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{SERVICE_ACCOUNT_EMAIL}:generateAccessToken",
"token_url": "https://sts.googleapis.com/v1/token",
"credential_source": {
"environment_id": "aws1",
"region_url": "http://169.254.169.254/latest/meta-data/placement/availability-zone",
"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials",
"regional_cred_verification_url": "https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15"
}
}