Skip to content

feat(gcp): grant config-only perms for storage, secrets, bigquery, cloudbuild, batch, workflows, firestore, vertex, scc#48

Merged
tim-thacker-nullify merged 1 commit into
mainfrom
feat/gcp-connector-add-missing-service-permissions
May 5, 2026
Merged

feat(gcp): grant config-only perms for storage, secrets, bigquery, cloudbuild, batch, workflows, firestore, vertex, scc#48
tim-thacker-nullify merged 1 commit into
mainfrom
feat/gcp-connector-add-missing-service-permissions

Conversation

@tim-thacker-nullify
Copy link
Copy Markdown
Member

Claude

Summary

Closes the gap between what the Nullify cloud scanner (context/internal/cloudintegrations/gcp/) actually enumerates and what this connector module grants. Adds 23 permissions across 9 services to the existing nullifyCloudConnector custom role. No new predefined role bindings.

Surfaced while reviewing a customer terraform plan: 9 scanner modules were silently hitting PermissionDenied and producing empty inventory rows. The risk graph in hyperdrive/pkg/graphanalysis was incomplete by exactly this gap.

What's added

Service Permissions Method called by scanner
Cloud Storage storage.buckets.{get,list,getIamPolicy} Buckets.List + Bucket.IAM.GetPolicy
Secret Manager secretmanager.secrets.{get,list} Projects.Secrets.List
BigQuery bigquery.{datasets,tables,routines}.{get,list} Datasets.List/Get, Tables.List, Routines.List
Cloud Build cloudbuild.buildTriggers.{get,list} Projects.Triggers.List
Cloud Batch batch.jobs.{get,list} Projects.Locations.Jobs.List
Cloud Workflows workflows.workflows.{get,list} Projects.Locations.Workflows.List
Firestore datastore.databases.{list,getMetadata} Projects.Databases.List
Vertex AI aiplatform.endpoints.{get,list} Projects.Locations.Endpoints.List
Security Command Center securitycenter.sources.{get,list} Organizations.Sources.List (org-scope only)

Service-config-only contract preserved

Every entry is *.list / *.get / *.getMetadata on configuration resources. Data-plane perms are explicitly excluded:

  • storage.objects.* (no object reads)
  • secretmanager.versions.access (no secret payloads)
  • bigquery.tables.getData (no row reads)
  • bigquery.jobs.create (no query execution / billing)
  • workflows.executions.* and workflows.stepEntries.* (no execution payloads)
  • datastore.entities.* (no document reads)
  • aiplatform.endpoints.predict / computeTokens (no inference)
  • securitycenter.findings.* and securitycenter.assets.* (no finding contents)

The predefined viewer roles for Workflows (roles/workflows.viewer), Firestore (roles/datastore.viewer), Vertex AI (roles/aiplatform.viewer), and SCC findings (roles/securitycenter.findingsViewer) are deliberately not used because each one grants data-plane permissions that would violate the connector's config-only contract.

Files

  • gcp-integration-setup/terraform/modules/nullify-gcp-integration/main.tf — append entries to local.custom_role_permissions; update header comment with new exclusions.
  • gcp-integration-setup/scripts/install.sh — sync the comma-separated CUSTOM_ROLE_PERMISSIONS string.
  • gcp-integration-setup/docs/permissions.md — add 9 rows to the custom-role table; add 8 rows to the "What Nullify cannot do" table.
  • gcp-integration-setup/terraform/README.md — update the "What this provisions" service list.

What's NOT changed

  • apis.tf (we don't enable customer-side service APIs; if the customer doesn't use BigQuery/Firestore/etc, the scanner gracefully handles "API not enabled" 403s).
  • WIF / OIDC trust wiring.
  • Scope / scope-binding logic.
  • Predefined role list (no additions).

Test plan

  • terraform fmt -recursive — clean ✅ (verified locally)
  • terraform validate on each example (single-project, organization, folder) ✅ (verified locally)
  • bash -n scripts/install.sh ✅ (verified locally)
  • Permission count parity: 52 perms in main.tf custom_role_permissions matches 52 in install.sh CUSTOM_ROLE_PERMISSIONS
  • Apply against a test GCP project (single-project scope) and confirm gcloud iam roles describe nullifyCloudConnector returns the new perms.
  • Run a context cloud scan against the test project; confirm the cloudaccountgcp model now populates Buckets, Secrets, BigQueryDatasets, BuildTriggers, BatchJobs, Workflows, FirestoreDatabases, VertexEndpoints (and Sources at org scope).
  • Confirm result.Errors no longer carries 403s for those 9 services.
  • Re-run the verify endpoint (POST /admin/integrations/cloud/gcp/validate) — must remain green; verify path doesn't exercise the new perms but should not regress.

…oudbuild, batch, workflows, firestore, vertex, scc

Closes the gap between what the Nullify cloud scanner enumerates and
what the cloud connector module grants. Adds 23 permissions across 9
services to the existing nullifyCloudConnector custom role; no new
predefined role bindings.

Every permission is a *.list / *.get / *.getMetadata on configuration
resources. Data-plane perms are explicitly excluded:
  - storage.objects.*            (no object reads)
  - secretmanager.versions.access (no secret payloads)
  - bigquery.tables.getData      (no row reads)
  - bigquery.jobs.create         (no query execution / billing)
  - workflows.executions.*       (no execution payloads)
  - workflows.stepEntries.*      (no step input/output reads)
  - datastore.entities.*         (no document reads)
  - aiplatform.endpoints.predict (no inference)
  - securitycenter.findings.*    (no finding content)

The predefined viewer roles for Workflows, Firestore (datastore.viewer),
Vertex AI, and SCC findings are deliberately not used because each one
includes data-plane permissions that violate the connector's
config-only contract.

scripts/install.sh CUSTOM_ROLE_PERMISSIONS string is kept in sync.
docs/permissions.md is extended with the new permissions and the new
"What Nullify cannot do" rows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tim-thacker-nullify tim-thacker-nullify added the minor Minor version updates (features) label Apr 30, 2026
@tim-thacker-nullify tim-thacker-nullify marked this pull request as ready for review May 5, 2026 11:18
@tim-thacker-nullify tim-thacker-nullify merged commit 60be764 into main May 5, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Minor version updates (features)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants