Skip to main content

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:

  1. Using the EKS pod's IAM role credentials
  2. Exchanging those AWS credentials for GCP tokens via Workload Identity Federation
  3. Impersonating a GCP service account
  4. 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:

  1. EKS pod IAM role provides AWS credentials (automatically refreshed by boto3)
  2. AWS credentials are exchanged for a GCP federated token via Workload Identity Federation
  3. Federated token is used to impersonate a GCP service account
  4. Service account token is used to access Google APIs
  5. All tokens automatically refresh when expired

Prerequisites

GCP Setup

  1. Create a Workload Identity Pool and Provider configured for AWS
  2. Create a GCP service account with necessary permissions
  3. Grant the Workload Identity Pool permission to impersonate the service account
  4. Share Google Sheet with the service account email

AWS Setup

  1. EKS cluster with IRSA (IAM Roles for Service Accounts) enabled
  2. IAM role with trust policy for the EKS service account
  3. 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 scopes list

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eks_gcp_wif-0.1.0.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eks_gcp_wif-0.1.0-py3-none-any.whl (5.6 kB view details)

Uploaded Python 3

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

Hashes for eks_gcp_wif-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d4f479d38e6bf3c4ed35897f6ac22c9122496cb907ccf982980a2dfbe61c2088
MD5 b4e0e56a2091fe478fc2bfd5184b9e39
BLAKE2b-256 a128b9fbb4726c4d2f56e6fb1ea6fa359c8b09c5a4f437c351f4c5748e53aa79

See more details on using hashes here.

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

Hashes for eks_gcp_wif-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 518e504f57e002b12fea4b4b0174e11aa41d6ea48f02e6317215683b6054e893
MD5 61ad4ffab741765be1d3c87c26944d1b
BLAKE2b-256 00f9b3fe3e9b454c09a59f1fa18a3b55a0699214dbbb7e48ed1a0a9d20797446

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page