gcp-spanner-set-iam-policy-instance

spanner.instances.setIamPolicy lets a principal grant any instance-level role to any principal, including itself. This affects ALL databases within the instance - a broader blast radius than database-scope setIamPolicy.

derived gcp emits CanGrantPermission

match (effective permission)

{ "action": "spanner.instances.setIamPolicy", "resource_type": "google.spanner.admin.instance.v1.Instance" }

emit

source typeIdentity
target typeIdentity
source<principal>
target<any principal (self-grant or other)>
permissionsspanner.instances.setIamPolicy
conditionsiam_permission deny_assignment scp_or_org_policy
state logicACTIVE when spanner.instances.setIamPolicy is confirmed as an ACTIVE effective permission on the instance scope and no org policy or IAM deny policy blocks IAM mutations; CONDITIONAL(scp_or_org_policy) if an org policy restricts IAM policy modifications; BLOCKED when an IAM deny policy (resourcemanager.projects.setIamPolicy deny or spanner.instances.setIamPolicy deny) explicitly denies the action. Reference /rules/derived/gcp/iam-deny.yaml for deny-policy modeling.

Narrative

{principal.name} holds spanner.instances.setIamPolicy on instance {instance.name} and can grant itself or any principal instance-level roles (e.g., roles/spanner.instanceAdmin, roles/spanner.databaseAdmin at instance scope), affecting all {count} databases in the instance. Note: only roles grantable at instance scope are accessible; project-level roles like roles/spanner.admin cannot be granted at instance scope IAM.

Raw rule rules/derived/gcp/spanner.yaml

id: gcp-spanner-set-iam-policy-instance
emits: CanGrantPermission
description: "spanner.instances.setIamPolicy lets a principal grant any instance-level role to any principal,\
  \ including itself. This affects ALL databases within the instance \u2014 a broader blast radius than\
  \ database-scope setIamPolicy."
match_effective_permission:
  action: spanner.instances.setIamPolicy
  resource_type: google.spanner.admin.instance.v1.Instance
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <any principal (self-grant or other)>
  permissions:
  - spanner.instances.setIamPolicy
  conditions:
  - iam_permission
  - deny_assignment
  - scp_or_org_policy
  state_logic: ACTIVE when spanner.instances.setIamPolicy is confirmed as an ACTIVE effective permission
    on the instance scope and no org policy or IAM deny policy blocks IAM mutations; CONDITIONAL(scp_or_org_policy)
    if an org policy restricts IAM policy modifications; BLOCKED when an IAM deny policy (resourcemanager.projects.setIamPolicy
    deny or spanner.instances.setIamPolicy deny) explicitly denies the action. Reference /rules/derived/gcp/iam-deny.yaml
    for deny-policy modeling.
  false_positive_note: spanner.instances.setIamPolicy is present in roles/spanner.admin and roles/spanner.instanceAdmin.
    Unlike database-scope setIamPolicy, this permission applies to the entire instance and grants IAM
    mutation rights over ALL databases in the instance simultaneously. Self-granting roles/spanner.admin
    at the instance scope yields maximum privilege for all databases in the instance. This is a higher-value
    escalation than database-scope setIamPolicy.
  narrative: '{principal.name} holds spanner.instances.setIamPolicy on instance {instance.name} and can
    grant itself or any principal instance-level roles (e.g., roles/spanner.instanceAdmin, roles/spanner.databaseAdmin
    at instance scope), affecting all {count} databases in the instance. Note: only roles grantable at
    instance scope are accessible; project-level roles like roles/spanner.admin cannot be granted at instance
    scope IAM.'
  derived_from:
  - spanner.instances.setIamPolicy effective permission on Instance
move · open · esc close