CloudGoogle Cloud

Scan GCP Snapshots Across Projects

Configure cnspec to scan GCP Compute Engine snapshots that reside in a different project than your scanner VM.

cnspec can scan GCP Compute Engine snapshots that reside in a different project than your scanner VM. During a cross-project snapshot scan, cnspec:

  1. Reads the snapshot metadata from the target project (the project containing the snapshot)
  2. Creates a temporary disk from the snapshot in the scanner project (the project where your cnspec VM runs)
  3. Attaches the disk to the scanner VM
  4. Mounts and scans the filesystem
  5. Detaches and deletes the temporary disk

Because cnspec uses a single credential for all of these steps, the scanner VM's service account must have permissions in both projects.

Workload Identity Federation (WIF) credentials are not supported for snapshot scanning. WIF tokens are scoped to a single project and cannot perform disk operations in the scanner project. Use the VM's default service account with direct IAM grants instead.

Prerequisites

  • A GCP Compute Engine VM running cnspec (the "scanner VM"), set up as described in Scan GCP Instances Using Snapshots
  • A service account attached to the scanner VM
  • A snapshot in a separate GCP project that you want to scan

Step 1: Grant snapshot read permissions on the target project

The scanner VM's service account needs permission to read snapshots from the target project.

SCANNER_SA_EMAIL="scanner-sa@scanner-project.iam.gserviceaccount.com"
TARGET_PROJECT="target-project-a"

Option A: Predefined role (simpler, broader permissions)

gcloud projects add-iam-policy-binding "$TARGET_PROJECT" \
  --member="serviceAccount:$SCANNER_SA_EMAIL" \
  --role="roles/compute.storageAdmin"

Option B: Custom role (least privilege)

gcloud iam roles create mondooSnapshotReader \
  --project="$TARGET_PROJECT" \
  --title="Mondoo Snapshot Reader" \
  --permissions="compute.snapshots.get,compute.snapshots.list,compute.snapshots.useReadOnly" \
  --stage="GA"

gcloud projects add-iam-policy-binding "$TARGET_PROJECT" \
  --member="serviceAccount:$SCANNER_SA_EMAIL" \
  --role="projects/$TARGET_PROJECT/roles/mondooSnapshotReader"

Step 2: Grant disk and instance permissions on the scanner project

The scanner VM's service account needs permission to create temporary disks and attach them to itself.

SCANNER_PROJECT="scanner-project"

gcloud iam roles create mondooSnapshotScanner \
  --project="$SCANNER_PROJECT" \
  --title="Mondoo Snapshot Scanner" \
  --permissions="compute.disks.create,compute.disks.get,compute.disks.use,compute.disks.delete,compute.instances.get,compute.instances.attachDisk,compute.instances.detachDisk" \
  --stage="GA"

gcloud projects add-iam-policy-binding "$SCANNER_PROJECT" \
  --member="serviceAccount:$SCANNER_SA_EMAIL" \
  --role="projects/$SCANNER_PROJECT/roles/mondooSnapshotScanner"

Step 3: Run the snapshot scan

If GOOGLE_APPLICATION_CREDENTIALS is set (for example, to a WIF credential file), unset it so cnspec uses the VM's default service account:

unset GOOGLE_APPLICATION_CREDENTIALS

Then run the scan:

sudo cnspec scan gcp snapshot my-vm-snapshot --project-id target-project-a

Permissions reference

Target project (where the snapshot lives)

PermissionPurpose
compute.snapshots.getRead snapshot metadata
compute.snapshots.listDiscover available snapshots
compute.snapshots.useReadOnlyCreate a disk from the snapshot

Scanner project (where the scanner VM runs)

PermissionPurpose
compute.disks.createCreate a temporary disk from the snapshot
compute.disks.getCheck disk status during creation
compute.disks.useAttach the disk to the scanner VM
compute.disks.deleteClean up the temporary disk after scanning
compute.instances.getRetrieve scanner VM metadata
compute.instances.attachDiskAttach the temporary disk
compute.instances.detachDiskDetach the disk after scanning

Troubleshooting

Error: ACCESS_TOKEN_SCOPE_INSUFFICIENT

Request had insufficient authentication scopes.
Reason: ACCESS_TOKEN_SCOPE_INSUFFICIENT

This means the VM has the correct IAM roles but was created without the necessary OAuth scopes. GCP VMs have two layers of access control: IAM roles and access scopes (set at VM creation time). The default scope often does not include compute.

Check current scopes:

gcloud compute instances describe INSTANCE-NAME --zone=ZONE \
  --format='value(serviceAccounts[0].scopes)'

Fix by updating to cloud-platform scope (requires a VM restart):

gcloud compute instances stop INSTANCE-NAME --zone=ZONE

gcloud compute instances set-service-account INSTANCE-NAME \
  --zone=ZONE \
  --scopes=cloud-platform

gcloud compute instances start INSTANCE-NAME --zone=ZONE

After the restart, re-run the cnspec scan command.

On this page