Skip to content

Onboarding: Google Cloud

This guide wires your GCP project into Venturi. Workload Identity Federation is the default; no service account keys are ever generated.

Time required

~15 minutes, plus a single terraform apply.

What this grants Venturi

A GCP service account authorized via Workload Identity Federation with four project-scoped read-only roles:

  • roles/bigquery.dataViewer — read the BigQuery billing-export dataset.
  • roles/monitoring.viewer — Vertex AI monitoring metrics, Cloud Monitoring time series.
  • roles/logging.viewer — Cloud Logging entries (Vertex AI prediction-log inventory).
  • roles/serviceusage.serviceUsageConsumer — list which services your project consumes (no API enablement).

Least-privilege option

If you set billing_dataset_id, the module additionally pins BigQuery access to that exact dataset — so you can drop the project-level dataViewer later.

The service account has zero write access and no exported keys. The platform's check_permissions.py enforces this; the bindings are verifiable in infra/gcp/onboarding/main.tf.

Step 1 — Get the values Venturi will provide

Email [email protected] and ask for:

  • wif_issuer_uri — Venturi's OIDC issuer URL.
  • wif_allowed_subjects — the exact OIDC subject(s) Venturi federates from. Wildcards are rejected by the module.

You will provide back to Venturi:

  • The service_account_email output.
  • The numeric project number and a friendly project name.
  • (Optional) the billing-export dataset ID if you scope down per Step 2.

Step 2 — Configure your terraform.tfvars

Create terraform.tfvars in infra/gcp/onboarding/:

project_id            = "my-prod-project"
service_account_id    = "venturi-readonly"   # 6-30 chars, lowercase + hyphens
use_workload_identity = true

wif_pool_id           = "venturi-pool"        # any unique id within your project
wif_provider_id       = "venturi-provider"
wif_issuer_uri        = "https://<from Venturi>"

# The OIDC subjects Venturi will sign with. The module rejects wildcards —
# list each explicitly. Ask Venturi for the exact strings.
wif_allowed_subjects = [
  "<from Venturi, e.g. system:serviceaccount:venturi:argmin-processor>",
]

# Optional: scope BigQuery viewer to a single dataset instead of project-wide.
# Leave empty to grant project-level dataViewer.
billing_dataset_id = ""

A complete terraform.tfvars.example ships in the module directory.

Step 3 — Apply

cd infra/gcp/onboarding
gcloud auth application-default login
gcloud config set project <project_id>
terraform init
terraform plan
terraform apply

Outputs:

  • service_account_email — copy into your onboarding email.
  • auth_methodworkload_identity_federation (never service_account_key — the module refuses to create keys).
  • granted_roles — human-readable list of what was granted.

Step 4 — Verify

cd infra/gcp/onboarding
./scripts/verify.sh

The verify script:

  1. Confirms the service account exists and has no user-managed keys (gcloud iam service-accounts keys list returns only system-managed keys).
  2. Lists IAM bindings at project scope and asserts each is in the read-only allowlist.
  3. Attempts a write API (e.g. bigquery.datasets.create) impersonating the SA via WIF and asserts 403 Permission denied.

Step 5 — Hand the values to Venturi

Reply to your onboarding email with:

service_account_email:  <terraform output>
project_id:             <project>
project_number:         <numeric project number>
wif_pool:               projects/<project_number>/locations/global/workloadIdentityPools/venturi-pool
wif_provider:           projects/<project_number>/locations/global/workloadIdentityPools/venturi-pool/providers/venturi-provider
billing_dataset:        <dataset_id, if scoped>
notes:                  <anything Venturi should know about your project layout>

Venturi responds within 1 business day confirming federation succeeded and ingestion has started.

Rotating the federation subjects

wif_allowed_subjects is a list — rotate without downtime:

  1. Ask Venturi for the new subject string.
  2. Add it to the list (don't replace yet) and terraform apply.
  3. Confirm Venturi is now using the new subject.
  4. Remove the old subject and terraform apply again.

Removing access

cd infra/gcp/onboarding
terraform destroy

Deletes the service account, the WIF pool/provider, and all IAM bindings. Notify Venturi first so ingestion can pause cleanly.

Troubleshooting

Symptom Most likely cause
"unauthorized_client" / "subject not allowed" wif_allowed_subjects is missing the exact subject Venturi signs with. Exact-string, no wildcards.
BigQuery query returns empty billing_dataset_id is set but the dataset doesn't exist or isn't the billing export. Check bq ls.
Vertex AI logs missing Cloud Logging exclusion filters are dropping Vertex AI rows before the sink Venturi reads.
terraform apply fails creating the WIF pool Caller lacks roles/iam.workloadIdentityPoolAdmin. Have an admin grant it, or apply from a CI runner that already has it.

Reference