Skip to main content
CostGraph reads your Google Cloud spend from a FOCUS billing export in BigQuery. You enable the export on your billing account, grant a read-only service account access to the exported data, and CostGraph ingests it into normalized, reconciled cost. Google does not offer an API to turn the billing export on, so one step is a manual click in the Cloud Console. Everything else is read-only and least-privilege.

What you enable

Google Cloud savings recommendations are on by default. You can turn them off by clearing Show Google Cloud savings recommendations in the connect dialog. See Savings recommendations.

Step 1: Enable the exports (Console)

Enabling a billing export is Console-only: Google provides no API, gcloud command, or Terraform resource for the toggle itself. This is the one manual step.
  1. In the Cloud Console, open Billing and select the billing account you want to connect.
  2. Go to Billing export > BigQuery export.
  3. Under FOCUS export, click Edit settings, choose the project that will hold the export, choose a data location, and Save. Google creates its own immutable dataset named gcp_billing_immutable_<BILLING_ACCOUNT_ID>_<region>; you do not pick the dataset.
  4. Under Detailed usage cost, click Edit settings, choose a project and dataset (or let it create gcp_billing_export_resource_v1_<region>), and Save.
The export project must have billing enabled and be linked to the billing account you are exporting. Any supported data location works, but the US or EU multi-regions are recommended: they backfill the current and previous month, which can take up to five days to complete. Regional locations do not backfill any prior data, so history only starts from the day you enable the export. First new rows appear within a few hours either way.

Step 2: Grant CostGraph read access

The connect dialog shows a one-line command. Open Cloud Shell in the project holding the export datasets and run it:
Cloud Shell already carries your console credentials, so no key is created or pasted anywhere. The script creates the reader service account, finds the FOCUS and detailed datasets for your billing account, applies the grants below, and authorizes CostGraph’s federated principal to impersonate it. It is idempotent, so rerun it safely. If the FOCUS export does not exist yet it stops and points you back at Step 1. With recommendations on, the script also:
  • lets the reader see the savings recommendations for your billing account and for projects that are not in an organization
  • sets up a daily recommendations export for your organization, run by a service account in your project (costgraph-recs-export) that CostGraph cannot act as
Setting up the export needs an organization admin once. If you are not one, the script prints the one command an organization admin runs, then you re-run the setup. Add COSTGRAPH_ENABLE_RECOMMENDATIONS=0 to the command to skip recommendations. The script also grants network access. Clear Show how your resources connect in the connect dialog, or add COSTGRAPH_ENABLE_NETWORK_INVENTORY=0 to the command, to leave it out. It prints the values to paste into the connect form:
Set COSTGRAPH_PROJECT_ID when the export lives outside your active Cloud Shell project, or COSTGRAPH_SA_NAME to reuse an existing service account.

What it grants

Doing it by hand instead? These are the exact, least-privilege grants: The costgraphNetworkReader role holds only these permissions:
  • compute.instances.list
  • compute.forwardingRules.list
  • compute.routers.list
  • compute.subnetworks.list
  • compute.backendServices.list
  • compute.networkEndpointGroups.get
  • compute.instanceGroups.get
  • file.instances.list
  • container.clusters.list
The costgraphQuotaReader role holds only these permissions:
  • compute.regions.list, compute.regions.get, compute.zones.list
  • compute.projects.get
  • compute.machineTypes.list, compute.acceleratorTypes.list
  • serviceusage.services.list, serviceusage.services.get
  • cloudquotas.quotas.get
The script also turns on the Cloud Quotas API in the export project. The recommendations export is a BigQuery Data Transfer from the Recommender data source into costgraph_recommendations, run as costgraph-recs-export, which holds roles/recommender.exporter on the organization and roles/bigquery.dataOwner on that dataset only. Dataset-level dataViewer (rather than project-level) keeps access scoped to the billing data only.
Keyless is recommended. Rather than exporting a service-account key, grant CostGraph’s identity permission to impersonate this service account: grant roles/iam.workloadIdentityUser on the service account to CostGraph’s federated principal (Workload Identity Federation). Use roles/iam.serviceAccountTokenCreator only when the caller is a Google identity. It is broader than external federation needs. No secret leaves your project and there is no key to rotate. The connect screen provides CostGraph’s identity to authorize. A downloaded service-account key is supported as a fallback.
CostGraph does not use OAuth “sign in with Google” for billing access, because that ties access to one person’s account and grants broad scopes. Impersonation (or a scoped service-account key) is the correct trust model.

Step 3: Connect in CostGraph

  1. Open Integrations and choose Google Cloud.
  2. Paste the values the Cloud Shell script printed. To set it up by hand instead, choose impersonation (recommended: authorize CostGraph’s identity on your service account) or paste a service-account key, then enter the billing account ID.
  3. CostGraph validates it can run a query and read the FOCUS dataset, then starts the first sync. If a role is missing, the connect screen names the exact grant to add.

What CostGraph does with it

  • Cost: FOCUS line items normalized to a canonical model, keeping both billed and effective (amortized) cost, credits, and commitment attribution.
  • Reconciliation: allocated plus unallocated cost is checked to equal the invoice per billing account per month; FOCUS is validated against the Detailed export.
  • Allocation: spend attributed by resource, label, and project, with an explicit unallocated bucket for tax, shared, and commitment costs.

Network access

Network access is the quickest way to fill in Context when only your bill is connected. With it, CostGraph reads your Google Cloud inventory and connects what you run. Context shows each network and subnet with its VMs and GKE clusters, and the disks, Filestore instances, Cloud NAT, and load balancers they use. When network flow tracing also runs, Context names the private traffic between them. Network access is read-only and on by default. The script creates the costgraphNetworkReader role on your organization and grants it to the reader service account. If you can’t grant on the organization, it grants the role on each project billed to your billing account instead. When those projects are in an organization, it also prints the commands an organization admin runs to cover every project. To also see workloads, usage, and live traffic, install the CostGraph Agent or the CostGraph Operator.

Turn it on for an existing connection

Select Grant network access in Context to open the connect dialog with the command, or rerun the Cloud Shell command with COSTGRAPH_ENABLE_NETWORK_INVENTORY=1:
It prints a NETWORK_INVENTORY_STATUS line with one of enabled, partial, or not_enrolled. Set the variable to 0 to remove the grants, and the line reads disabled. Without the variable, the script grants it. You don’t need to reconnect. CostGraph picks up the new access within the hour.

Quotas and regions

Ask CostGraph about your Google Cloud quotas in chat, from an MCP client, or in a workflow, for example “which regions are close to their CPU quota”. CostGraph reads your quotas, regions, zones and enabled APIs live when you ask, using the costgraphQuotaReader role. It reads the export project unless you name another project.

Existing connections: re-run the setup command

Re-run the Cloud Shell command from Step 2. You don’t need to reconnect. If you ask about quotas before you re-run it, CostGraph tells you the connection does not have access yet.

Savings recommendations

With recommendations on, Google Cloud’s own savings recommendations appear in Insights next to CostGraph’s. Each one shows two numbers: “Google says X/mo,CostGraphpricesitatX/mo, CostGraph prices it at Y/mo”. Google’s figure is at list price; CostGraph’s comes from your bill, after your discounts.
  • Idle virtual machines, disks, IP addresses and Cloud SQL instances show what they cost you today, as the saving.
  • Machine type changes are priced from your bill and CostGraph’s catalog.
  • Committed use discount recommendations, and recommendations CostGraph can’t price yet, show the monthly spend they affect, not a saving, with Google’s estimate next to it. They don’t add to the savings total.
  • When CostGraph already flags the same virtual machine, you see one item that says whether Google agrees.
The connection card in Settings > Integrations tells you what to do if access or the organization setup is missing.

Turn them on for an existing connection

Re-run the Cloud Shell command. If you cleared Show Google Cloud savings recommendations when you connected, also connect the billing account again with the box checked. First results appear about two days after the setup, once Google delivers the first export.

Automating the setup

The Cloud Shell script in Step 2 covers this for a single billing account. Across many projects, provision it as code instead:
  • google_bigquery_dataset for the Detailed destination
  • google_bigquery_dataset_iam_member / google_project_iam_member for the grants
  • google_project_service to enable the BigQuery API and cloudquotas.googleapis.com
  • google_organization_iam_custom_role (or google_project_iam_custom_role) with the costgraphQuotaReader permissions above, and google_organization_iam_member to grant it
The FOCUS export toggle remains a one-time manual Console step per billing account.