Connect Google Cloud¶
An Engineer or Admin can configure the Google Cloud connector from the guided setup without a human handoff. No long-lived cloud credentials by default: Venturi’s workload identity reaches the project through Workload Identity Federation, and the module never creates or exports a service-account key. See Docs authority & product state.
Access boundary¶
The module creates a service account that Venturi impersonates through Workload Identity Federation, with these read roles:
roles/on the billing-export dataset only.bigquery. dataViewer roles/on the project for Vertex AI and Cloud Monitoring metrics.monitoring. viewer roles/on the project for Cloud Logging entries. It excludes Data Access audit logs, which requirelogging. viewer roles/.logging. privateLogViewer roles/on the project to inspect which APIs, such as Vertex AI, are enabled and their quota state. It cannot enable or disable any API. It also carriesserviceusage. serviceUsageConsumer serviceusage., which lets its holder consume quota and billing in the project.services. use
BigQuery access is dataset-scoped from the start: set billing_dataset_id to
the billing-export dataset and billing_, as in the
configuration below. If billing_ is false or billing_dataset_id
is empty, the module also grants roles/ on the whole
project; do not use that mode.
billing_dataset_id must name a dataset in project_id. The module connects 1
project and grants the dataset-scoped read inside that project, so it cannot
grant access to a Cloud Billing export dataset that lives in a separate billing
or FinOps project; an apply that names such a dataset fails because the dataset
is not found in project_id.
Content-bearing logs. Read access to a log source is not storage of its
content. roles/ can read Vertex AI container logs, which hold
whatever your serving containers write to standard output and standard error,
and a project-wide roles/ grant can read the BigQuery table
that Vertex AI request-response logging writes, which contains sampled prompts
and responses when you enable that logging. The module grants roles/ on the
project, where it reads the _Required bucket and the _Default view of the
_Default bucket, not user-defined log buckets. Scope what that grant reaches
by routing Vertex AI container logs to a user-defined log bucket and excluding
them from the _Default sink; Vertex AI access logs, which record timestamp
and latency for each request, stay in _Default. Keep BigQuery read scoped to
the billing-export dataset, and keep request-response logging tables out of
that dataset. For any record that still contains content, the collector applies
a field allowlist in memory, discards prompt and completion fields before a
record is materialized, and never persists, logs, retries, or exports them. The
normalized InvocationEvent schema has no field for prompt or completion text.
Steps¶
1. Generate configuration¶
Role: Engineer or Admin in Venturi; for the apply, a Google Cloud setup
principal that can create the Workload Identity Pool and provider
(roles/), create the service account and set its
IAM policy (roles/), set project IAM bindings
(roles/), and set IAM on the billing-export
dataset (for example, roles/ on that dataset). Enabling an
API needs serviceusage., for example through
roles/.
Workload Identity Federation and service-account impersonation need the IAM, Resource Manager, Service Account Credentials, and Security Token Service APIs in the project. The module does not enable APIs, so enable any that are not already on before the apply:
gcloud services enable iam.googleapis.com cloudresourcemanager.googleapis.com \
iamcredentials.googleapis.com sts.googleapis.com --project "<project_id>"
Select Google Cloud in guided setup. The tenant flow generates the exact issuer,
allowed subjects, connector ID, and pinned Terraform artifact in-product.
Download the pinned Terraform artifact and extract it: the extracted
infra/ directory holds the module, terraform.,
and scripts/verify.sh. Save the generated values below as
infra/, run every command on this page from
that directory, and keep it, with its Terraform state, for rotation and
removal.
project_id = "my-prod-project"
service_account_id = "venturi-readonly"
wif_pool_id = "venturi-pool"
wif_provider_id = "venturi-provider"
wif_issuer_uri = "<generated in guided setup>"
wif_allowed_subjects = ["<generated exact subject>"]
billing_dataset_id = "billing_export"
billing_dataset_only = true
Wildcards are rejected. Keep every subject exact.
Leave use_ out of terraform.tfvars; it defaults to true.
Setting it to false skips the pool, provider, and impersonation binding, and
the module never creates a service-account key, so the connector has no way to
authenticate.
2. Deploy and prove the boundary¶
Role: the setup principal for the apply; for the local check, a principal
that can read the project IAM policy, list the service account’s keys
(roles/), and list Workload Identity pools in the
project (for example, roles/), plus
roles/ on the service account to exercise the
write probe. Without the pool-list permission the script prints
MISS WIF pool, which fails the check.
cd infra/gcp/onboarding
export PROJECT_ID="my-prod-project"
gcloud auth login
gcloud auth application-default login
gcloud config set project "$PROJECT_ID"
terraform init
terraform plan
terraform apply
SERVICE_ACCOUNT_EMAIL="$(terraform output -raw service_account_email)" \
./scripts/verify.sh
This is the only terraform apply in the setup path; the
Deploy step later activates the connector without applying the
module again.
Terraform uses the Application Default Credentials from
gcloud auth application-default login; verify.sh calls gcloud with the
account from gcloud auth login. If a different principal runs the check,
sign in as that principal with gcloud auth login before running verify.sh.
The local script confirms the service account has no user-managed keys, prints
a role: line for each project-scope role binding, checks the Workload
Identity Pool, and attempts a write call, such as BigQuery dataset creation,
while impersonating the service account; the write must be denied. The
script’s role allowlist is broader than the module: it prints
roles/, roles/, and
roles/ as OK at project scope, so a run with no
SEC line does not by itself prove that no write-capable role is bound. Read
the role lines instead: they must be exactly role: roles/,
role: roles/, and
role: roles/, and any other role: line is
a security finding. Without roles/, the script
reports the write probe as SKIP, which does not fail the check; automated
credential validation runs the denied-write probes as Venturi’s identity. To
exercise the probe locally, grant the role for the check and remove it
afterward. Connector activation performs the positive BigQuery, Logging, and
Monitoring reads through federation. See
Verify & confirm.
3. Register outputs and validate¶
Enter the service-account email, project number, Workload Identity Pool
provider resource name
(projects/<project_number>/),
and billing dataset in the connector step. Automated credential validation
checks the issuer, exact subject, federation exchange, positive reads, and write
denial.
4. Inspect evidence¶
Open the readiness result and /invocations. Review coverage, unknown ownership
or billing dimensions, and source freshness.
Success evidence¶
terraform applysucceeds with no service-account key resource.verify.shexits0with noSECorMISSline, its project-scope role lines are exactlyrole: roles/,monitoring. viewer role: roles/, andlogging. viewer role: roles/(any otherserviceusage. serviceUsageConsumer role:line, includingroles/,bigquery. dataViewer roles/, oriam. serviceAccountTokenCreator roles/, is a security finding), a write-probeiam. workloadIdentityUser SKIPdoes not fail it, and the connector’s positive read probes pass.- Automated credential validation shows the exact issuer and subject accepted.
- The 1st Google Cloud-backed
AttributionRecordappears in/invocations.
Recovery¶
| Failure | Action |
|---|---|
unauthorized_client or subject rejection |
Compare the exact generated issuer and subject; remove wildcard or whitespace drift and reapply. |
terraform apply fails with a permission error on the pool, service account, or an IAM binding |
Grant the setup principal the matching role from step 1, then apply again. |
terraform apply or validation fails with SERVICE_DISABLED or “API has not been used in project” |
Enable the named API with gcloud services enable as shown in step 1, wait a few minutes for it to take effect, then apply or validate again. |
terraform apply fails with Not found: Dataset for the billing dataset |
billing_dataset_id names a dataset outside project_id, or a dataset that does not exist. Set it to the billing-export dataset in project_id; the module cannot grant access to a dataset in another project. |
verify.sh prints a role: line other than roles/, roles/, and roles/ |
Security finding, even when the script prints it as OK. Disable the connector, remove the extra project-scope binding, apply, and rerun verify.sh. |
verify.sh prints MISS WIF pool although the pool exists |
The identity running the script cannot list Workload Identity pools. Grant it roles/ on the project, or run the check as the setup principal, then rerun. |
verify.sh prints role: roles/ |
The project-wide BigQuery grant is present. Set billing_dataset_id and billing_, apply, and rerun verify.sh. |
| Billing query is empty | Confirm the export dataset, project, location, and dataset-scoped binding. |
| Vertex evidence is missing | Inspect Logging exclusions and confirm the expected metadata log exists. |
| Positive read is denied | Add only the named missing read role at the narrowest scope, then rerun validation. |
verify.sh reports the write probe as SKIP |
Not a failure. To exercise the write probe, grant the person running the script roles/ on the service account, rerun, then remove the grant. |
| Freshness becomes stale | Check the latest billing-export partition and readiness probe timestamp. |
Support is an optional escalation path after the validation evidence is available.
Rotate or revoke¶
wif_ is a list, so both subjects are accepted during rotation.
Review the subject at least every 12 months:
- In
Integrations / Google Cloud, generate the next exact federation subject. - Add it to
wif_, keeping the current subject, and apply.allowed_ subjects - Activate the new subject in the connector settings and rerun automated credential validation.
- Remove the previous subject, apply again, and rerun
verify.sh.
Do not use wildcards to bridge rotation.
To revoke access, disable the connector in
Integrations / Google Cloud, then run:
Confirm the service account, pool, provider, and bindings are absent and record the revocation result in the connector audit record.
Reference¶
- Verify the trust boundary
- Trust & security
- Rotate & offboard
- Google Cloud: Configure Workload Identity Federation with other identity providers
- Google Cloud: Service Usage roles and permissions
- Google Cloud: Logging access control
- Google Cloud: Route log entries
- Google Cloud: Online inference logging
- Google Cloud: Request-response logging
Sign in to send feedback. Opens in a new tab.
Copy page details
Docs feedback: Connect Google Cloud
Page: https://docs.venturi.systems/onboarding/gcp/