gcp-wif-token-valid-for-sa
match (record)
{
"field": "iamPolicy.bindings[role=roles/iam.workloadIdentityUser]",
"resource_type": "google.iam.ServiceAccount"
}
emit
| source type | Token |
|---|---|
| target type | ServiceIdentity |
| source | <federated STS access token minted for the WIF principal> |
| target | <impersonated ServiceAccount> |
Narrative
A federated STS token for the WIF principal is valid for {sa.name} (short-lived, no static key), obtained via the token exchange + getAccessToken.
Raw rule rules/explicit/gcp-wif.yaml
id: gcp-wif-token-valid-for-sa
emits: CredentialValidFor
applies_to:
- gcp
match_record:
resource_type: google.iam.ServiceAccount
field: iamPolicy.bindings[role=roles/iam.workloadIdentityUser]
emit:
source_type: Token
target_type: ServiceIdentity
source: <federated STS access token minted for the WIF principal>
target: <impersonated ServiceAccount>
api_source: sts.googleapis.com token-exchange + iamcredentials generateAccessToken
evidence_field: presence of a roles/iam.workloadIdentityUser binding for a WIF principal
properties:
static_key: false
mechanism: sts.googleapis.com token-exchange -> iam.serviceAccounts.getAccessToken
false_positive_note: 'This is not a harvestable long-lived credential (no iam.serviceAccountKeys.create):
the federated token is short-lived and only mintable by an external identity that satisfies the provider
trust AND the workloadIdentityUser binding. Path value comes from the derived CanFederateAs, not from
this fact alone. Do not emit if no workloadIdentityUser binding maps a WIF principal to the SA.'
narrative: A federated STS token for the WIF principal is valid for {sa.name} (short-lived, no static
key), obtained via the token exchange + getAccessToken.