Review GCP VM API scopes and IAM permissions

Distinguish cloud-platform scope from actual IAM permissions and apply least privilege.

Description

The broad cloud-platform OAuth scope does not itself grant every Google Cloud permission. Actual API access requires the service account’s IAM permissions. Google generally recommends cloud-platform scope together with least-privilege IAM roles.

Excessive IAM permissions increase the impact of VM compromise. Narrowing scopes alone does not control every authentication method or permission.

Potential impact

  • A VM with excessive IAM roles can affect multiple resources if compromised.
  • Removing required scopes can break legitimate API calls.

Remediation

  • Identify the attached service account and grant only required resource and operation permissions through IAM. Do not remove cloud-platform merely because it is present.
  • If separate requirements call for narrower scopes, check compatibility with the required APIs and authentication methods. Test that necessary calls succeed and unwanted calls are denied after changes.

Examples

These examples compare OAuth scopes only and do not define IAM roles. Replace the historical image and network with actual deployment values and review effective service-account permissions. The after configuration is an option for environments requiring limited scopes, not a universal security fix.

Before

hcl
resource "google_compute_instance" "vm" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"

    access_config {}
  }

  service_account {
    scopes = ["userinfo-email", "compute-ro", "storage-ro", "cloud-platform"]
  }
}

After

hcl
resource "google_compute_instance" "vm" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"

    access_config {}
  }

  service_account {
    scopes = ["userinfo-email", "compute-ro", "storage-ro"]
  }
}

Explanation:

  • Before: cloud-platform is included, but actual permissions remain limited by IAM roles.
  • After: Scopes are narrowed. Check for broken required calls; this does not replace least-privilege IAM.

References