EKS to GCP authentication via Workload Identity Federation
Project description
EKS Pod to GCP Authentication via Workload Identity Federation
This project demonstrates how to authenticate from an AWS EKS pod to Google Cloud Platform (GCP) services using Workload Identity Federation (WIF), without requiring GCP service account keys.
What Does This Code Do?
This application runs in an EKS pod and updates a Google Sheet by:
- Using the EKS pod's IAM role credentials
- Exchanging those AWS credentials for GCP tokens via Workload Identity Federation
- Impersonating a GCP service account
- Making authenticated requests to Google Sheets API
All credentials automatically refresh when expired, making it suitable for long-running applications.
Authentication Flow
┌─────────────────┐
│ EKS Pod │
│ (IAM Role) │
└────────┬────────┘
│ 1. AWS credentials (auto-refresh)
▼
┌─────────────────────────┐
│ EKSCredentialSupplier │
│ (boto3.Session) │
└────────┬────────────────┘
│ 2. Exchange via WIF
▼
┌─────────────────────────┐
│ GCP STS Token Service │
│ (sts.googleapis.com) │
└────────┬────────────────┘
│ 3. Federated token
▼
┌─────────────────────────┐
│ Service Account │
│ Impersonation │
└────────┬────────────────┘
│ 4. Access token
▼
┌─────────────────────────┐
│ Google Sheets API │
└─────────────────────────┘
Step-by-step:
- EKS pod IAM role provides AWS credentials (automatically refreshed by boto3)
- AWS credentials are exchanged for a GCP federated token via Workload Identity Federation
- Federated token is used to impersonate a GCP service account
- Service account token is used to access Google APIs
- All tokens automatically refresh when expired
Prerequisites
GCP Setup
- Create a Workload Identity Pool and Provider configured for AWS
- Create a GCP service account with necessary permissions
- Grant the Workload Identity Pool permission to impersonate the service account
- Share Google Sheet with the service account email
AWS Setup
- EKS cluster with IRSA (IAM Roles for Service Accounts) enabled
- IAM role with trust policy for the EKS service account
- Kubernetes service account annotated with the IAM role ARN
Environment Variables
GCP_PROJECT_NUMBER=123456789
GCP_WIF_POOL_ID=my-pool
GCP_WIF_PROVIDER_ID=my-provider
GCP_SERVICE_ACCOUNT=my-sa@project.iam.gserviceaccount.com
AWS_REGION=us-east-1
How to Use
1. Install Dependencies
pip install boto3 google-auth google-auth-httplib2
2. Configure Environment
Set environment variables or update config.py:
GCP_PROJECT_NUMBER = "123456789"
WORKLOAD_IDENTITY_POOL = "my-pool"
WORKLOAD_IDENTITY_PROVIDER = "my-provider"
SERVICE_ACCOUNT_EMAIL = "my-sa@project.iam.gserviceaccount.com"
DOCUMENT_ID = "your-google-sheet-id"
3. Deploy to EKS
kubectl apply -f pod.yaml
4. Run
python main.py
Core Code for WIF Integration
To integrate WIF authentication into your own codebase, copy these essential components:
Required Imports
import os
import boto3
from google.auth import aws, impersonated_credentials
from google.auth.transport.requests import AuthorizedSession
EKSCredentialSupplier Class
class EKSCredentialSupplier(aws.AwsSecurityCredentialsSupplier):
"""Supplies AWS credentials from EKS pod IAM role."""
def __init__(self, region=None):
self._session = boto3.Session()
self._region = region or os.getenv("AWS_REGION", "us-east-1")
def get_aws_security_credentials(self, context, request):
credentials = self._session.get_credentials()
return aws.AwsSecurityCredentials(
access_key_id=credentials.access_key,
secret_access_key=credentials.secret_key,
session_token=credentials.token
)
def get_aws_region(self, context, request):
return self._region
Credential Setup Function
def get_wif_credentials():
"""Get credentials using Workload Identity Federation."""
project_number = os.getenv("GCP_PROJECT_NUMBER")
pool_id = os.getenv("GCP_WIF_POOL_ID")
provider_id = os.getenv("GCP_WIF_PROVIDER_ID")
service_account = os.getenv("GCP_SERVICE_ACCOUNT")
aws_region = os.getenv("AWS_REGION", "us-east-1")
audience = f"//iam.googleapis.com/projects/{project_number}/locations/global/workloadIdentityPools/{pool_id}/providers/{provider_id}"
credential_supplier = EKSCredentialSupplier(region=aws_region)
# Adjust scopes based on your needs
scopes = ["https://www.googleapis.com/auth/cloud-platform"]
credentials = aws.Credentials(
audience=audience,
subject_token_type="urn:ietf:params:aws:token-type:aws4_request",
token_url="https://sts.googleapis.com/v1/token",
aws_security_credentials_supplier=credential_supplier,
scopes=scopes
)
if service_account:
credentials = impersonated_credentials.Credentials(
source_credentials=credentials,
target_principal=service_account,
target_scopes=scopes
)
return credentials
Initialize Session
credentials = get_wif_credentials()
authed_session = AuthorizedSession(credentials)
# Use authed_session for all GCP API calls
response = authed_session.get("https://www.googleapis.com/...")
Key Features
- No Service Account Keys: Uses Workload Identity Federation instead of storing GCP credentials
- Automatic Credential Refresh: Both AWS and GCP credentials refresh automatically
- Long-Running Support: Suitable for long-running applications in EKS
- Secure: Leverages EKS pod IAM roles and GCP's federated identity
Common Scopes
# Google Sheets
["https://www.googleapis.com/auth/spreadsheets"]
# Google Drive (read-only)
["https://www.googleapis.com/auth/drive.readonly"]
# All Google Cloud APIs
["https://www.googleapis.com/auth/cloud-platform"]
# Multiple scopes
["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive.readonly"]
Troubleshooting
403 Error: "Request had insufficient authentication scopes"
- Add the required scope to the
scopeslist
403 Error: Permission denied on Google Sheet
- Share the sheet with the GCP service account email
Authentication fails
- Verify Workload Identity Pool configuration
- Check IAM role trust policy for EKS service account
- Ensure service account has impersonation permissions
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eks_gcp_wif-0.1.0.tar.gz.
File metadata
- Download URL: eks_gcp_wif-0.1.0.tar.gz
- Upload date:
- Size: 4.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4f479d38e6bf3c4ed35897f6ac22c9122496cb907ccf982980a2dfbe61c2088
|
|
| MD5 |
b4e0e56a2091fe478fc2bfd5184b9e39
|
|
| BLAKE2b-256 |
a128b9fbb4726c4d2f56e6fb1ea6fa359c8b09c5a4f437c351f4c5748e53aa79
|
File details
Details for the file eks_gcp_wif-0.1.0-py3-none-any.whl.
File metadata
- Download URL: eks_gcp_wif-0.1.0-py3-none-any.whl
- Upload date:
- Size: 5.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
518e504f57e002b12fea4b4b0174e11aa41d6ea48f02e6317215683b6054e893
|
|
| MD5 |
61ad4ffab741765be1d3c87c26944d1b
|
|
| BLAKE2b-256 |
00f9b3fe3e9b454c09a59f1fa18a3b55a0699214dbbb7e48ed1a0a9d20797446
|