gcp-cloudasset-bulk-recon

Search, list, or export all GCP assets and IAM policy bindings at org/folder/project scope via Cloud Asset Inventory - the same enumeration the reference collector performs, giving an attacker a pre-built map of the environment.

derived gcp emits CanRead

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'cai': None}

where

node_class(?cai) == ManagementService node_type(?cai) == ConfigurationService ?cai.origin_service == gcp:cloudasset effective_action(?principal, ?cai) includes any of ['cloudasset.assets.searchAllResources', 'cloudasset.assets.searchAllIamPolicies', 'cloudasset.assets.listAssets', 'cloudasset.assets.exportAssets']

emit

source typeIdentity
target typeConfigurationService
source?principal
target?cai
permissionscloudasset.assets.searchAllResources cloudasset.assets.searchAllIamPolicies cloudasset.assets.listAssets cloudasset.assets.exportAssets
conditionsiam_permission
state logicACTIVE when the principal holds effective cloudasset.assets.searchAllResources, searchAllIamPolicies, listAssets, or exportAssets at the project/folder/org scope and the Cloud Asset Inventory API is enabled (cloudasset.googleapis.com); CONDITIONAL(api_enabled) when the permission is present but the API is not enabled in the project; BLOCKED when a VPC-SC perimeter or IAM deny policy explicitly denies all four actions at the effective scope.

Narrative

{principal.name} can call Cloud Asset Inventory searchAllResources / listAssets / searchAllIamPolicies (or exportAssets) at {cai.scope} scope, enumerating all GCP resource configurations and IAM policy bindings across every project in that scope. This provides the same comprehensive inventory the reference collector uses to build the attack graph - a pre-built map of the environment for further traversal. This is a recon primitive; it does not grant access to any of the described resources.

Raw rule rules/derived/gcp/cloudasset.yaml

id: gcp-cloudasset-bulk-recon
emits: CanRead
description: "Search, list, or export all GCP assets and IAM policy bindings at org/folder/project scope\
  \ via Cloud Asset Inventory \u2014 the same enumeration the reference collector performs, giving an\
  \ attacker a pre-built map of the environment."
match:
- - principal: null
  - HasPermission
  - cai: null
where:
- node_class(?cai) == ManagementService
- node_type(?cai) == ConfigurationService
- ?cai.origin_service == gcp:cloudasset
- effective_action(?principal, ?cai) includes any of ['cloudasset.assets.searchAllResources', 'cloudasset.assets.searchAllIamPolicies',
  'cloudasset.assets.listAssets', 'cloudasset.assets.exportAssets']
emit:
  source_type: Identity
  target_type: ConfigurationService
  source: ?principal
  target: ?cai
  permissions:
  - cloudasset.assets.searchAllResources
  - cloudasset.assets.searchAllIamPolicies
  - cloudasset.assets.listAssets
  - cloudasset.assets.exportAssets
  conditions:
  - iam_permission
  state_logic: ACTIVE when the principal holds effective cloudasset.assets.searchAllResources, searchAllIamPolicies,
    listAssets, or exportAssets at the project/folder/org scope and the Cloud Asset Inventory API is enabled
    (cloudasset.googleapis.com); CONDITIONAL(api_enabled) when the permission is present but the API is
    not enabled in the project; BLOCKED when a VPC-SC perimeter or IAM deny policy explicitly denies all
    four actions at the effective scope.
  confidence: 0.92
  derived_from:
  - HasPermission(?principal, cloudasset.assets.searchAllResources|searchAllIamPolicies|listAssets|exportAssets,
    ?cai)
  false_positive_note: "CanRead here is a RECON edge only. Calling searchAllResources, listAssets, searchAllIamPolicies,\
    \ or exportAssets returns resource metadata and IAM policy bindings \u2014 it does NOT grant the caller\
    \ permission to operate on any of the described resources. Do NOT chain this edge to CanEnterProject,\
    \ CanEnterOrganization, CanAssume, CanExecuteAs, or CanEscalateTo.\nOrg/folder scope amplifies the\
    \ recon blast radius: a single caller with org-level cloudasset.assets.searchAllResources or listAssets\
    \ can enumerate all resources across every project in the organization. Note the scope in the narrative\
    \ but do NOT emit CanEnterOrganization or CanEnterProject as a result.\nexportAssets writes a snapshot\
    \ to a GCS bucket or BigQuery dataset. The permission gates only the export INITIATION; the destination-resource\
    \ IAM governs whether the exported data is readable \u2014 model destination access in gcs.yaml /\
    \ bigquery.yaml, not here.\nanalyzeIamPolicy (also in roles/cloudasset.viewer) simulates permission\
    \ evaluation but does not grant access; it is subsumed by this same recon rule and needs no separate\
    \ edge.\nCAI asset snapshots include resource configuration and IAM policy bindings but do NOT include\
    \ Secret Manager secret payloads, KMS key material, or other credential values \u2014 do not emit\
    \ ContainsSecret or ExposesCredential on the CAI node."
  narrative: "{principal.name} can call Cloud Asset Inventory searchAllResources / listAssets / searchAllIamPolicies\
    \ (or exportAssets) at {cai.scope} scope, enumerating all GCP resource configurations and IAM policy\
    \ bindings across every project in that scope. This provides the same comprehensive inventory the\
    \ reference collector uses to build the attack graph \u2014 a pre-built map of the environment for\
    \ further traversal. This is a recon primitive; it does not grant access to any of the described resources."
move · open · esc close