Safeguard
Cloud Security

GCP Security Best Practices for 2026

A hands-on Google Cloud hardening guide: resource hierarchy and Organization Policy, least-privilege IAM, VPC Service Controls, CMEK, and Security Command Center — with Terraform and gcloud examples.

Marcus Chen
Cloud Security Engineer
5 min read

Google Cloud rewards teams that understand its resource hierarchy and punishes those who don't. The most common way GCP data leaks is depressingly simple: a Cloud Storage bucket granted allUsers or allAuthenticatedUsers, a service account key exported to a laptop and never rotated, or a project spun up outside any folder so it inherits none of the org's guardrails. GCP's security model is genuinely strong — but only when you configure the hierarchy, IAM, and network controls to work together. This guide covers the practices that matter, structured around the layers Google actually gives you to control.

Start With the Resource Hierarchy

Everything in GCP inherits downward: Organization → Folders → Projects → Resources. IAM bindings and Organization Policies set high in the tree flow to everything beneath them, so the hierarchy is your primary control plane. Get this right and most other controls become one-time settings rather than per-project chores.

Apply Organization Policy constraints at the org node so no project can opt out:

resource "google_organization_policy" "no_public_buckets" {
  org_id     = var.org_id
  constraint = "constraints/storage.publicAccessPrevention"
  boolean_policy { enforced = true }
}

resource "google_organization_policy" "disable_sa_keys" {
  org_id     = var.org_id
  constraint = "constraints/iam.disableServiceAccountKeyCreation"
  boolean_policy { enforced = true }
}

Enforcing storage.publicAccessPrevention and iam.disableServiceAccountKeyCreation org-wide eliminates two of the most common GCP breach paths in a single stroke — public buckets and long-lived exported keys.

Practice Least Privilege in IAM

GCP's primitive roles — Owner, Editor, Viewer — are almost always too broad. Editor alone grants write access across dozens of services. Prefer predefined roles scoped to the job, and reserve custom roles for cases where nothing fits.

  • Prefer Workload Identity Federation over service account keys. Federation lets workloads in GitHub Actions, AKS, EKS, or on-prem exchange their existing identity for short-lived GCP credentials — no downloadable key to leak.
  • Use the IAM Recommender. It analyzes 90 days of usage and proposes tighter roles, surfacing the gap between granted and used permissions.
  • Bind roles at the narrowest scope. A service that reads one bucket should get roles/storage.objectViewer on that bucket, not project-level Editor.
# Find bindings that grant the overly broad Editor/Owner primitive roles
gcloud projects get-iam-policy PROJECT_ID \
  --flatten="bindings[].members" \
  --filter="bindings.role:roles/editor OR bindings.role:roles/owner" \
  --format="table(bindings.role, bindings.members)"

Pay particular attention to the default service accounts. The Compute Engine and App Engine default service accounts are created with the broad Editor role, and any VM or workload that runs as one inherits it. Either disable automatic role grants to default service accounts with the iam.automaticIamGrantsForDefaultServiceAccounts constraint, or create dedicated, narrowly scoped service accounts for each workload and stop using the defaults entirely.

Isolate Data and Network Boundaries

Two controls do most of the heavy lifting here. VPC Service Controls create a service perimeter around APIs like Cloud Storage and BigQuery so that even a valid, leaked credential can't exfiltrate data to a project outside the perimeter — a direct mitigation for the "stolen key" scenario. Private Google Access and firewall rules keep workloads off the public internet.

resource "google_compute_firewall" "deny_ssh_from_internet" {
  name      = "deny-ssh-inbound"
  network   = google_compute_network.app.id
  direction = "INGRESS"
  priority  = 900
  deny { protocol = "tcp"; ports = ["22"] }
  source_ranges = ["0.0.0.0/0"]
}

Reach VM management planes through Identity-Aware Proxy (IAP) rather than opening SSH to the world.

Encrypt With Keys You Control

GCP encrypts everything at rest by default with Google-managed keys. For regulated data, use customer-managed encryption keys (CMEK) via Cloud KMS so you control rotation and can revoke access by disabling the key. Store application secrets in Secret Manager, granted to workloads through their service account identity rather than embedded in code or images.

Turn On Continuous Detection

Enable Security Command Center to continuously scan for misconfigurations, public resources, and IAM anomalies, and stream Cloud Audit Logs — especially Admin Activity and Data Access logs — to a sink you retain for the period your compliance framework requires. Data Access logs are not fully enabled by default for most services; turn them on explicitly for sensitive projects.

GCP Hardening Checklist

LayerControlVerify
HierarchyOrg PolicypublicAccessPrevention + key-creation constraints enforced at org node
IAMRolesNo project-level Editor/Owner on service accounts; keys disabled
IdentityFederationWorkload Identity Federation used instead of exported keys
NetworkPerimeterVPC Service Controls around Storage/BigQuery; no 0.0.0.0/0 on 22
DataEncryptionCMEK for regulated data; secrets in Secret Manager
DetectionSCC + logsSecurity Command Center on; Data Access logs enabled and retained

How Safeguard Helps

Every one of these controls is expressible in Terraform, which means every one of them can be verified before it reaches Google Cloud. Safeguard's infrastructure-as-code scanning reads your Terraform and flags public bucket bindings, allUsers grants, service-account-key creation, over-broad primitive roles, and open firewall rules in the pull request — mapped to the exact resource block so the fix lands before merge, not after Security Command Center flags it in production. The workloads deploying onto that infrastructure are covered by software composition analysis, which generates an SBOM and identifies vulnerable dependencies your code actually reaches, and by container image scanning for the images you push to Artifact Registry. Griffin, Safeguard's AI triage engine, prioritizes findings by real exploitability rather than raw severity. Teams comparing this shift-left approach to a cloud-native posture platform often review the Safeguard vs Prisma Cloud comparison.

Catch GCP misconfigurations in the pull request — get started free or read the documentation.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.