GCP Landing Zone -- Security¶
Identity flow, threat model, access control, DMZ patterns, VPC Service Controls, and security best practices for GCP project architectures.
Security Model Overview¶
GCP security operates in layers:
- Identity and Access Management (IAM) -- who can do what on which resource
- Organization Policies -- constraints on what configurations are allowed
- Network Security -- VPC firewalls, VPC Service Controls, Cloud Armor
- Data Protection -- encryption at rest and in transit, VPC Service Controls perimeters
- Zero-Trust Access -- Identity-Aware Proxy (IAP), BeyondCorp model
IAM Architecture¶
Role Hierarchy and Delegation¶
graph TD
OrgAdmin[Organization Admin\nresourcemanager.organizationAdmin] --> SharedVPCAdmin[Shared VPC Admin\ncompute.xpnAdmin + resourcemanager.projectIamAdmin]
OrgAdmin --> FolderAdmin[Folder Admin\nresourcemanager.folderAdmin]
SharedVPCAdmin --> NetAdmin[Network Admin\ncompute.networkAdmin - host project]
SharedVPCAdmin --> SecAdmin[Security Admin\ncompute.securityAdmin - host project]
SharedVPCAdmin --> SvcProjAdmin[Service Project Admin\ncompute.networkUser - subnets]
SvcProjAdmin --> InstanceAdmin[Instance Admin\ncompute.instanceAdmin - service project]
IAM Best Practices¶
| Practice | Implementation |
|---|---|
| Grant roles to groups, not individuals | Create Google Groups per team/function (e.g., [email protected]) |
| Grant at highest appropriate level | Org-level for cross-cutting roles; folder-level for team-scoped roles |
| Use custom roles for least privilege | Narrow predefined roles when they grant too many permissions |
| Use deny policies for guardrails | IAM deny policies override allow policies (set at org/folder level) |
| Enforce MFA | Required for all human principals via Google Workspace / Cloud Identity |
| Use Workload Identity Federation | For external workloads (AWS, Azure, on-prem) instead of service account keys |
| Disable SA key creation | Org policy: constraints/iam.disableServiceAccountKeyCreation |
| Short-lived credentials | Use Security Token Service for temporary elevated access |
Service Account Strategy¶
- One service account per application/component (not shared)
- Use Workload Identity for GKE pods (not service account keys)
- Use
constraints/iam.allowedPolicyMemberDomainsto restrict SA membership to org domains - Audit service account usage with IAM Policy Analyzer
Network Security¶
DMZ-Less Pattern (Google Recommended)¶
GCP's recommended security architecture eliminates the need for a traditional DMZ:
| Traditional DMZ | GCP DMZ-Less Equivalent |
|---|---|
| Public-facing subnet with bastion host | Identity-Aware Proxy (IAP) for admin access |
| NAT gateway VMs in DMZ | Cloud NAT (managed service, no VMs) |
| WAF appliances in DMZ | Cloud Armor policies on external LB |
| API gateway in DMZ | External Load Balancer + Cloud Endpoints / API Gateway |
| Public subnet for load balancers | External LBs are Google-managed (outside VPC) |
VPC Firewall Strategy¶
graph TD
subgraph Firewall Layers
FW1[1. Default deny all ingress\nImplied rule - always present]
FW2[2. Allow health check ranges\n35.191.0.0/16, 130.211.0.0/22]
FW3[3. Allow IAP ranges\n35.235.240.0/20]
FW4[4. Allow inter-tier traffic\nApp subnet to Data subnet only]
FW5[5. Deny all egress to internet\nExplicit deny (override implied allow)]
end
Recommended Firewall Rules¶
| Rule | Direction | Source | Target (Tag) | Action |
|---|---|---|---|---|
| Allow LB health checks | Ingress | 35.191.0.0/16, 130.211.0.0/22 |
load-balanced-backend |
Allow |
| Allow IAP SSH/RDP | Ingress | 35.235.240.0/20 |
iap-access |
Allow |
| Allow app-to-data | Ingress | Tag app-tier |
Tag data-tier on DB port |
Allow |
| Allow internal between app instances | Ingress | Tag app-tier |
Tag app-tier |
Allow |
| Deny all other ingress | Ingress | 0.0.0.0/0 |
All instances | Deny |
| Restrict egress | Egress | Tag restricted-egress |
Specific destinations only | Allow |
| Deny egress to internet | Egress | All instances | 0.0.0.0/0 |
Deny |
Use network tags (not IP ranges) for rule targets so rules remain valid when CIDR blocks change.
VPC Service Controls¶
VPC Service Controls create security perimeters around Google-managed services (BigQuery, Cloud Storage, Pub/Sub, etc.) to prevent data exfiltration. They operate independently of and in addition to IAM.
graph TD
subgraph Service Perimeter
ProjA[Project A\nBigQuery Dataset]
ProjB[Project B\nCloud Storage Bucket]
VPC1[VPC Network\nVMs]
end
VPC1 -->|Allowed| ProjA
VPC1 -->|Allowed| ProjB
ProjA -->|Allowed| ProjB
ExtUser[External User\noutside perimeter] -->|Denied| ProjA
VPC1 -->|Denied| ExtBucket[External Bucket\noutside perimeter]
Key Concepts¶
| Concept | Description |
|---|---|
| Service Perimeter | Boundary around projects and VPCs; blocks cross-perimeter data access by default |
| Ingress Rule | Allows access from outside the perimeter based on context (IP, identity, device) |
| Egress Rule | Allows data to leave the perimeter to specific external destinations |
| Access Level | Context-aware access definition (source IP, identity, device policy, geography) |
| Perimeter Bridge | Connects two perimeters for controlled data exchange |
| Restricted VIP | restricted.googleapis.com (199.36.153.4/30) -- private route to Google APIs, no internet exposure |
| Dry Run Mode | Monitor violations without blocking access (for policy testing) |
Recommended Configuration¶
# Create an access level (allowed network ranges)
gcloud access-context-manager levels create corporate-network \
--title="Corporate Network" \
--basic-level-spec=access-level.yaml \
--policy=ACCESS_POLICY_ID
# access-level.yaml
# {
# "conditions": [
# {
# "ipSubnetworks": ["203.0.113.0/24"]
# }
# ]
# }
# Create a service perimeter
gcloud access-context-manager perimeters create prod-perimeter \
--title="Production Perimeter" \
--resources=projects/PROJECT_NUM \
--restricted-services="bigquery.googleapis.com,storage.googleapis.com" \
--access-levels=corporate-network \
--policy=ACCESS_POLICY_ID
Cloud Armor¶
Attach WAF policies to external load balancers:
# Create security policy with WAF rules
gcloud compute security-policies create prod-waf-policy \
--description="Production WAF policy"
# Add preconfigured WAF rules (OWASP ModSecurity CRS)
gcloud compute security-policies rules create 1000 \
--security-policy=prod-waf-policy \
--expression="evaluatePreconfiguredExpr('sqli-v33-stable')" \
--action=deny-403 \
--description="Block SQL injection"
gcloud compute security-policies rules create 1001 \
--security-policy=prod-waf-policy \
--expression="evaluatePreconfiguredExpr('xss-v33-stable')" \
--action=deny-403 \
--description="Block XSS"
# Attach to backend service
gcloud compute backend-services update prod-backend \
--security-policy=prod-waf-policy
Identity-Aware Proxy (IAP)¶
IAP for SSH Access (Replaces Bastion Hosts)¶
# Enable IAP for the project
gcloud compute project-info add-metadata \
--metadata=enable-oslogin=TRUE
# Grant IAP-secured Tunnel User role
gcloud compute instances add-iam-policy-binding my-instance \
--member="user:[email protected]" \
--role="roles/iap.tunnelResourceAccessor"
# SSH through IAP (no external IP needed on VM)
gcloud compute ssh my-instance --tunnel-through-iap
IAP for Web Application Authentication¶
graph LR
User[User Browser] --> IAP[Identity-Aware Proxy]
IAP -->|Verify identity + context| IAM[Cloud IAM]
IAM -->|Authorized| App[Application Backend]
IAM -->|Denied| Reject[403 Forbidden]
App -->|Validate IAP JWT| Verify[Verify signed headers\nX-Goog-Iap-Jwt-Assertion]
The application backend validates the IAP-signed JWT header (X-Goog-Iap-Jwt-Assertion) to confirm the request passed through IAP. This provides zero-trust authentication without managing certificates or identity providers at the application level.
Threat Model¶
Threat Categories and Mitigations¶
| Threat | GCP Mitigation | Configuration |
|---|---|---|
| Stolen credentials | MFA, IAP, VPC Service Controls | Enforce MFA org-wide; restrict API access to authorized networks |
| Data exfiltration via misconfigured IAM | VPC Service Controls | Block data copy operations crossing perimeter boundaries |
| Data exfiltration via compromised VM | VPC Service Controls + Cloud NAT | VMs cannot access services outside perimeter; NAT logs all egress |
| External IP on private workload | Org policy + firewall | constraints/compute.vmExternalIpAccess denies external IPs |
| SQL injection / XSS | Cloud Armor | WAF rules on external LBs |
| Insider threat | IAM deny policies + audit logs | Centralized logging; deny policies for sensitive operations |
| Service account key leakage | Org policy | constraints/iam.disableServiceAccountKeyCreation; use Workload Identity |
| Container image tampering | Binary Authorization | Enforce signed images in GKE |
| On-premises network breach | VPC Service Controls + context-aware access | Extend perimeter via VPN/Interconnect; restrict by source IP |
| DNS exfiltration | Cloud DNS logging + monitoring | Log all DNS queries; alert on suspicious patterns |
Encryption¶
| Layer | GCP Default | Recommended Enhancement |
|---|---|---|
| At rest | Google-managed encryption (AES-256) | Customer-Managed Encryption Keys (CMEK) via Cloud KMS for regulated data |
| In transit within Google | Encryption between data centers | Use Private Service Connect or VPC Peering to avoid internet transit |
| In transit to/from internet | TLS on external LBs | Enforce TLS 1.2+ via Cloud Armor security policy |
| Application-level | N/A | Application-layer encryption for highly sensitive fields |
Security Command Center¶
Enable SCC Premium for centralized threat detection:
| SCC Feature | Purpose |
|---|---|
| Security Health Analytics | Detect misconfigurations (open firewall rules, public buckets) |
| Threat Detection | Detect crypto mining, malware, unauthorized access |
| Vulnerability scanning | OS and container vulnerability assessment |
| Web Security Scanner | DAST for App Engine, Cloud Run, and Compute Engine |
| Asset Inventory | Track all resources and their security posture |
| Event Threat Detection | Real-time threat detection from Cloud Audit Logs |
Security Baseline Checklist¶
- Organization resource created and org admin roles assigned
- Baseline org policies applied (OS Login, Shielded VM, SA key restriction, resource locations)
- MFA enforced for all human identities
- IAM roles granted to groups (not individuals)
- Shared VPC configured with centralized network admin
- All workloads in private subnets (no external IPs)
- Cloud NAT configured for outbound egress
- VPC Service Controls perimeters created for sensitive data
- Cloud Armor policies on all external load balancers
- IAP enabled for SSH/RDP access (no bastion hosts)
- Binary Authorization enforced for GKE clusters
- VPC Flow Logs enabled on all subnets
- Centralized logging sink configured
- Security Command Center Premium enabled
- Cloud Audit Logs enabled for all services
- Billing budgets and alerts configured
- CMEK configured for regulated data stores
- Regular DR and security testing cadence established