GCP Workload Identity Federation — SKILL.md

Raw skill file that agents receive when using this skill

Download
---
name: "GCP Workload Identity Federation"
description: "Skill for GCP Workload Identity Federation — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "infrastructure"
agents: ["claude-code", "codex", "gemini"]
tags: ["gcp-workload-identity", "infrastructure", "auto-generated"]
---

# GCP Workload Identity Federation

---
name: GCP Workload Identity Federation
description: Configure secure authentication for external workloads (GitHub Actions, AWS, Azure) to access GCP resources without service account keys
metadata:
  author: skynet
  version: 1.0.0
category: infrastructure
---

# GCP Workload Identity Federation

## Overview

Workload Identity Federation allows external workloads to authenticate to GCP without storing service account keys, using OIDC tokens from trusted identity providers.

## Prerequisites

- GCP project with appropriate IAM permissions
- External identity provider (GitHub Actions, AWS, Azure AD, etc.)
- `gcloud` CLI installed and authenticated

## Core Commands

### Create Workload Identity Pool

```bash
# Create identity pool
gcloud iam workload-identity-pools create POOL_NAME \
    --project=PROJECT_ID \
    --location=global \
    --display-name="Pool Display Name" \
    --description="Pool for external workloads"

# Verify pool creation
gcloud iam workload-identity-pools describe POOL_NAME \
    --project=PROJECT_ID \
    --location=global
```

### Configure Identity Providers

#### GitHub Actions Provider

```bash
# Create GitHub provider
gcloud iam workload-identity-pools providers create-oidc PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME \
    --display-name="GitHub Actions" \
    --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \
    --issuer-uri="https://token.actions.githubusercontent.com"

# Add attribute conditions for specific repository
gcloud iam workload-identity-pools providers update-oidc PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME \
    --attribute-condition="assertion.repository=='OWNER/REPO'"
```

#### AWS Provider

```bash
# Create AWS provider
gcloud iam workload-identity-pools providers create-aws PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME \
    --account-id=AWS_ACCOUNT_ID \
    --display-name="AWS Provider"

# Add attribute mapping
gcloud iam workload-identity-pools providers update-aws PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME \
    --attribute-mapping="google.subject=assertion.arn,attribute.aws_role=assertion.arn.contains('assumed-role') ? assertion.arn.extract('{account}:assumed-role/{role_name}/') : assertion.arn"
```

### Bind Service Account

```bash
# Allow external identity to impersonate service account
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
    --project=PROJECT_ID \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_NAME/attribute.repository/OWNER/REPO"

# For all repositories in an organization
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT_EMAIL \
    --project=PROJECT_ID \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_NAME/attribute.repository_owner/ORG_NAME"
```

## Common Workflows

### GitHub Actions Integration

```yaml
# .github/workflows/deploy.yml
name: Deploy
on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v3
      
      - id: 'auth'
        uses: 'google-github-actions/auth@v1'
        with:
          workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_NAME/providers/PROVIDER_NAME'
          service_account: 'SERVICE_ACCOUNT_EMAIL'
          
      - name: 'Set up Cloud SDK'
        uses: 'google-github-actions/setup-gcloud@v1'
        
      - name: 'Use gcloud CLI'
        run: 'gcloud info'
```

### AWS Cross-Cloud Authentication

```bash
# Configure AWS CLI to use GCP credentials
aws sts assume-role-with-web-identity \
    --role-arn arn:aws:iam::ACCOUNT:role/ROLE_NAME \
    --role-session-name gcp-session \
    --web-identity-token $(gcloud auth print-identity-token) \
    --duration-seconds 3600
```

### Test Authentication

```bash
# Test token generation
gcloud iam workload-identity-pools create-cred-config \
    projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_NAME/providers/PROVIDER_NAME \
    --service-account=SERVICE_ACCOUNT_EMAIL \
    --output-file=credentials.json

# Test with generated credentials
export GOOGLE_APPLICATION_CREDENTIALS=credentials.json
gcloud auth list
```

## Decision Trees

### Provider Type Selection

```
External Identity Provider?
├── GitHub Actions → Use OIDC provider with token.actions.githubusercontent.com
├── GitLab CI → Use OIDC provider with gitlab.com
├── AWS → Use AWS provider with account ID
├── Azure → Use OIDC provider with Azure AD endpoint
└── Custom OIDC → Use OIDC provider with custom issuer
```

### Attribute Mapping Strategy

```
Scope of Access?
├── Single Repository → attribute.repository='owner/repo'
├── Organization → attribute.repository_owner='org'
├── Specific AWS Role → attribute.aws_role contains 'role-name'
└── Environment-based → attribute.environment='prod'
```

## Troubleshooting

### Common Errors and Solutions

**Error: `The caller does not have permission`**
```bash
# Check IAM permissions
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --format="table(bindings.role)" \
    --filter="bindings.members:YOUR_EMAIL"

# Add required role
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="user:YOUR_EMAIL" \
    --role="roles/iam.workloadIdentityPoolAdmin"
```

**Error: `Invalid token or token not found`**
```bash
# Verify provider configuration
gcloud iam workload-identity-pools providers describe PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME

# Check issuer URI and attribute mapping
gcloud iam workload-identity-pools providers describe PROVIDER_NAME \
    --project=PROJECT_ID \
    --location=global \
    --workload-identity-pool=POOL_NAME \
    --format="value(oidc.issuerUri,attributeMapping)"
```

**Error: `Workload identity pool does not exist`**
```bash
# List available pools
gcloud iam workload-identity-pools list \
    --project=PROJECT_ID \
    --location=global

# Check project number vs ID usage
gcloud projects list \
    --filter="projectId:PROJECT_ID" \
    --format="value(projectNumber)"
```

**Error: `Principal not found in policy binding`**
```bash
# Verify service account binding
gcloud iam service-accounts get-iam-policy SERVICE_ACCOUNT_EMAIL \
    --project=PROJECT_ID

# Check principal format
echo "principalSet://iam.googleapis.com/projects/$(gcloud projects list --filter="projectId:PROJECT_ID" --format="value(projectNumber)")/locations/global/workloadIdentityPools/POOL_NAME/attribute.repository/OWNER/REPO"
```

### Debugging Authentication Flow

```bash
# Enable audit logs for debugging
gcloud logging read "protoPayload.serviceName=iam.googleapis.com AND protoPayload.methodName=google.iam.credentials.v1.IAMCredentials.GenerateIdToken" \
    --limit=10 \
    --format=json

# Test token exchange manually
curl -X POST https://sts.googleapis.com/v1/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "audience=//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_NAME/providers/PROVIDER_NAME&grant_type=urn:ietf:params:oauth:grant-type:token-exchange&requested_token_type=urn:ietf:params:oauth:token-type:access_token&scope=https://www.googleapis.com/auth/cloud-platform&subject_token_type=urn:ietf:params:oauth:token-type:id_token&subject_token=EXTERNAL_TOKEN"
```

curl -s https://skills.skynet.ceo/api/skills/gcp-workload-identity/skill.md