gcp-bigtable-set-iam-policy

bigtable.tables.setIamPolicy lets a principal grant any role on the table to any principal (including itself). Self-granting roles/bigtable.user (includes bigtable.tables.readRows + bigtable.tables.mutateRows) yields full data-plane read/write access scoped to that table without project-level IAM change.

derived gcp emits CanGrantPermission

match (effective permission)

{ "action": "bigtable.tables.setIamPolicy", "resource_type": "google.bigtable.admin.v2.Table" }

emit

source typeIdentity
target typeIdentity
source<principal>
target<any principal (self-grant or other)>
permissionsbigtable.tables.setIamPolicy
conditionsiam_permission
state logicACTIVE when bigtable.tables.setIamPolicy is confirmed as an ACTIVE effective permission on the table, instance, or project scope AND no deny policy or org policy blocks IAM mutations on Bigtable resources; CONDITIONAL(iam_permission) when the effective-permission evaluation is uncertain (e.g. IAM Conditions expression partially unresolved); BLOCKED when a deny policy explicitly denies bigtable.tables.setIamPolicy at the effective scope, or when a VPC-SC perimeter blocks IAM admin API calls (note: IAM calls are not part of the Bigtable service perimeter scope; VPC-SC does NOT block setIamPolicy for bigtable.googleapis.com).

Narrative

{principal.name} holds bigtable.tables.setIamPolicy on table {table.name} and can grant itself or any principal roles/bigtable.user, gaining bigtable.tables.readRows + bigtable.tables.mutateRows (full data-plane read/write) on {table.name} without modifying project-level IAM.

Raw rule rules/derived/gcp/bigtable.yaml

id: gcp-bigtable-set-iam-policy
emits: CanGrantPermission
description: bigtable.tables.setIamPolicy lets a principal grant any role on the table to any principal
  (including itself). Self-granting roles/bigtable.user (includes bigtable.tables.readRows + bigtable.tables.mutateRows)
  yields full data-plane read/write access scoped to that table without project-level IAM change.
match_effective_permission:
  action: bigtable.tables.setIamPolicy
  resource_type: google.bigtable.admin.v2.Table
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <any principal (self-grant or other)>
  permissions:
  - bigtable.tables.setIamPolicy
  conditions:
  - iam_permission
  state_logic: 'ACTIVE when bigtable.tables.setIamPolicy is confirmed as an ACTIVE effective permission
    on the table, instance, or project scope AND no deny policy or org policy blocks IAM mutations on
    Bigtable resources; CONDITIONAL(iam_permission) when the effective-permission evaluation is uncertain
    (e.g. IAM Conditions expression partially unresolved); BLOCKED when a deny policy explicitly denies
    bigtable.tables.setIamPolicy at the effective scope, or when a VPC-SC perimeter blocks IAM admin API
    calls (note: IAM calls are not part of the Bigtable service perimeter scope; VPC-SC does NOT block
    setIamPolicy for bigtable.googleapis.com).'
  confidence: min(contributing_confidences) * 0.97
  derived_from:
  - bigtable.tables.setIamPolicy effective permission on Table
  false_positive_note: "bigtable.tables.setIamPolicy is present in roles/bigtable.admin (any scope) and\
    \ is the per-TABLE IAM mutation action. It allows modifying the Cloud IAM policy of the table resource,\
    \ enabling a self-grant of roles/bigtable.user (which includes bigtable.tables.readRows + bigtable.tables.mutateRows\
    \ + bigtable.tables.sampleRowKeys). This is a self-escalation path to data access without project\
    \ IAM change. Separately, bigtable.instances.setIamPolicy is broader: it modifies IAM at the instance\
    \ scope, affecting ALL tables in the instance. Emit a separate CanGrantPermission edge for bigtable.instances.setIamPolicy\
    \ with target scoped to the Instance node. Do NOT conflate the two \u2014 table-scope setIamPolicy\
    \ does NOT confer instance- level IAM mutation. The human-user minimum-project-role requirement (at\
    \ least one project-level Bigtable role) is a UI/console enforcement; the IAM API itself does not\
    \ enforce it \u2014 self-granting via setIamPolicy on a table can still succeed for a service account\
    \ regardless of project role. Chains to CanReadData(principal, table) via the self-bound roles/bigtable.user,\
    \ then to ContainsSecret/CanExfiltrate if the table holds sensitive data."
  narrative: '{principal.name} holds bigtable.tables.setIamPolicy on table {table.name} and can grant
    itself or any principal roles/bigtable.user, gaining bigtable.tables.readRows + bigtable.tables.mutateRows
    (full data-plane read/write) on {table.name} without modifying project-level IAM.'
move · open · esc close