For the complete documentation index, see llms.txt. This page is also available as Markdown.

GCP_RUNS_AS

Summary

Forestall ACL Alias

GCP_RUNS_AS

GCP Alias

Compute Execution & Pipeline Pivots

Affected Object Types

Service Accounts

Exploitation Certainty

Certain

Description

GCP_RUNS_AS represents that a GCE virtual machine runs as an attached service account. It points from the VM to the service account bound to it at creation time:

Virtual Machine ── GCP_RUNS_AS ──► Service Account

Attaching a service account to a VM makes that identity available to every process on the machine. The guest does not hold a key file; instead the metadata server at metadata.google.internal issues short-lived OAuth access tokens on request, with no authentication beyond being on the instance:

http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

This is by design and is how workloads authenticate to Google APIs without managing credentials. Its consequence for the graph is that code execution on a VM is equivalent to holding the attached service account's IAM privileges. GCP_RUNS_AS is the edge that makes that equivalence explicit, and it is what turns a shell into a privilege escalation.

Why the edge matters for attack paths

GCP_RUNS_AS is the pivot that converts machine access into identity. It completes several compound paths that are incomplete without it:

Preceding edge
Combined effect

OS Login session yields the attached SA's token

Planted key yields a shell, then the attached SA's token

Attacker creates a new VM with a chosen SA attached, establishing this edge deliberately to harvest that SA

The last is the important one. GCP_ACT_AS_SA on its own only grants the right to attach a service account to infrastructure — it is not directly exploitable. It becomes an escalation only when combined with the ability to create or modify a compute resource, because the new VM's GCP_RUNS_AS edge is what actually surrenders the token. An attacker with both can attach any service account they can act as to a VM they control, and read its token out of the metadata server.

The default Compute Engine service account deserves particular attention. Unless explicitly overridden, GCP attaches it to new VMs and grants it roles/editor on the project if iam.automaticIamGrantsForDefaultServiceAccounts is not enforced. In that case, any VM running as it therefore has an edge to a project-editor identity, which itself carries GCP_CREATE_SA_KEYS and GCP_ACT_AS_SA. A single low-value VM can be the entry point to full project control through this chain.

Access scopes are a legacy secondary restriction on what a VM's token may call. They are not a security boundary to rely on: https://www.googleapis.com/auth/cloud-platform is the common default and permits every API the service account's IAM roles allow.

Identification

gcloud CLI

A VM is only as sensitive as the roles held by the service account it runs as and service accounts parented in one project frequently holds roles elsewhere.

GCP Console

  1. Open GCP Console → Compute Engine → VM Instances → select an instance.

  2. The Service accounts section on the instance detail page names the attached identity and its access scopes.

  3. Follow that identity to IAM & Admin → Service Accounts → select the SA → Permissions, then check IAM & Admin → IAM for the roles it holds on the project.

  4. Compare against IAM & Admin → IAM at folder and organization scope — an attached SA may hold bindings well above the VM's own project.

Exploitation

GCP_RUNS_AS has no exploit of its own — the edge simply records an attachment, not a permission grant — but reaching it requires code execution on the VM, and cashing it in is immediate and unconditional. Its significance is what that execution is worth.

Given any shell on the instance, the attached identity is available immediately and without a credential:

The token is a bearer credential usable from anywhere until it expires, so it can be exfiltrated and replayed off the instance:

Where the SA is a project editor — as the default Compute Engine service account is — the path continues into durable persistence, since editor carries the ability to create service account keys:

Two properties make this pivot valuable to an attacker beyond the privileges themselves. Requests made with the token are attributed to the service account, not to the attacker's own principal, so activity blends into normal workload traffic. And the credential is issued on demand by the metadata server, so there is no key file on disk to find and no rotation event to observe.

Mitigation

  1. Never leave the default Compute Engine service account attached. Sometimes it holds roles/editor on the project by default. Create a dedicated, minimally privileged service account per workload and attach that instead.

  2. Grant the attached SA only the roles its workload needs, at the narrowest scope that works. The VM's blast radius is exactly this SA's permission set — treat every role granted to it as granted to anyone who gets code execution on the machine.

  3. Do not attach an SA at all to VMs that make no Google API calls. An instance with no attached identity has no token to steal.

  4. Block metadata server access from workloads that do not need it, using network policy or host-level egress controls. This is the only control that severs the edge rather than limiting its value.

  5. Enforce the iam.automaticIamGrantsForDefaultServiceAccounts organization policy constraint so newly created default service accounts do not automatically receive roles/editor.

  6. Restrict roles/iam.serviceAccountUser (GCP_ACT_AS_SA) so attackers cannot choose which identity a new VM runs as. Pay particular attention to principals that hold it together with compute-create permissions — that combination lets them create this edge at will.

  7. Audit attachments of privileged service accounts to compute resources on a schedule, and alert when an SA with folder- or org-scoped roles is attached to a VM.

Detection

Log Type
Method
Key Fields

Admin Activity

v1.compute.instances.insert

serviceAccounts[].email on the new instance — the edge being created

Admin Activity

v1.compute.instances.setServiceAccount

Attached identity changed on an existing VM

Admin Activity

SetIamPolicy

New roles granted to an SA that is attached to VMs

Data Access

Token use by SA

authenticationInfo.principalEmail is the SA; compare callerIp against the VM's egress

Alert on:

  • VMs created with a service account that holds folder- or organization-scoped roles.

  • setServiceAccount on an existing VM — reattaching a different identity is uncommon in steady-state operations and is a direct attempt to acquire this edge.

  • Any VM created with the default Compute Engine service account attached, given its default roles/editor grant.

  • Activity attributed to a VM-attached service account originating from an IP outside that VM's egress range, which indicates the token was exfiltrated rather than used in place.

  • An attached service account calling APIs unrelated to its workload's normal behaviour, particularly iam.serviceAccounts.keys.create or Secret Manager reads it has never made before.

  • The same principal holding roles/iam.serviceAccountUser and compute-create permissions, which allows this edge to be established on demand.

References

  • https://cloud.google.com/compute/docs/access/service-accounts

  • https://cloud.google.com/compute/docs/metadata/overview

  • https://cloud.google.com/iam/docs/service-account-overview

  • https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances

  • https://cloud.google.com/iam/docs/best-practices-service-accounts

Last updated

Was this helpful?