Google CloudStatic-verified

Keyless Access Scoped to Callers You Meant

attribute_condition is optional, and the issuer is not yours - so omitting it on a GitHub Actions provider trusts every workflow in every repository belonging to anyone on GitHub. It works perfectly in testing, because your workflow is one of the ones it admits. Refused here, along with a wildcard principalSet.

terraformGoogle Cloudgcp
gcp-workload-identity-federationvizier v1.2.0

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan clean (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-09-13 · how we verify

Use it from the registry

terraform · opentofu
module "workload_identity_federation" {
  source  = "www.iac-bazaar.com/iac-bazaar/gcp-workload-identity-federation/gcp"
  version = "1.0.0"
}

Needs a registry token from /account/tokens. The module itself is free; the account is what identifies you. Full setup: registry docs.

Cite it in your README

badge · attribution

Paste this beside the module in the repository that uses it. The badge is rendered from this artifact's verification record, so it reads static-verified because the record says so, and the link lands on this page.

README.md, GitLab, Gitea
[![IaC Bazaar: static-verified](https://www.iac-bazaar.com/api/artifacts/gcp-workload-identity-federation/badge)](https://www.iac-bazaar.com/catalog/gcp-workload-identity-federation?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)

Terraform module 1.0.0, static-verified on IaC Bazaar: [Keyless Access Scoped to Callers You Meant](https://www.iac-bazaar.com/catalog/gcp-workload-identity-federation?utm_source=syndication&utm_medium=readme&utm_campaign=artifact)

```hcl
module "workload_identity_federation" {
  source  = "www.iac-bazaar.com/iac-bazaar/gcp-workload-identity-federation/gcp"
  version = "1.0.0"
}
```

Preview:IaC Bazaar: static-verified

Inputs & outputs

Create a free account to read this module's contract

The declared contract - every input name, type, default and description, plus every output - is shown to signed-in accounts, not to anonymous visitors.

A free account sees the contract of every module in the catalogue. There is no subscription and nothing to buy - the modules are free to download, and they run under Vizier.

Documentation

gcp-workload-identity-federation

Keyless access from outside Google, scoped to the callers you actually meant. Works with Terraform and OpenTofu (>= 1.6), google provider >= 6.0, < 7.0.

attribute_condition is optional, and omitting it is the worst default in this service. The issuer is not yours. For GitHub Actions the issuer is GitHub's, so "any token this issuer signs" means any workflow, in any repository, belonging to anybody, anywhere on GitHub - all of it able to impersonate whatever service account the pool grants. The setup works perfectly in testing, because your workflow is one of the ones it admits, and that is exactly why this one gets shipped. A precondition refuses a provider with no condition, and a second refuses a GitHub provider whose condition never mentions the repository or its owner, since a condition that only checks how a token was issued has not narrowed who.

The member string is the other half. A binding to principalSet://…/attribute.repository/my-org/my-repo is one repository; principalSet://…/* is everything the pool admits. Those differ by very little in a place nobody reads twice, so a precondition refuses the wildcard and wildcard_grants is an output that should stay empty.

This exists to replace service account keys, which is the point. A downloaded key is a credential with no expiry that lives in somebody's CI settings forever and survives every offboarding. A federated token lasts an hour and cannot be lifted out of the workflow that earned it - provided the condition above is real.

Pin assertion.sub where you can. GitHub's subject claim already carries the repository and the ref in one value (repo:org/repo:ref:refs/heads/main), so there is no way to satisfy half of it. Separate assertion.repository and assertion.ref clauses are equivalent and more flexible; repository_owner alone is the weakest form still worth having, because it admits every repository in your organisation including one a contractor opened this morning.

Smaller things: google.subject must be mapped and Google's error does not say which key is missing, so a precondition names it; and a pool id cannot be reused for 30 days after deletion, so it is worth picking a name you can live with.

Verification

Static validation runs tofu fmt, init, validate, tflint and checkov. This module has not yet had a live test, so it is published as statically validated with its live test pending and does not carry the live-tested mark.

Usage code & full reference need an account

The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.

  • Usage

Related modules

Static validatedLive test pending

gcp-firewall-policy

A global network firewall policy exists independently of any network; an association puts it in the path, and a policy with a hundred rules and none governs nobody while rendering as fully configured. enable_logging defaults to false on every rule, so a deny that fires leaves no evidence. Refuses a policy with no network, logs every rule unless told not to, and counts the disabled ones.

View module
Static validatedLive test pending

gcp-service-perimeter

spec is the dry-run configuration and status is the enforced one - two blocks of the same shape, and a perimeter with only a spec is evaluated on every request, logs violations, and blocks nothing. Empty restricted_services is the other way to have none: the perimeter exists, covers the projects, and governs no API.

View module
Static validatedLive test pending

gcp-dlp

Sensitive Data Protection on a schedule: an inspection template naming the detectors and a weekly trigger over a bucket or a BigQuery table, sampling ten percent of each file, scanning only what changed since the last run, with findings written to your dataset without the matched values and a summary sent to Security Command Center. A full scan, billed per byte, is accepted by name.

View module
Static validatedLive test pending

gcp-recaptcha

A key with a testing score returns that score for every assessment, bots included - right for staging and, on a production key, a filter that filters nothing; allow_all_domains lets any site consume your assessments against your quota. Testing mode refused without acceptance, domains required on web keys, invisible scoring by default; only a backend assessment call turns a token into a decision.

View module
Static validatedLive test pending

gcp-secure-web-proxy

A gateway with no rules allows nothing, and a session matcher of true is an open proxy to the internet; the gateway needs a proxy-only subnet in the region that is yours to make; and without TLS inspection the proxy sees the SNI hostname and nothing inside. Rules built from a URL list of your hosts, allow-all accepted by name only, outputs that say what is allowed and that TLS is not inspected.

View module
Static validatedLive test pending

gcp-cloud-ids

Creating the endpoint creates no packet mirroring policy, so an endpoint with nothing mirrored is provisioned, billed by the hour, shown with a green check and has never seen a packet. The mirroring policy is created with it and refused when it mirrors nothing. Cloud IDS detects and never blocks; blocks_traffic is an output that is always false.

View module