Skip to content

Connect to GCP

Nullstone provisions and manages infrastructure in a Google Cloud project, so it needs a service account with access to that project. A Google Cloud project is an isolated namespace for infrastructure; organizations commonly map one project to each environment (for example, dev, staging, prod).

Nullstone supports two authentication methods:

MethodHow it worksBest for
Service Account Impersonation (recommended)You create a service account and let a dedicated Nullstone service account impersonate it for short-lived tokens. No key file is downloaded or stored.Most organizations.
Service AccountYou create a service account, download a JSON key file, and upload it to Nullstone.Environments where impersonation is not an option.

Both methods use the same service account and roles — they differ only in how Nullstone authenticates. We recommend Service Account Impersonation because it avoids long-lived key files.

Use Cloud Shell

The commands below use Google Cloud Shell, which has the gcloud CLI pre-installed and pre-authenticated — no local install required. Open the Google Cloud console, select the target project in the header, and click Activate Cloud Shell (the terminal icon, top right). Confirm the active project with gcloud config get-value project.

Service Account Impersonation

In this pattern, you create a service account in your project and grant Nullstone's dedicated service account (nullstone-assumer@assumer.iam.gserviceaccount.com) permission to impersonate it. Nullstone requests short-lived tokens as needed — no credentials are downloaded or stored, and you can revoke access at any time by removing the impersonation binding.

Set the variables used throughout (replace PROJECT_ID with your project):

shell
export PROJECT_ID=...
export SERVICE_ACCOUNT_ID=nullstone
export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_ID}@${PROJECT_ID}.iam.gserviceaccount.com"

1. Create the service account

shell
gcloud iam service-accounts create "${SERVICE_ACCOUNT_ID}" \
  --project="${PROJECT_ID}" \
  --description="Nullstone Agent" \
  --display-name="nullstone"

2. Grant roles to the service account

Nullstone needs the following roles to provision infrastructure. Grant them in one pass:

shell
ROLES=(
  roles/editor
  roles/resourcemanager.projectIamAdmin
  roles/iam.serviceAccountAdmin
  roles/servicenetworking.networksAdmin
  roles/container.admin
  roles/compute.loadBalancerAdmin
  roles/artifactregistry.admin
  roles/secretmanager.admin
  roles/iam.roleAdmin
  roles/logging.admin
  roles/pubsub.admin
)

for role in "${ROLES[@]}"; do
  gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
    --role="${role}"
done

3. Enable required APIs

Enable the Service Usage and Cloud Resource Manager APIs so Nullstone can read project metadata:

shell
gcloud services enable serviceusage.googleapis.com cloudresourcemanager.googleapis.com \
  --project="${PROJECT_ID}"

4. Allow Nullstone to impersonate the service account

Grant Nullstone's assumer service account permission to mint tokens for your service account. Copy the Nullstone Assumer Service Account shown in the Add Provider dialog — it is environment-specific (in production it is nullstone-assumer@assumer.iam.gserviceaccount.com):

shell
export ASSUMER_SERVICE_ACCOUNT=nullstone-assumer@assumer.iam.gserviceaccount.com

gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_EMAIL}" \
  --member="serviceAccount:${ASSUMER_SERVICE_ACCOUNT}" \
  --role="roles/iam.serviceAccountTokenCreator" \
  --project="${PROJECT_ID}"

5. Configure Nullstone

In the Nullstone UI, go to Providers and click Add Provider. Select GCP for the provider type and choose Service Account Impersonation. Enter the Project ID and the Service Account email (nullstone@<project-id>.iam.gserviceaccount.com).

FINISH

Click Test Connection before proceeding.

Service Account

In this pattern, you create a service account, download a JSON key file, and upload it to Nullstone. Use this method only when impersonation is not an option — the key file is a long-lived credential you must store and rotate.

Set the variables used throughout (replace PROJECT_ID with your project):

shell
export PROJECT_ID=...
export SERVICE_ACCOUNT_ID=nullstone
export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_ID}@${PROJECT_ID}.iam.gserviceaccount.com"

1. Create the service account

shell
gcloud iam service-accounts create "${SERVICE_ACCOUNT_ID}" \
  --project="${PROJECT_ID}" \
  --description="Nullstone Agent" \
  --display-name="nullstone"

2. Grant roles to the service account

Nullstone needs the following roles to provision infrastructure. Grant them in one pass:

shell
ROLES=(
  roles/editor
  roles/resourcemanager.projectIamAdmin
  roles/iam.serviceAccountAdmin
  roles/servicenetworking.networksAdmin
  roles/container.admin
  roles/compute.loadBalancerAdmin
  roles/artifactregistry.admin
  roles/secretmanager.admin
  roles/iam.roleAdmin
  roles/logging.admin
  roles/pubsub.admin
)

for role in "${ROLES[@]}"; do
  gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
    --role="${role}"
done

3. Enable required APIs

Enable the Service Usage and Cloud Resource Manager APIs so Nullstone can read project metadata:

shell
gcloud services enable serviceusage.googleapis.com cloudresourcemanager.googleapis.com \
  --project="${PROJECT_ID}"

4. Create a service account key

Generate a JSON key file that Nullstone will use to authenticate:

shell
gcloud iam service-accounts keys create "nullstone.json" \
  --iam-account="${SERVICE_ACCOUNT_EMAIL}"

5. Configure Nullstone

In the Nullstone UI, go to Providers and click Add Provider. Select GCP for the provider type and choose Service Account. Enter the Project ID and upload the nullstone.json key file created in the previous step.

FINISH

Click Test Connection before proceeding.

WARNING

The key file is a long-lived credential. Store it securely, rotate it periodically, and delete the service account to revoke Nullstone's access.

Cost Provider

Nullstone reports GCP spend by querying a BigQuery billing export — Google Cloud has no Cost-Explorer-style query API, so the billing export is the source of truth.

How it works

  1. GCP writes your cost data to BigQuery. You enable billing export for your Cloud Billing account into a dataset in a project you choose. A single export includes spend for every project that bills to that account, so it is commonly sent to a standalone billing project separate from your infrastructure projects.
  2. You connect that billing project to Nullstone as a provider and grant the connected service account read access to the BigQuery cost tables.
  3. Nullstone impersonates that service account — the same mechanism used for infrastructure access — to run the BigQuery queries and read your costs.

Prerequisites

You need the Billing Account Costs Manager or Administrator role to enable the export. The commands below use Cloud Shell (gcloud and bq are pre-installed and authenticated); select the billing project in the console header first.

Set the variables used throughout — BILLING_PROJECT_ID is the project you connect as your GCP provider and that receives the export:

shell
export BILLING_PROJECT_ID=...                                # connected as your GCP provider; receives the export
export DATASET=billing_export
export LOCATION=US                                           # US or EU multi-region (see note)
export SERVICE_ACCOUNT_EMAIL="nullstone@${BILLING_PROJECT_ID}.iam.gserviceaccount.com"

Use a multi-region location

Create the dataset in the US or EU multi-region. GCP only backfills the detailed usage export (up to the previous month) for multi-region datasets; a single-region dataset starts empty and only accrues data going forward.

1. Enable the BigQuery API and create the export dataset

shell
gcloud services enable bigquery.googleapis.com --project="${BILLING_PROJECT_ID}"

bq --project_id="${BILLING_PROJECT_ID}" --location="${LOCATION}" mk --dataset \
  "${BILLING_PROJECT_ID}:${DATASET}"

2. Enable Detailed usage cost export (console)

There is no API, gcloud, or Terraform for this step — do it in the console:

  1. Go to Billing → Billing export → BigQuery export.
  2. Under Detailed usage cost, click Edit settings.
  3. Set Project to ${BILLING_PROJECT_ID} and Dataset to ${DATASET}, then Save.

Enable Detailed usage cost (not Standard) — the detailed export includes the resource labels Nullstone uses for stack/environment/block attribution. GCP creates a table named gcp_billing_export_resource_v1_<BILLING_ACCOUNT_ID>; it can take a few hours to first appear.

3. Connect the billing project and grant BigQuery access

Connect the billing project to Nullstone as a provider using Service Account Impersonation. That flow creates the nullstone@${BILLING_PROJECT_ID} service account and lets Nullstone impersonate it. Then grant that same service account access to the billing export:

shell
# Run BigQuery query jobs in the billing project
gcloud projects add-iam-policy-binding "${BILLING_PROJECT_ID}" \
  --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
  --role="roles/bigquery.jobUser"

# Read the billing export (this role includes bigquery.tables.list, used to find the export table)
gcloud projects add-iam-policy-binding "${BILLING_PROJECT_ID}" \
  --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
  --role="roles/bigquery.dataViewer"

To discover the export table, Nullstone lists the tables in the dataset, which requires bigquery.tables.list — in addition to bigquery.tables.getData / bigquery.tables.get to read the table and bigquery.jobs.create to run queries. roles/bigquery.dataViewer and roles/bigquery.jobUser together provide all of these.

Do not add an IAM condition to the dataViewer grant

A resource.name-based IAM condition does not apply to bigquery.tables.list, so a conditioned grant fails with Permission bigquery.tables.list denied on dataset .... Grant roles/bigquery.dataViewer without a condition — on the project, or on the dataset via a BigQuery dataset ACL.

4. Add the cost provider in Nullstone

  1. Go to Cloud Accounts, open the Cost tab, and click Add Cost Provider.
  2. Select the billing project.
  3. Enter the Billing Export Dataset (${DATASET}) — the export table is optional, Nullstone discovers it automatically.
  4. Click Test. Nullstone locates the export table, confirms it can read it, and enumerates the projects present in the export — each is listed as an included account, so one export covers spend for every project on the billing account.

History starts near-zero

The detailed export backfills at most the previous month, so early history is sparse. The open invoice month stays mutable — GCP revises rows until the invoice finalizes — so recent figures may shift slightly.

If the test reports that no export table was found, wait a few hours and retry. If it reports a permission error, confirm the service account can be impersonated and has roles/bigquery.jobUser and an unconditioned roles/bigquery.dataViewer.