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:
- Reads the snapshot metadata from the target project (the project containing the snapshot)
- Creates a temporary disk from the snapshot in the scanner project (the project where your cnspec VM runs)
- Attaches the disk to the scanner VM
- Mounts and scans the filesystem
- 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_CREDENTIALSThen run the scan:
sudo cnspec scan gcp snapshot my-vm-snapshot --project-id target-project-aPermissions reference
Target project (where the snapshot lives)
| Permission | Purpose |
|---|---|
compute.snapshots.get | Read snapshot metadata |
compute.snapshots.list | Discover available snapshots |
compute.snapshots.useReadOnly | Create a disk from the snapshot |
Scanner project (where the scanner VM runs)
| Permission | Purpose |
|---|---|
compute.disks.create | Create a temporary disk from the snapshot |
compute.disks.get | Check disk status during creation |
compute.disks.use | Attach the disk to the scanner VM |
compute.disks.delete | Clean up the temporary disk after scanning |
compute.instances.get | Retrieve scanner VM metadata |
compute.instances.attachDisk | Attach the temporary disk |
compute.instances.detachDisk | Detach the disk after scanning |
Troubleshooting
Error: ACCESS_TOKEN_SCOPE_INSUFFICIENT
Request had insufficient authentication scopes.
Reason: ACCESS_TOKEN_SCOPE_INSUFFICIENTThis 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=ZONEAfter the restart, re-run the cnspec scan command.