gcp-ar-set-iam-policy
artifactregistry.repositories.setIamPolicy grants full control over the repo's IAM allow policy - self-grant writer access, then push to poison consumers.
match (effective permission)
{
"action": "artifactregistry.repositories.setIamPolicy",
"resource_type": "google.artifactregistry.Repository"
}
emit
| source type | Identity |
|---|---|
| target type | ResourcePolicy |
| source | <principal> |
| target | <ResourcePolicy of the Artifact Registry repository> |
| permissions | artifactregistry.repositories.setIamPolicy |
| state logic | ACTIVE when the permission is effective. BLOCKED if an IAM deny policy denies artifactregistry.repositories.setIamPolicy (e.g. from an org-wide deny policy), or if a VPC-SC perimeter rejects the API call. Inherits weakest from the contributing role binding. |
Narrative
{principal.name} can set the IAM allow policy of repository {repo.name} (artifactregistry.repositories.setIamPolicy), granting itself roles/artifactregistry.writer and subsequently pushing a malicious image to poison every mutable-tag consumer.
Raw rule rules/derived/gcp/artifactregistry.yaml
id: gcp-ar-set-iam-policy
emits: CanModifyPolicy
description: "artifactregistry.repositories.setIamPolicy grants full control over the repo's IAM allow\
\ policy \u2014 self-grant writer access, then push to poison consumers."
match_effective_permission:
action: artifactregistry.repositories.setIamPolicy
resource_type: google.artifactregistry.Repository
emit:
source_type: Identity
target_type: ResourcePolicy
source: <principal>
target: <ResourcePolicy of the Artifact Registry repository>
permissions:
- artifactregistry.repositories.setIamPolicy
conditions: []
state_logic: ACTIVE when the permission is effective. BLOCKED if an IAM deny policy denies artifactregistry.repositories.setIamPolicy
(e.g. from an org-wide deny policy), or if a VPC-SC perimeter rejects the API call. Inherits weakest
from the contributing role binding.
confidence: 0.95
derived_from:
- 'effective permission: artifactregistry.repositories.setIamPolicy on <repo>'
false_positive_note: "setIamPolicy at project/folder/org scope (resourcemanager.*.setIamPolicy) also\
\ implies CanModifyPolicy on the repo transitively \u2014 those paths are handled by gcp/identity-escalation.yaml.\
\ This rule covers the repo-level setIamPolicy permission only. Check that an IAM deny policy does\
\ not shadow the grant before emitting ACTIVE."
narrative: '{principal.name} can set the IAM allow policy of repository {repo.name} (artifactregistry.repositories.setIamPolicy),
granting itself roles/artifactregistry.writer and subsequently pushing a malicious image to poison
every mutable-tag consumer.'