> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorcost.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect GCP infrastructure cost

> Connect a GCP project via a service account key or Workload Identity Federation, pointed at your BigQuery billing export.

# Connect GCP infrastructure cost

This connects a GCP project for infrastructure spend, read from your **BigQuery billing export** — GCP has no other API surface for project-level spend, so this export is required either way.

You choose between two ways for TensorCost to authenticate:

| Mode                                   | What it needs                                                                    | When to use it                                                                                                                                                       |
| -------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Service account key**                | A JSON key you generate and paste in                                             | Simplest, but many GCP organizations block service-account key creation by policy                                                                                    |
| **Workload Identity Federation (WIF)** | Three resource names from a Terraform module we provide — no key material at all | Required if your organization enforces Google's `iam.disableServiceAccountKeyCreation` policy (Secure by Default, common on GCP organizations created 2024 or later) |

If you try the service account key path and key creation fails with an organization-policy error, switch to WIF — it doesn't need the permission that policy blocks.

## Prerequisites

* **Billing export enabled.** In the GCP Console, go to **Billing → Billing export → BigQuery export** and turn on **Detailed usage cost**. Note the project ID and dataset ID it writes to — you'll need both regardless of auth mode.
* For the WIF path: Terraform ≥ 1.5 and the [Google provider](https://registry.terraform.io/providers/hashicorp/google), and permission to create IAM bindings, a Workload Identity Pool, and a service account in the billing project.
* For the service account key path: permission to create a service account and IAM bindings in the billing project (`roles/owner`, or the narrower IAM-admin + BigQuery-admin roles).

## Path A — Service account key

<Steps>
  <Step title="Create a service account">
    In the GCP project that holds your billing export:

    ```bash theme={null}
    gcloud iam service-accounts create tensorcost-billing-reader \
      --display-name="TensorCost billing reader" \
      --project=<billing-project-id>
    ```
  </Step>

  <Step title="Grant it read access to the export">
    ```bash theme={null}
    gcloud projects add-iam-policy-binding <billing-project-id> \
      --member="serviceAccount:tensorcost-billing-reader@<billing-project-id>.iam.gserviceaccount.com" \
      --role="roles/bigquery.jobUser"

    bq add-iam-policy-binding \
      --member="serviceAccount:tensorcost-billing-reader@<billing-project-id>.iam.gserviceaccount.com" \
      --role="roles/bigquery.dataViewer" \
      <billing-project-id>:<dataset-id>
    ```

    `bigquery.jobUser` lets it run the read query; `bigquery.dataViewer` on the dataset lets it read the export rows. Nothing broader.
  </Step>

  <Step title="Create and download a key">
    ```bash theme={null}
    gcloud iam service-accounts keys create tensorcost-key.json \
      --iam-account=tensorcost-billing-reader@<billing-project-id>.iam.gserviceaccount.com
    ```

    <Warning>
      This file contains a long-lived private key. Treat it like a password — paste it into the TensorCost connect form and then delete the local copy; don't commit it anywhere.
    </Warning>

    If this command fails with an organization-policy error, your org blocks service-account key creation — skip to Path B (WIF) below instead.
  </Step>

  <Step title="Connect in TensorCost">
    **Build → Connect**, Cloud tab → **Google Cloud Platform** → **Connect →**, leave the auth mode on **Service account key**, and fill in:

    | Field                           | Value                                                                       |
    | ------------------------------- | --------------------------------------------------------------------------- |
    | Project ID                      | Your billing project ID                                                     |
    | Service account JSON key        | Paste the full contents of `tensorcost-key.json`                            |
    | BigQuery billing export dataset | The dataset ID from the prerequisites step                                  |
    | Billing export table (optional) | Only if you renamed or partitioned the export table — otherwise leave blank |

    Click **Verify**, then **Connect**.
  </Step>
</Steps>

## Path B — Workload Identity Federation (no key)

WIF exchanges a short-lived token for GCP access instead of a downloadable key — nothing to leak, rotate, or accidentally commit.

<Steps>
  <Step title="Run the onboarding Terraform module">
    We provide a Terraform module for this — ask your TensorCost contact for the source if you don't already have it. Apply it in WIF mode:

    ```hcl theme={null}
    module "tensorcost_onboarding" {
      source = "<path we provide>"

      billing_project_id        = "<billing-project-id>"
      billing_dataset_id        = "<dataset-id>"
      tensorcost_sa_email       = "<shown in the TensorCost connect form>"
      tensorcost_auth_mode      = "wif"
      tensorcost_oidc_issuer_uri = "https://tensorcost.com"
      tensorcost_oidc_audience   = "<shown in the TensorCost connect form>"
    }
    ```

    ```bash theme={null}
    terraform init && terraform apply
    ```

    This creates a Workload Identity Pool and provider trusting TensorCost's OIDC issuer, a service account scoped to this project, and grants that service account `roles/bigquery.dataViewer` on your export dataset and `roles/bigquery.jobUser` on the project. No key material is created at any point.
  </Step>

  <Step title="Connect in TensorCost">
    **Build → Connect**, Cloud tab → **Google Cloud Platform** → **Connect →**, switch the auth mode to **Workload Identity Federation**, and fill in:

    | Field                           | Terraform output                                                            |
    | ------------------------------- | --------------------------------------------------------------------------- |
    | Project ID                      | `billing_project_id`                                                        |
    | Workload Identity Pool          | `workload_identity_pool_id`                                                 |
    | Workload Identity Provider      | `workload_identity_provider_id` (the full resource path — paste it exactly) |
    | Service account email           | `tensorcost_service_account_email`                                          |
    | BigQuery billing export dataset | `billing_dataset_id`                                                        |

    Click **Verify**, then **Connect**.
  </Step>
</Steps>

## What Verify actually checks

Both modes mint a real token — a JWT signed with your key in Path A, or a full Workload Identity Federation token exchange plus service-account impersonation in Path B — and, once you've filled in the BigQuery dataset field, confirm it can actually read that dataset. An identity that mints fine but is explicitly denied dataset access fails Verify; a token that can't be confirmed due to a network hiccup on TensorCost's side degrades to a pass with a warning, rather than blocking you for something that isn't your misconfiguration.

## Common failures

| What you see                                         | Cause                                                                                                      | Fix                                                                                                                      |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| Service account JSON key rejected as invalid         | Pasted an incomplete file, or one missing `client_email` / `private_key`                                   | Re-download the key with `gcloud iam service-accounts keys create` and paste the full file contents                      |
| Billing export access denied                         | The service account (or, in WIF mode, the impersonated account) lacks `bigquery.dataViewer` on the dataset | Re-check the IAM binding matches the exact dataset ID you entered                                                        |
| Billing export dataset not found                     | Dataset ID typo, or the export lives in a different project than the one you entered as Project ID         | Confirm both values against the GCP Console's Billing export page                                                        |
| Zero rows after connecting                           | The billing export table is empty                                                                          | GCP can take 24–48 hours to backfill after you first enable Detailed usage cost export — this isn't a connection problem |
| Key creation fails with an organization-policy error | Your GCP organization enforces `iam.disableServiceAccountKeyCreation`                                      | Use Path B (WIF) instead — it needs no key                                                                               |
