Skip to content

Onboarding: Google Cloud

This guide wires your GCP project into Argmin. 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 Argmin

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 Argmin will provide

Email contact@argmin.co and ask for:

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

You will provide back to Argmin:

  • 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    = "argmin-readonly"   # 6-30 chars, lowercase + hyphens
use_workload_identity = true

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

# The OIDC subjects Argmin will sign with. The module rejects wildcards —
# list each explicitly. Ask Argmin for the exact strings.
wif_allowed_subjects = [
  "<from Argmin, e.g. system:serviceaccount:argmin: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 Argmin

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/argmin-pool
wif_provider:           projects/<project_number>/locations/global/workloadIdentityPools/argmin-pool/providers/argmin-provider
billing_dataset:        <dataset_id, if scoped>
notes:                  <anything Argmin should know about your project layout>

Argmin 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 Argmin for the new subject string.
  2. Add it to the list (don't replace yet) and terraform apply.
  3. Confirm Argmin 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 Argmin first so ingestion can pause cleanly.

Troubleshooting

Symptom Most likely cause
"unauthorized_client" / "subject not allowed" wif_allowed_subjects is missing the exact subject Argmin 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 Argmin 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