Customer setup guide

Connect one Google Cloud root.

Create or reuse a dedicated customer-owned service account, grant four predefined roles, and let the Sythe Labs platform read one complete Cloud Asset Inventory boundary and Artifact Registry container vulnerability findings.

Overview

Bounded Google SDK operations.

The connector authenticates the uploaded service-account JSON in memory, then uses the Google APIs Node.js Client to call Cloud Asset Inventory v1 assets.list, Artifact Registry Docker image list, and Container Analysis occurrence list. It requests only fixed CAI asset types plus VULNERABILITY and DISCOVERY occurrences, then follows pagination until Google returns an empty next-page token.

Google SDK authentication

Client library
googleapis
Token operation
service-account-token-exchange
Authorization scope
https://www.googleapis.com/auth/cloud-platform
CAI read pathRead only
01
RESOURCE snapshot

Cloud Asset Inventory v1 assets.list for the fixed supported asset types.

cloudasset.googleapis.comcloudasset.assets.listResource
02
IAM_POLICY snapshot

Cloud Asset Inventory v1 assets.list for the fixed supported asset types.

cloudasset.googleapis.comcloudasset.assets.listIamPolicy
Registry vulnerability read pathRead only
01
Docker image snapshot

projects.locations.repositories.dockerImages.list for in-scope Registry projects.

artifactregistry.googleapis.comartifactregistry.dockerimages.list
02
Vulnerability and discovery occurrence snapshot

projects.occurrences.list for in-scope Registry projects.

containeranalysis.googleapis.comcontaineranalysis.occurrences.list
Before you start

Keep the account, key, and console under customer control.

The customer creates and controls the service account. Do not send its JSON key to Sythe Labs staff, paste it into a support request, or ask staff to enter the Google Cloud console.

  • 01

    One authoritative organization, folder, or project root for the inventory boundary.

  • 02

    A customer-owned project where the dedicated service account and Cloud Asset Inventory API will live.

  • 03

    Every project under that root with an in-scope Artifact Registry Docker repository.

  • 04

    Permission to create or reuse a service account, enable the required APIs, grant four predefined roles, and create a JSON key only for a new connection.

  • 05

    Organization administrator access to the signed-in Sythe Labs platform Integrations page.

Create the connection

Grant four predefined roles, then upload a JSON key only for a new connection.

Copy the prompt below into a CLI coding agent. It asks for the root, service-account project, Registry projects, and whether this is a new connection or an upgrade. For an upgrade, it reuses the existing service account and encrypted key: grant the new access, then run Sync without disconnecting or reconnecting.

Set up or upgrade a read-only Google Cloud service account so the Sythe Labs platform can read Cloud Asset Inventory and Artifact Registry container vulnerability findings for exactly one resource root.

Context:
- I am already signed in to the gcloud CLI with an account that can administer IAM at the root below and enable APIs in each registry project.
- Use the gcloud CLI and ordinary POSIX shell syntax only. Do not open the Google Cloud console and do not install anything.

Ask me for these five values first, then echo them back before running anything:
1. ROOT_KIND - organization, folder, or project. This is the highest resource whose descendants Sythe Labs should read.
2. ROOT_ID - the numeric id for an organization or folder, or the project id for a project.
3. SA_PROJECT - the project id that owns the service account and the Cloud Asset Inventory API. It may be the same project as ROOT_ID.
4. REGISTRY_PROJECT_IDS - every project under the root that hosts an in-scope Artifact Registry Docker repository. APIs are enabled in these projects.
5. CONNECTION_MODE - new_connection or upgrade_existing_connection. For an upgrade, also ask for the exact existing service-account email shown on the Sythe Labs Google Cloud integration and use it unchanged. Do not create a key or reconnect during an upgrade.

After I confirm the values, assign them to quoted shell variables. Set REGISTRY_PROJECT_IDS as a shell array with one quoted project id per item. For new_connection, set SA_EMAIL to sythe-labs-asset-reader@$SA_PROJECT.iam.gserviceaccount.com and KEY_FILE to an unused absolute local path. For upgrade_existing_connection, set SA_EMAIL to the exact existing service-account email I provided.

Run these steps in order. Stop at the first failure and show me the exact gcloud error.

Step 1 - enable the required APIs. Enable Cloud Asset Inventory in the service-account project. Enable Artifact Registry and Container Scanning in every registry project. Container Scanning enables Container Analysis for vulnerability metadata.
gcloud services enable cloudasset.googleapis.com --project="$SA_PROJECT"

for REGISTRY_PROJECT_ID in "${REGISTRY_PROJECT_IDS[@]}"; do
  gcloud services enable artifactregistry.googleapis.com containerscanning.googleapis.com --project="$REGISTRY_PROJECT_ID"
done

Step 2 - get or create exactly one dedicated service account. Run this describe command first. For upgrade_existing_connection, it must succeed and you reuse that exact account. For new_connection, if it succeeds, reuse the account. Only if it reports NOT_FOUND, run the create command below. If it reports any other error, stop. Never create a second service account.
gcloud iam service-accounts describe "$SA_EMAIL" --project="$SA_PROJECT"

Only after a new_connection describe reports NOT_FOUND, run:
gcloud iam service-accounts create sythe-labs-asset-reader \
  --project="$SA_PROJECT" \
  --display-name="Sythe Labs Cloud and Artifact Registry reader"

For new_connection, the created account email is sythe-labs-asset-reader@$SA_PROJECT.iam.gserviceaccount.com.

Step 3 - grant roles/serviceusage.serviceUsageConsumer on the service-account project:
gcloud projects add-iam-policy-binding "$SA_PROJECT" \
  --member="serviceAccount:$SA_EMAIL" \
  --role="roles/serviceusage.serviceUsageConsumer" \
  --condition=None

Step 4 - grant these three roles at the root so they inherit to every child resource:
- roles/cloudasset.viewer
- roles/artifactregistry.reader
- roles/containeranalysis.occurrences.viewer

ROOT_ROLES=(
  "roles/cloudasset.viewer"
  "roles/artifactregistry.reader"
  "roles/containeranalysis.occurrences.viewer"
)

for ROOT_ROLE in "${ROOT_ROLES[@]}"; do
  case "$ROOT_KIND" in
    organization)
      gcloud organizations add-iam-policy-binding "$ROOT_ID" \
        --member="serviceAccount:$SA_EMAIL" \
        --role="$ROOT_ROLE" \
        --condition=None
      ;;
    folder)
      gcloud resource-manager folders add-iam-policy-binding "$ROOT_ID" \
        --member="serviceAccount:$SA_EMAIL" \
        --role="$ROOT_ROLE" \
        --condition=None
      ;;
    project)
      gcloud projects add-iam-policy-binding "$ROOT_ID" \
        --member="serviceAccount:$SA_EMAIL" \
        --role="$ROOT_ROLE" \
        --condition=None
      ;;
    *)
      echo "ROOT_KIND must be organization, folder, or project" >&2
      exit 1
      ;;
  esac
done

Step 5 - create one JSON key only for new_connection. Choose an unused local path, stop if it already exists, and never overwrite a key file. For upgrade_existing_connection, skip this step entirely and keep the JSON key already stored by Sythe Labs.
if [ "$CONNECTION_MODE" = "new_connection" ]; then
  if [ -e "$KEY_FILE" ]; then
    echo "KEY_FILE already exists: $KEY_FILE" >&2
    exit 1
  fi

  gcloud iam service-accounts keys create "$KEY_FILE" \
    --iam-account="$SA_EMAIL" \
    --project="$SA_PROJECT"
fi

If Step 5 fails because of the constraints/iam.disableServiceAccountKeyCreation organization policy, stop and tell me. A new connection requires a user-managed JSON key and has no OAuth or Workload Identity Federation fallback. An upgrade continues to use the key already stored by Sythe Labs.

Rules:
- Grant exactly the four roles above. Do not grant Owner, Editor, Viewer, or any other role, do not enable another API, and do not create or change any other resource.
- Never print the contents of the key file and never send it anywhere. Leave it on my machine.
- Do not disconnect, replace the key, or upload a key during upgrade_existing_connection. After IAM propagation, the existing integration can use the new Registry access on its next sync.

For new_connection, when every step succeeds, print exactly these four lines:
ROOT_TYPE=<organization, folder, or project>
CANONICAL_ROOT=<organizations/ID, folders/ID, or projects/PROJECT_ID>
SERVICE_ACCOUNT=<service-account email>
KEY_FILE=<absolute path to the JSON key file>

I select ROOT_TYPE as the root type, paste CANONICAL_ROOT into the canonical resource name field, and upload KEY_FILE on the Sythe Labs Google Cloud integration page.

For upgrade_existing_connection, when every step succeeds, print exactly these four lines:
ROOT_TYPE=<organization, folder, or project>
CANONICAL_ROOT=<organizations/ID, folders/ID, or projects/PROJECT_ID>
SERVICE_ACCOUNT=<service-account email>
NEXT_ACTION=Run Sync from the existing Sythe Labs Google Cloud integration without reconnecting or uploading a key.

Container Scanning starts on new image pushes. Existing images need a new push before Google creates vulnerability results for them.
  1. 01

    Choose the authoritative organization, folder, or project root and copy its canonical resource name.

  2. 02

    Choose or confirm the customer-owned project that owns the dedicated service account.

  3. 03

    Enable the Cloud Asset Inventory API in the service-account project.

  4. 04

    Enable Artifact Registry and Container Scanning in every project with an in-scope Docker repository.

  5. 05

    Create or reuse the dedicated service account for the Sythe Labs platform connection.

  6. 06

    Grant Service Usage Consumer to that service account in the project that owns it.

  7. 07

    Grant Cloud Asset Viewer, Artifact Registry Reader, and Container Analysis Occurrences Viewer at the selected root with inherited coverage for every intended child resource.

  8. 08

    Create and download one JSON key only for a new connection if organization policy permits user-managed keys.

  9. 09

    For a new connection, open the signed-in Integrations page, enter the canonical root, and select the JSON key file.

  10. 10

    For an existing connection, keep the stored JSON key, wait for IAM propagation, and run Sync. Do not disconnect or reconnect.

Service Usage Consumer

roles/serviceusage.serviceUsageConsumer

Permit the service account to consume the enabled Cloud Asset Inventory API.

Binding location: Service-account project

Permissions
  • serviceusage.services.use

Cloud Asset Viewer

roles/cloudasset.viewer

List RESOURCE and IAM_POLICY assets throughout the selected root boundary.

Binding location: Selected organization, folder, or project root

Permissions
  • cloudasset.assets.listResource
  • cloudasset.assets.listIamPolicy

Artifact Registry Reader

roles/artifactregistry.reader

List Docker images in Artifact Registry repositories throughout the selected root boundary.

Binding location: Selected organization, folder, or project root

Permissions
  • artifactregistry.dockerimages.list

Container Analysis Occurrences Viewer

roles/containeranalysis.occurrences.viewer

List Container Analysis vulnerability occurrences throughout the selected root boundary.

Binding location: Selected organization, folder, or project root

Permissions
  • containeranalysis.occurrences.list
Access and data

Fixed Cloud Asset types and Registry vulnerability occurrences.

The connector supplies these exact asset-type filters to the two Cloud Asset Inventory reads. It also lists Docker images plus VULNERABILITY and DISCOVERY occurrences in each configured Registry project. Discovery data prevents an unscanned or expired image from appearing clean. It does not request an unbounded asset catalog.

RESOURCE - 10 asset types

  • cloudresourcemanager.googleapis.com/Project
  • compute.googleapis.com/Instance
  • compute.googleapis.com/Disk
  • compute.googleapis.com/Firewall
  • run.googleapis.com/Service
  • container.googleapis.com/Cluster
  • storage.googleapis.com/Bucket
  • sqladmin.googleapis.com/Instance
  • artifactregistry.googleapis.com/Repository
  • alloydb.googleapis.com/Cluster

IAM_POLICY - 1 asset type

  • storage.googleapis.com/Bucket

8 types become inventory

Compute Engine virtual machine

compute.googleapis.com/Instance

compute-instance / iaas

Compute Engine persistent block storage

compute.googleapis.com/Disk

block-storage / iaas

Cloud Run managed application service

run.googleapis.com/Service

serverless-service / paas

Google Kubernetes Engine managed cluster

container.googleapis.com/Cluster

container-orchestration / paas

Cloud Storage object bucket

storage.googleapis.com/Bucket

object-storage / iaas

Cloud SQL managed database instance

sqladmin.googleapis.com/Instance

managed-database / paas

Artifact Registry managed repository

artifactregistry.googleapis.com/Repository

artifact-registry / paas

AlloyDB for PostgreSQL managed database cluster

alloydb.googleapis.com/Cluster

managed-database / paas

Supporting configuration checks

  • Public SSH ingress on Compute Engine firewall rules

  • Public Cloud Storage bucket IAM

  • Cloud Storage bucket versioning or retention protection

  • Automated Cloud SQL backups

Project and firewall assets support lookup and checks but do not become inventory rows. The connector does not call Compute Engine, Cloud Storage, Cloud SQL, AlloyDB, Resource Manager, export, feed, or search APIs. Container Scanning begins with new image pushes; existing images need a new push before Google creates vulnerability results. A failed or incomplete CAI or Registry collection preserves the prior complete data and never produces a false pass.

Key lifecycle

The customer controls replacement and revocation.

The Sythe Labs platform stores the uploaded JSON as an encrypted opaque secret and uses it only for the bounded SDK operations in this guide. Google Cloud remains the source of truth for key status and revocation.

Replace

Create a new JSON key for the same dedicated service account and replace it from the signed-in status page. The Sythe Labs platform validates both CAI reads before switching keys.

Enable Registry findings

For an existing connection, grant the two Registry roles, enable Artifact Registry and Container Scanning in each registry project, then run Sync. Do not disconnect, replace, or re-upload the JSON key.

Revoke

After replacement succeeds, delete the old key in Google Cloud. To stop access immediately, delete the current key in Google Cloud and then disconnect the integration.

Disconnect

Disconnect from the signed-in status page to delete the encrypted key, stop scheduled synchronization, and remove Google Cloud connector inventory from active inventory.

Clean up

After disconnecting, delete the dedicated service account or remove all four role assignments when it is no longer needed. Remove customer-held key copies under your credential-retention process.

Troubleshooting

Resolve the stable reason shown in the signed-in status page.

Match the reason code to the customer-owned action below. Keep a safe request identifier for support, but never copy a service-account key or raw provider response into a message.

The service-account key is invalid

invalid_credential

Create a new JSON key for the dedicated customer-owned service account, then replace the key from the signed-in Integrations page. Do not send the key to Sythe Labs staff or include it in a support request.

The selected root cannot be read

inaccessible_scope

Use the canonical organization, folder, or project resource name and grant Cloud Asset Viewer to the dedicated service account at that exact root.

Cloud Asset Inventory is disabled

api_disabled

Enable the Cloud Asset Inventory API in the project that owns the service account, then retry the connection.

Registry vulnerability scanning is disabled

registry_api_disabled

Enable Artifact Registry and Container Scanning in every project with an in-scope Docker repository, then run Sync. The existing connection and JSON key remain valid.

Service Usage Consumer is missing

missing_service_usage_consumer

Grant Service Usage Consumer to the dedicated service account in the project that owns it, then retry the connection.

Resource inventory permission is missing

missing_resource_permission

Grant Cloud Asset Viewer to the dedicated service account at the selected root so RESOURCE assets can be listed throughout that boundary.

IAM policy inventory permission is missing

missing_iam_policy_permission

Grant Cloud Asset Viewer to the dedicated service account at the selected root so bucket IAM policies can be listed throughout that boundary.

Artifact Registry image permission is missing

missing_artifact_registry_permission

Grant Artifact Registry Reader to the existing service account at the selected root, or in each in-scope registry project, then run Sync. Do not reconnect or upload another key.

Container Analysis vulnerability permission is missing

missing_container_analysis_permission

Grant Container Analysis Occurrences Viewer to the existing service account at the selected root, or in each in-scope registry project, then run Sync. Do not reconnect or upload another key.

Some images have no completed vulnerability scan

image_scan_incomplete

Container Scanning has not finished a scan for every in-scope image. Newly pushed images finish shortly, and base images Google cannot analyze never will. Findings for the images that did scan are already published; no reconnection or role change is required.

Google Cloud could not reach every location

unreachable_region

Google Cloud reported one or more locations as unreachable for this request. Run Sync again once the location recovers. Findings collected from the reachable locations are already published and are left untouched.

Google Cloud could not complete the request

transient_failure

Wait for the retry window shown in the signed-in status page, then run the sync again. The prior complete inventory remains unchanged.

The connection configuration is invalid

configuration_error

Review the selected root, service-account project, registry projects, and all four predefined role assignments, then submit the connection again.

Google Cloud returned an unsupported result

provider_schema_drift

Use Sythe Labs support and include only the stable reason code and safe request identifier shown in the signed-in status page. Do not include the key or a raw provider response.

Need platform help?

Use the Sythe Labs support page and include only the stable reason code and safe request identifier shown in the signed-in status page.