GCP Skill
Overview
GCP's resource hierarchy provides powerful security controls, but defaults are often permissive. This skill guides systematic review of GCP infrastructure for security misconfigurations.
Core principle: Never use primitive roles. GCP's predefined and custom roles exist for a reason. roles/owner, roles/editor, and roles/viewer are almost never appropriate.
The GCP Security Review Process
Phase 1: Check IAM First
IAM is the foundation. Start here:
- •
Review Role Assignments
- •Using predefined roles (not primitive)?
- •Scoped to specific resources (not project)?
- •Conditions applied where possible?
- •
Check Service Accounts
- •Dedicated accounts per workload?
- •Not using default service accounts?
- •Keys managed properly (or none)?
- •
Verify No Public Access
- •No
allUsersbindings? - •No
allAuthenticatedUsersbindings? - •Workload Identity for GKE?
- •No
Phase 2: Check Network Boundaries
Then verify network isolation:
- •
Firewall Rules
- •No 0.0.0.0/0 ingress (except load balancers)?
- •Deny rules to restrict default allow?
- •Tags used to target specific instances?
- •
VPC Design
- •Private Google Access enabled?
- •Cloud NAT for outbound?
- •VPC Flow Logs enabled?
- •
Service Access
- •Private Service Connect?
- •VPC Service Controls?
- •No public IPs on compute?
Phase 3: Check Data Protection
Finally, verify data security:
- •
Encryption
- •CMEK for sensitive data?
- •Data encrypted in transit?
- •Secret Manager for credentials?
- •
Storage Security
- •Uniform bucket-level access?
- •No public buckets?
- •Versioning for critical data?
Red Flags - STOP and Investigate
IAM Red Flags
# ❌ CRITICAL: Primitive role
resource "google_project_iam_member" "bad" {
role = "roles/editor" # Too broad!
member = "serviceAccount:..."
}
# ❌ CRITICAL: Public access
resource "google_storage_bucket_iam_member" "bad" {
role = "roles/storage.objectViewer"
member = "allUsers" # Anyone on internet!
}
# ❌ HIGH: All authenticated users
member = "allAuthenticatedUsers" # Any Google account!
# ❌ HIGH: Default service account
resource "google_compute_instance" "bad" {
service_account {
email = "PROJECT_NUMBER-compute@developer.gserviceaccount.com"
}
}
Network Red Flags
# ❌ CRITICAL: SSH from anywhere
resource "google_compute_firewall" "bad" {
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["0.0.0.0/0"] # From anywhere!
}
# ❌ HIGH: All protocols
allow {
protocol = "all" # Everything open!
}
# ❌ HIGH: Cloud SQL public IP
resource "google_sql_database_instance" "bad" {
settings {
ip_configuration {
ipv4_enabled = true # Public IP!
}
}
}
Cloud Functions Red Flags
# ❌ HIGH: Public invocation
resource "google_cloudfunctions2_function_iam_member" "bad" {
role = "roles/cloudfunctions.invoker"
member = "allUsers" # Anyone can invoke!
}
# ❌ HIGH: Default service account
# (Not specifying service_account_email)
# ❌ MEDIUM: No VPC connector
# (Missing vpc_connector for internal resources)
Common Rationalizations - Don't Accept These
| Excuse | Reality |
|---|---|
| "Editor role is easiest" | Predefined roles exist. Take 5 minutes to find the right one. |
| "allAuthenticatedUsers is secure" | It means ANY Google account. That's not secure. |
| "Default SA is fine" | Default SA has Editor. Create dedicated accounts. |
| "We need public Cloud SQL" | Use Cloud SQL Auth Proxy. Never public. |
| "0.0.0.0/0 is temporary" | Temporary becomes permanent. Use IAP from day one. |
| "Function must be public" | Use API Gateway or load balancer with auth. |
GCP Security Checklist
Before approving GCP infrastructure:
IAM:
- • No primitive roles (owner/editor/viewer)
- • Dedicated service accounts per workload
- • No
allUsersorallAuthenticatedUsers - • Workload Identity for GKE
- • Conditions on sensitive bindings
Network:
- • No 0.0.0.0/0 firewall rules
- • IAP for administrative access
- • VPC Flow Logs enabled
- • Private Google Access enabled
Storage:
- • Uniform bucket-level access
- • No public buckets
- • CMEK for sensitive data
- • Versioning enabled
Compute:
- • Dedicated service accounts
- • No public IPs (use Cloud NAT)
- • VPC connectors for serverless
Quick Patterns
Secure Service Account
resource "google_service_account" "app" {
account_id = "my-app-sa"
display_name = "My App Service Account"
description = "Dedicated SA for my-app with minimal permissions"
}
# Specific predefined role
resource "google_project_iam_member" "app_storage" {
project = var.project_id
role = "roles/storage.objectViewer" # Predefined, minimal
member = "serviceAccount:${google_service_account.app.email}"
condition {
title = "Only from VPC"
description = "Restrict to internal access"
expression = "request.auth.access_levels.hasOnly(['accessPolicies/123/accessLevels/vpc_only'])"
}
}
Secure Cloud Storage
resource "google_storage_bucket" "secure" {
name = "my-secure-bucket"
location = "US"
uniform_bucket_level_access = true
encryption {
default_kms_key_name = google_kms_crypto_key.bucket_key.id
}
versioning {
enabled = true
}
logging {
log_bucket = google_storage_bucket.logs.name
}
}
# No public access - only specific SA
resource "google_storage_bucket_iam_member" "app_access" {
bucket = google_storage_bucket.secure.name
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.app.email}"
}
Secure Firewall
# Allow only from IAP for SSH
resource "google_compute_firewall" "allow_iap_ssh" {
name = "allow-iap-ssh"
network = google_compute_network.vpc.name
allow {
protocol = "tcp"
ports = ["22"]
}
source_ranges = ["35.235.240.0/20"] # IAP range only
target_tags = ["allow-iap-ssh"]
}
Quick Security Scans
# GCP native tools gcloud asset search-all-iam-policies --query="policy:allUsers" gcloud compute firewall-rules list --filter="sourceRanges:0.0.0.0/0" gcloud sql instances list --filter="settings.ipConfiguration.ipv4Enabled=true" # Third-party scanners checkov -f main.tf # Terraform scanning forseti # GCP security scanning gcloud scc findings list # Security Command Center
References
Detailed patterns and examples in references/:
- •
iam-patterns.md- Advanced IAM and Workload Identity - •
network-security.md- VPC and firewall patterns - •
organization-policies.md- Org-level constraints