GCP IAM & Service Accounts — SKILL.md

Raw skill file that agents receive when using this skill

Download
---
name: "GCP IAM & Service Accounts"
description: "Skill for GCP IAM & Service Accounts — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "infrastructure"
agents: ["claude-code", "codex", "gemini"]
tags: ["gcp-iam", "infrastructure", "auto-generated"]
---

# GCP IAM & Service Accounts

---
name: GCP IAM & Service Accounts
description: Use this skill when you need to manage Google Cloud Platform Identity and Access Management (IAM) and Service Accounts - creating service accounts, assigning roles, managing permissions, generating keys, and troubleshooting access issues.
metadata:
  author: skynet
  version: 1.0.0
category: infrastructure
---

# GCP IAM & Service Accounts

## Prerequisites
- Google Cloud CLI installed (`gcloud` command)
- Authenticated with appropriate permissions
- Active GCP project configured

## Essential Commands

### Authentication & Setup
```bash
# Authenticate with Google Cloud
gcloud auth login

# Set active project
gcloud config set project PROJECT_ID

# List current configuration
gcloud config list
```

### Service Account Management

#### Create Service Account
```bash
# Basic service account creation
gcloud iam service-accounts create SA_NAME \
    --display-name="Display Name" \
    --description="Service account description"

# Example
gcloud iam service-accounts create my-app-sa \
    --display-name="My Application Service Account" \
    --description="Service account for my application"
```

#### List Service Accounts
```bash
# List all service accounts in current project
gcloud iam service-accounts list

# Filter by name
gcloud iam service-accounts list --filter="displayName:My App*"

# Get specific service account details
gcloud iam service-accounts describe SA_EMAIL
```

#### Delete Service Account
```bash
gcloud iam service-accounts delete SA_EMAIL
```

### Service Account Keys

#### Generate Key Files
```bash
# Generate JSON key file
gcloud iam service-accounts keys create ~/key.json \
    --iam-account=SA_EMAIL

# Generate P12 key file (legacy)
gcloud iam service-accounts keys create ~/key.p12 \
    --iam-account=SA_EMAIL \
    --key-file-type=p12
```

#### List and Manage Keys
```bash
# List keys for service account
gcloud iam service-accounts keys list \
    --iam-account=SA_EMAIL

# Delete a key
gcloud iam service-accounts keys delete KEY_ID \
    --iam-account=SA_EMAIL
```

### IAM Role Management

#### Assign Roles to Service Accounts
```bash
# Grant role to service account
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SA_EMAIL" \
    --role="ROLE_NAME"

# Examples
gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-app-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

# Grant multiple roles
gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-app-sa@my-project.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client"
```

#### Remove Roles
```bash
gcloud projects remove-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:SA_EMAIL" \
    --role="ROLE_NAME"
```

#### Resource-Level Permissions
```bash
# Grant access to specific Cloud Storage bucket
gsutil iam ch serviceAccount:SA_EMAIL:objectViewer gs://BUCKET_NAME

# Grant access to specific Compute Engine instance
gcloud compute instances add-iam-policy-binding INSTANCE_NAME \
    --zone=ZONE \
    --member="serviceAccount:SA_EMAIL" \
    --role="roles/compute.instanceAdmin"
```

### IAM Policy Management

#### View IAM Policies
```bash
# Get project-level IAM policy
gcloud projects get-iam-policy PROJECT_ID

# Get formatted output
gcloud projects get-iam-policy PROJECT_ID \
    --format="table(bindings.role,bindings.members[])"

# Filter for specific member
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --filter="bindings.members:serviceAccount:SA_EMAIL"
```

#### Test IAM Permissions
```bash
# Test what permissions a service account has
gcloud projects test-iam-permissions PROJECT_ID \
    --permissions="storage.objects.get,storage.objects.list"
```

## Decision Tree: Choosing Service Account Strategy

```
Need GCP access from application?
├── Running on GCP (GCE, GKE, Cloud Functions, etc.)
│   └── Use Default Service Account or attach Custom SA
│       ├── Default SA sufficient? → Use default
│       └── Need specific permissions? → Create custom SA
├── Running outside GCP
│   ├── CI/CD Pipeline
│   │   └── Create SA → Generate JSON key → Store securely
│   ├── Local Development
│   │   ├── Personal project → Use personal credentials
│   │   └── Team project → Create dev SA with limited permissions
│   └── Production External Service
│       └── Create SA → Generate JSON key → Rotate regularly
└── Cross-project access needed?
    └── Create SA in source project → Grant access in target project
```

## Common Workflows

### Workflow 1: Setup Application Service Account
```bash
# 1. Create service account
gcloud iam service-accounts create my-app-prod \
    --display-name="Production App Service Account"

# 2. Assign required roles
gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-app-prod@my-project.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

gcloud projects add-iam-policy-binding my-project \
    --member="serviceAccount:my-app-prod@my-project.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client"

# 3. Generate key file
gcloud iam service-accounts keys create ~/prod-key.json \
    --iam-account=my-app-prod@my-project.iam.gserviceaccount.com

# 4. Test authentication
export GOOGLE_APPLICATION_CREDENTIALS=~/prod-key.json
gcloud auth application-default print-access-token
```

### Workflow 2: Cross-Project Service Account Access
```bash
# 1. Create SA in source project
gcloud iam service-accounts create cross-project-sa \
    --project=source-project

# 2. Grant permissions in target project
gcloud projects add-iam-policy-binding target-project \
    --member="serviceAccount:cross-project-sa@source-project.iam.gserviceaccount.com" \
    --role="roles/storage.admin"

# 3. Verify access
gcloud projects get-iam-policy target-project \
    --flatten="bindings[].members" \
    --filter="bindings.members:serviceAccount:cross-project-sa@source-project.iam.gserviceaccount.com"
```

### Workflow 3: Service Account Impersonation
```bash
# Grant user ability to impersonate service account
gcloud iam service-accounts add-iam-policy-binding SA_EMAIL \
    --member="user:USER_EMAIL" \
    --role="roles/iam.serviceAccountTokenCreator"

# Use impersonation
gcloud compute instances list \
    --impersonate-service-account=SA_EMAIL
```

## Troubleshooting

### Error: "Permission denied"
```
ERROR: (gcloud.compute.instances.list) Some requests did not succeed:
 - Insufficient Permission: Request had insufficient authentication scopes.
```
**Solutions:**
```bash
# Check current scopes
gcloud auth list

# Re-authenticate with full scopes
gcloud auth login --enable-gdrive-access

# For service accounts, verify roles
gcloud projects get-iam-policy PROJECT_ID \
    --flatten="bindings[].members" \
    --filter="bindings.members:serviceAccount:SA_EMAIL"
```

### Error: "Service account does not exist"
```
ERROR: (gcloud.iam.service-accounts.keys.create) NOT_FOUND: 
Service account my-sa@project.iam.gserviceaccount.com does not exist.
```
**Solutions:**
```bash
# Verify service account exists
gcloud iam service-accounts list --filter="email:my-sa@*"

# Check project ID in email format
gcloud config get-value project

# Create if missing
gcloud iam service-accounts create my-sa
```

### Error: "Invalid key file"
```
Error: The file [~/key.json] is not a valid service account key file.
```
**Solutions:**
```bash
# Verify JSON format
cat ~/key.json | python -m json.tool

# Re-generate key file
gcloud iam service-accounts keys create ~/new-key.json \
    --iam-account=SA_EMAIL

# Check file permissions
chmod 600 ~/key.json
```

### Error: "Quota exceeded"
```
ERROR: (gcloud.iam.service-accounts.create) RESOURCE_EXHAUSTED: 
Quota exceeded for quota metric 'Service accounts' and limit 'Service accounts per project'
```
**Solutions:**
```bash
# Check current service account count
gcloud iam service-accounts list --format="value(email)" | wc -l

# Delete unused service accounts
gcloud iam service-accounts list --filter="disabled:true"
gcloud iam service-accounts delete UNUSED_SA_EMAIL

# Request quota increase through Google Cloud Console
```

### Access Token Issues
```bash
# Refresh application default credentials
gcloud auth application-default login

# Clear and reset credentials
gcloud auth revoke
gcloud auth login

# Verify token validity
gcloud auth print-access-token
```

## Security Best Practices

### Key Rotation
```bash
# List existing keys with creation date
gcloud iam service-accounts keys list \
    --iam-account=SA_EMAIL \
    --format="table(name,validAfterTime,validBeforeTime)"

# Create new key
gcloud iam service-accounts keys create ~/new-key.json \
    --iam-account=SA_EMAIL

# After updating application, delete old key
gcloud iam service-accounts keys delete OLD_KEY_ID \
    --iam-account=SA_EMAIL
```

### Principle of Least Privilege
```bash
# Use predefined roles instead of primitive roles
# Good: roles/storage.objectViewer
# Avoid: roles/viewer

# Create custom roles for specific needs
gcloud iam roles create customStorageRole \
    --project=PROJECT_ID \
    --title="Custom Storage Role" \
    --permissions="storage.objects.get,storage.objects.list"
```

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