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 AccountAttaching 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/tokenThis 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:
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
Open GCP Console → Compute Engine → VM Instances → select an instance.
The Service accounts section on the instance detail page names the attached identity and its access scopes.
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.
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
Never leave the default Compute Engine service account attached. Sometimes it holds
roles/editoron the project by default. Create a dedicated, minimally privileged service account per workload and attach that instead.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.
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.
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.
Enforce the
iam.automaticIamGrantsForDefaultServiceAccountsorganization policy constraint so newly created default service accounts do not automatically receiveroles/editor.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.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
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.
setServiceAccounton 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/editorgrant.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.createor Secret Manager reads it has never made before.The same principal holding
roles/iam.serviceAccountUserand 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?